# 학습 곡선
지난 시간에 포스팅했던 다항 회귀 모델은 보통의 선형 회귀 모델보다 주어진 훈련 데이터에 훨씬 더 잘 맞추려고 했다. 다음의 코드는 2차원을 넘어 30차원, 100차원 다항 회귀 모델의 예측 결과를 비교한 것이다.
from sklearn.preprocessing import StandardScaler
from sklearn.pipeline import Pipeline
for style, width, degree in (('k--',1,100),('g-',1,30),('r-',1,2)):
poly_features = PolynomialFeatures(degree=degree, include_bias=False)
standard = StandardScaler()
lin_reg = LinearRegression()
lin_regression = Pipeline([
('polyfeatures',poly_features),
('std_scaler',standard),
('lin_reg',lin_reg),
])
lin_regression.fit(X,y)
y_newbig = lin_regression.predict(X_new)
plt.plot(X_new, y_newbig, style, label=str(degree), linewidth=width)
plt.plot(X, y, "b.", linewidth=3)
plt.legend(loc="upper left")
plt.xlabel("$x_1$", fontsize=18)
plt.ylabel("$y$", rotation=0, fontsize=18)
plt.axis([-3, 3, 0, 10])
plt.show()
차원이 늘어날 수록, 주어진 훈련 데이터에 맞추기 위해 곡선이 점점 더 구불구불해지는 것을 알 수 있다.
물론 100차원 회귀 모델은 훈련 데이터에 심하게 과대적합된 상태이다.
차원이 너무 작아도 훈련 데이터에 과소적합되고, 차원이 너무 커도 훈련 데이터에 과대적합되기 때문에 얼마나 적절하게 복잡한 모델을 사용할지 선택하는 것은 중요하다.
모델의 일반화 성능을 추정하기 위해 지난 포스팅에서 다룬 교차 검증 방법 이외의 또 다른 방법은 학습 곡선을 살펴보는 것이다.
학습 곡선 그래프는 훈련 세트와 검증 세트의 모델 성능을 훈련 세트 크기의 함수로 나타낸다. 이 그래프는 훈련 세트와 검증 세트에서의 모델의 성능을 훈련 세트 크기만큼 함수로 나타낸 것인데, 이 그래프를 생성하기 위해선 간단히 크기가 다른 서브 세트를 만들어 모델을 여러 번 훈련시키는 것이다.
from sklearn.metrics import mean_squared_error
from sklearn.model_selection import train_test_split
def plot_learning_curves(model, X, y):
X_train, X_val, y_train, y_val = train_test_split(X, y, test_size=0.2, random_state=10)
# 훈련세트, 검증세트 분할
train_errors, val_errors = [], [] # 훈련 세트 오차, 검증 세트 오차
for m in range(1, len(X_train)): # 훈련 세트 개수가 1개일 때 부터 전체 개수일 때 까지 검증
model.fit(X_train[:m], y_train[:m])
y_train_predict = model.predict(X_train[:m])
y_val_predict = model.predict(X_val)
# 각 훈련 세트 개수에서 훈련 세트 오류, 검증 세트 오류 적재
train_errors.append(mean_squared_error(y_train[:m], y_train_predict))
val_errors.append(mean_squared_error(y_val, y_val_predict))
# 그래프 출력
plt.plot(np.sqrt(train_errors), "r-+", linewidth=2, label="training set")
plt.plot(np.sqrt(val_errors), "b-", linewidth=3, label="validation set")
plt.legend(loc="upper right", fontsize=14)
plt.xlabel("training set size", fontsize=14)
plt.ylabel("RMSE", fontsize=14)
lin_reg = LinearRegression() # 단순 선형 회귀 모델
plot_learning_curves(lin_reg, X, y)
plt.axis([0, 80, 0, 3])
plt.show()
훈련 세트가 적을 때엔 훈련 세트에서 모델이 정확하게 작동하지만, 검증 세트에서 모델의 RMSE는 가장 높은 것을 볼 수 있다. 훈련 세트의 사이즈가 늘어남에 따라 훈련 세트에서의 정확도는 감소하고, 검증 세트에서의 정확도는 점점 증가한다. 결국 두 가지 경우에서의 RMSE 는 꽤 높은 수치(1.7~1.8 부근) 에서 수평한 구간을 만들며 근접해 있는 모습을 보인다.
이 학습 곡선은 전형적인 과소적합 모델의 학습곡선이다. 두 곡선이 수평한 구간을 만들며 꽤 높은 오차에서 매우 가까이 근접해 있다.
다음으로 10차 다항 회귀 모델의 학습 곡선을 그려보면 다음과 같다.
from sklearn.pipeline import Pipeline
polynomial_regression = Pipeline([
('poly_features', PolynomialFeatures(degree=10, include_bias=False)),
('lin_reg', LinearRegression()),
])
plot_learning_curves(polynomial_regression,X,y)
plt.axis([0, 80, 0, 3])
plt.show()
위 그래프를 보면 10차원 다항 회귀 모델은 훈련 데이터의 오차가 선형 회귀 모델보다 훨씬 낮다.
또한 두 곡선 사이에 공간이 있는데, 훈련 데이터 상에서 모델의 성능이 검증 데이터 상에서보다 훨씬 낫다는 것이고, 이는 과대적합 모델의 특징이다. 하지만 더 큰 훈련 세트를 사용하면 두 곡선은 점점 가까워진다.
# 편향/분산 트레이드오프
모델의 일반화 오차는 세 가지 다른 종류의 오차의 합으로 표현할 수 있다.
1.편향
편향은 잘못된 가정으로 인한 것으로, 예를 들어 2차원 데이터를 선형으로 가정하는 경우 발생한다. 편향이 큰 모델은 과소적합되기 쉽다.
2.분산
분산은 훈련 데이터에 있는 작은 변동에 모델이 과도하게 민감하기 때문에 나타나는 것으로 자유도가 높은 모델이 높은 분산을 가지기 쉬워 훈련 데이터에 과대적합되는 경향이 있다.
3.줄일 수 없는 오차
줄일 수 없는 오차는 데이터 자체에 있는 노이즈 때문에 발생한다. 이 오차를 줄일 유일한 방법은 데이터에서 노이즈를 제거하는 것이다.
모델의 복잡도가 커지면 통상적으로 분산이 늘어나고 편향은 줄어들며, 모델의 복잡도가 낮아지면 편향이 커지고 분산이 작아진다. 이를 편향/분산 트레이드오프라고 한다.
'Artificial Intelligence > Machine Learning' 카테고리의 다른 글
핸즈온 머신러닝(5) - 로지스틱 회귀 1 (0) | 2020.01.24 |
---|---|
핸즈온 머신러닝(5) - 규제가 있는 선형 모델 (0) | 2020.01.24 |
핸즈온 머신러닝(5) - 다항 회귀 (0) | 2020.01.23 |
핸즈온 머신러닝(5) - 선형 회귀와 경사 하강법 2 (0) | 2020.01.23 |
핸즈온 머신러닝(5) - 선형 회귀와 경사 하강법 1 (0) | 2020.01.23 |
댓글