다중회귀 - MultipleRegression¶
선형회귀(Linear Regression)를 통해 하나의 특성(feature)을 사용하여 모델을 훈련시켰다. 여러 개의 특성을 사용한 선형회귀인 다중회귀에 대해 알아보자.
Dataset¶
import pandas as pd
df = pd.read_csv("http://bit.ly/perch_csv_data")
perch_full = df.to_numpy()
print(perch_full)
[[ 8.4 2.11 1.41] [13.7 3.53 2. ] [15. 3.82 2.43] [16.2 4.59 2.63] [17.4 4.59 2.94] [18. 5.22 3.32] [18.7 5.2 3.12] [19. 5.64 3.05] [19.6 5.14 3.04] [20. 5.08 2.77] [21. 5.69 3.56] [21. 5.92 3.31] [21. 5.69 3.67] [21.3 6.38 3.53] [22. 6.11 3.41] [22. 5.64 3.52] [22. 6.11 3.52] [22. 5.88 3.52] [22. 5.52 4. ] [22.5 5.86 3.62] [22.5 6.79 3.62] [22.7 5.95 3.63] [23. 5.22 3.63] [23.5 6.28 3.72] [24. 7.29 3.72] [24. 6.38 3.82] [24.6 6.73 4.17] [25. 6.44 3.68] [25.6 6.56 4.24] [26.5 7.17 4.14] [27.3 8.32 5.14] [27.5 7.17 4.34] [27.5 7.05 4.34] [27.5 7.28 4.57] [28. 7.82 4.2 ] [28.7 7.59 4.64] [30. 7.62 4.77] [32.8 10.03 6.02] [34.5 10.26 6.39] [35. 11.49 7.8 ] [36.5 10.88 6.86] [36. 10.61 6.74] [37. 10.84 6.26] [37. 10.57 6.37] [39. 11.14 7.49] [39. 11.14 6. ] [39. 12.43 7.35] [40. 11.93 7.11] [40. 11.73 7.22] [40. 12.38 7.46] [40. 11.14 6.63] [42. 12.8 6.87] [43. 11.93 7.28] [43. 12.51 7.42] [43.5 12.6 8.14] [44. 12.49 7.6 ]]
csv -> pandas -> numpy
import numpy as np
perch_weight = np.array([5.9, 32.0, 40.0, 51.5, 70.0, 100.0, 78.0, 80.0, 85.0, 85.0, 110.0,
115.0, 125.0, 130.0, 120.0, 120.0, 130.0, 135.0, 110.0, 130.0,
150.0, 145.0, 150.0, 170.0, 225.0, 145.0, 188.0, 180.0, 197.0,
218.0, 300.0, 260.0, 265.0, 250.0, 250.0, 300.0, 320.0, 514.0,
556.0, 840.0, 685.0, 700.0, 700.0, 690.0, 900.0, 650.0, 820.0,
850.0, 900.0, 1015.0, 820.0, 1100.0, 1000.0, 1100.0, 1000.0,
1000.0])
from sklearn.model_selection import train_test_split
train_input, test_input, train_target, test_target = train_test_split(perch_full, perch_weight, random_state=42)
from sklearn.preprocessing import PolynomialFeatures
poly = PolynomialFeatures(include_bias=False)
poly.fit(train_input)
train_poly = poly.transform(train_input)
print(train_poly.shape)
(42, 9)
poly.get_feature_names()
['x0', 'x1', 'x2', 'x0^2', 'x0 x1', 'x0 x2', 'x1^2', 'x1 x2', 'x2^2']
test_poly = poly.transform(test_input)
Model - MultiRegression¶
from sklearn.linear_model import LinearRegression
lr = LinearRegression()
lr.fit(train_poly, train_target)
LinearRegression(copy_X=True, fit_intercept=True, n_jobs=None, normalize=False)
Score¶
print(lr.score(train_poly, train_target))
0.9903183436982124
print(lr.score(test_poly, test_target))
0.9714559911594132
특성을 더 많이 추가하면?
poly = PolynomialFeatures(degree=5, include_bias=False)
poly.fit(train_input)
train_poly = poly.transform(train_input)
test_poly = poly.transform(test_input)
print(train_poly.shape)
(42, 55)
특성이 55개 생겼다.
lr.fit(train_poly, train_target)
LinearRegression(copy_X=True, fit_intercept=True, n_jobs=None, normalize=False)
print(lr.score(train_poly, train_target))
print(lr.score(test_poly, test_target))
0.9999999999991096 -144.40579242335605
test set에서 음수가 나옴을 알 수 있다. 특성의 개수를 과도하게 늘려 train set에 과대적합이 발생했다. 이를 규제를 통해 줄여보자.
규제¶
규제는 머신러닝 모델이 훈련 세트를 너무 과도하게 학습하지 못하도록 훼방 놓는 것을 의미한다. 즉 모델이 훈련 세트에 과대적합되지 않도록 만드는 것이다. 선형 회귀 모델의 경우 특성에 곱해지는 계수를 작게 만드는 것이다.
선형 회귀 모델에 규제를 적용하는것은 그 계수에 규제를 적용하는 것과 마찬가지이다. 특성의 스케일이 정규화되지 않으면 여기에 곱해지는 계수 값도 차이가 발생하기 때문에 정규화가 필요하다.
from sklearn.preprocessing import StandardScaler
ss = StandardScaler()
ss.fit(train_poly)
train_scaled = ss.transform(train_poly)
test_scaled = ss.transform(test_poly)
릿지 & 라쏘¶
선형 회귀 모델에 규제를 추가한 모델을 릿지와 라쏘라 부른다. 두 모델은 규제를 가하는 방법이 다르다. 릿지는 제곱한 값을 기준으로 규제를 가하고, 라쏘는 계수의 절댓값을 기준으로 규제를 적용한다. 일반적으로 릿지를 더 선호한다.
## 릿지
from sklearn.linear_model import Ridge
ridge = Ridge()
ridge.fit(train_scaled, train_target)
print(ridge.score(train_scaled, train_target))
0.9896101671037343
print(ridge.score(test_scaled, test_target))
0.9790693977615398
릿지와 라쏘 모델을 사용할 때는 규제의 양을 조절할 수 있다. 모델 객체를 만들 때, alpha 매개변수를 규제의 강도를 조절한다. alpha의 값이 커지면 규제의 강도가 세진다. 적절한 alpha 값을 찾는 한 방법은 R^2의 값의 그래프를 그려보는 것이다. train set와 test set의 점수가 가장 가까운 지점(과대/과소적합이 제일 적은 지점)이 최적의 alpha 값이다.
import matplotlib.pyplot as plt
train_score = []
test_score = []
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)
train_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.xlabel('alpha')
plt.ylabel('R^2')
plt.show()
ridge = Ridge(alpha = 0.1)
ridge.fit(train_scaled, train_target)
print(ridge.score(train_scaled, train_target))
print(ridge.score(test_scaled, test_target))
0.9903815817570366 0.9827976465386927
라쏘는 릿지 모델을 Lasso로 변환하면 똑같이 구할 수 있다!
from IPython.core.display import display, HTML
display(HTML("<style>.container {width:90% !important;}</style>"))
'ML & DL (Machine Learning&Deep Learning) > Machine Learning (ML)' 카테고리의 다른 글
[Machine Learning] LinearRegression (0) | 2021.10.13 |
---|
댓글