박해선 선생님의 [혼자 공부하는 머신러닝+딥러닝] 책을 정리해보았다. 아래 링크에서 책의 내용을 선생님께서 설명해 주신다.
https://youtu.be/xkknXJeEaVA
기본적으로 Scikit-learn을 활용하는 내용이라 사용법을 익힌다는 생각으로 정리해본다.
학습하기
from sklearn.linear_model import LinearRegression
lr = LinearRegression()
lr.fit(train_input, train_target)
print(lr.coef_, lr.intercept_)
lr.score(train_input, train_target)
lr.score(test_input, test_target)
학습한 직선 그리기
plt.scatter(train_input, train_target)
plt.plot([15,50], [15*lr.coef_+lr.intercept_, 50*lr.coef_+lr.intercept_])
train_poly = np.column_stack((train_input ** 2, train_input))
test_poly = np.column_stack((test_input ** 2, test_input))
poly 학습
lr = LinearRegression()
lr.fit(train_poly, train_target)
print(lr.coef_, lr.intercept_)
학습한 곡선 그리기
point = np.arange(15, 50)
plt.scatter(train_input, train_target)
plt.plot(point, 1.01*point**2 - 21.6*point + 116.05
plt.show()
여러가지 feature를 사용한다.
from sklear.preprocessing import PolynomialFeatures
# degree = 2
poly = PolynomialFeatures()
poly.fit([2,3])
# 1(bias), 2, 3, 2**2, 2*3, 3**2
print(poly.transfore([2,3]))
[[1. 2. 3. 4. 6. 9.]]
estimator : fit, predict, score
transformer : fit, transform
poly = PolynomialFeatures(include_bias=False) #bias 생략
poly.fit(train_input)
train_poly = poly.transform(train_input)
poly.get_feature_names()
['x0', 'x1', 'x2', ...]
test_poly = poly.transform(test_input)
from sklearn.linear_model import LinearRegression
lr = LinearRegression()
lr.fit(train_poly, train_target)
poly feature를 만드는 과정에서 PolynomialFeatures(degree=5, include_bias=False)로 5차 계수를 만든다면 overfitting의 문제가 발생한다.
from sklearn.preprocessing import StandardScaler
ss = StandardScaler()
ss.fit(train_poly) # degree=5
train_scaled = ss.tranform(train_poly)
test_scaled = ss.transform(test_poly)
L2규제 가중치에 제곱
from sklearn.linear_model import Ridge
ridge = Ridge()
ridge.fit(train_scaled, train_target)
alpha_list = [0.001, 0.01, 0.1, 1, 10, 100]
for alpha in alpha_list:
ridge = Ridge(alpha=alpha)
ridge.fit(train_scaled, train_target)
trian_score.append(ridge.score(train_scaled, train_target))
test_score.append(ridge.score(test_scaled, test_target))
plt.plot(np.log10(alpha_list), train_score)
plt.plot(np.log10(alpha_list), test_score)
plt.show
from sklearn.linear_model import Lasso
lasso = Lasso(alpha=10)
lasso.fit(train_scaled, train_target)
print(np.sum(lasso.coef_==0)) # 40, Lasso는 일부특성을 사용하지 않는 경우가 있다.
fish_input = fish[['Weight','Length','Diagonal','Height','Width']].to_numpy()
fish_target = fish['Species'].to_numpy()
from sklearn.neighbors import KNeighborsClassifier
kn= KNeighborsClassifier(n_neighbors=3)
kn.fit(train_scaled, train_target)
print(kn.classes_)
['Bream' 'Parkki' 'Perch' 'Pike' 'Roach' 'Smelt' 'Whitefish']
print(kn.predict(test_scaled[:5]))
['Perch' 'Smelt' 'Pike' 'Perch' 'Perch']
proba = kn.predict_proba(test_scaled[:5])
print(np.round(proba, decimals=4))
[[0. 0. 0.6677 0. 0.3333 0. 0.]]
z = ax무게 + bx길이 + cx대각선 + dx높이 + ex두께 +f(절편)
z값을 그대로 사용하면 회귀가 되기 때문에 0~1사이의 값을 가지는 확률로 바꾸어주기 위해서 시그모이드 함수(로지스틱 함수)를 사용한다.
predict 는 z값을
predict_proba 는 pi(sigmoid z)값을 본다.
bream_smelt_indexes = (train_target=='Bream') | (train_target=='Smelt')
train_bream_smelt = train_scaled[bream_smelt_indexes]
target_bream_smelt = train_target[bream_smelt_indexes]
from sklearn.linear_model import LogisticRegression
lr=LogisticRegression()
lr.fit(train_bream_smelt, target_brea_smelt)
print(lr.predict(train_bream_smelt[:5]))
[B S B B B]
print(lr.predict_proba(train_bream_smelt[:5]))
[[0.997 0.002]]
print(lr.coef_, lr.intercept_)
[[-0.4037798 -0.56720209 -0.662 -1.012 -0.7316]][-2.1615] # 다섯가지 특성에 곱하는 w값들이다.
decisions = lr.decision_function(train_bream_smelt[:5])
print(decisions)
[-6.029 3.5712 -5.2656 -4.2432 -6.0607]
from scipy.special import expit
print(expit(decisions))
[0.0024 0.9726 0.005139 0.01415 0.002327]
lr = LogisticRegression(C=20, max_iter=1000) # C는 규제의 반비례값(기본값 1), 기본반복은 100회
lr.fit(train_scaled, train_target)
print(lr.score(train_scaled, train_target))
print(lr.score(test_scaled, test_target))
proba = lr.predict_proba(test_scaled[:5])
print(np.round(proba, decimals=3))
print(lr.coef_.shape, lr.intercept_.shape)
(7,5) (7,) # class마다 선형함수가 만들어지는 것을 알수 있다.
# One versus Rest의 방식을 사용한다.
# 7개의 z가 나온다. 각각을 시그모이드로 만들면 각각의 합은 1이 되어야한다.
# 따라서 시그모이드가 아니고 softmax함수를 사용한다.
decision = lr.decision_function(test_scaled[:5])
print(np.round(decision, decimals=2))
[[-6.5 1.03 5.16 -2.73 3.34 0.33 - 063]]
# 일종의 정규화의 과정이다.
from scipy.special import softmax
proba = softmax(decision, axis=1)
print(np.round(proba, decimals=3))
[[0. 0.014 0.841 0. 0.136 0.007 0.003]]