-
학습, 검증곡선과 편향-분산 트레이드오프(Bias-Variance Tradeoff)Programming & Machine Learning/풀어쓰는 머신러닝 2017. 8. 11. 02:57
본 포스팅을 읽기 전에, 교차검증이 무엇인지에 대해 모르는 분들은 이곳을 참고해주시길 바랍니다.
학습, 검증곡선과 편향-분산 트레이드오프
편향-분산 트레이드오프 (Bias-Variance Tradeoff)
머신 러닝에서의 error는 크게 두 분류로 나뉜다. bias(편향), 그리고 variance(분산)이다. bias는 흔히 생각할 수 있는 error로, 선형 회귀같은 문제에서의 SSE를 떠올리면 쉽다. 모델이 학습데이터를 충분히 설명할 수 없는 상황에서 커지는 에러이다. 이 상황을 흔히 underfitting이라고 한다. variance는 그 반대로 모델이 학습데이터를 과도하게 잘 설명하는 상황이다. 모집단을 추정하고자 표본집단을 이용하여 모델을 만들어놨더니, 표본집단만을 거창하게 잘 설명하는 모델이 된 것이다. 머신러닝을 공부하는 사람이라면 한 번 쯤 들어본, overfitting의 상황이다. variance에 대해 수학적으로 조금 더 직관적으로 얘기하자면, Training Score와 Cross Validation의 차이가 심해지는 상황이 variance가 증가하는 상황이다. 아래의 그림을 보면 매우 쉽게 알 수 있다. 빨간 곡선은 cross validation error이고, training error가 녹색 곡선이다. 학습이 진행됨에 따라 오버피팅이 되기 때문에 트레이닝 스코어는 계속해서 증가하는 경향을 보이지만, 교차검증값은 점점 악화된다. 모델이 일반화 성능을 잘 보여주는 영역에서 벗어나고 있는 상황이다. (참고 - 트레이닝 스코어 : 학습데이터로 모델을 테스트했을때의 스코어, 교차검증 스코어 : 모델의 일반적 성능을 추정하기 위해, 테스트셋을 resampling 하는 등의 모델 일반화 검증을 하는 방법에 대한 스코어)
일반적인 머신러닝에서는 편향-분산의 관계는 편향이 올라가면 분산은 내려가고, 분산이 올라가면 편향이 내려가는 시소 관계에 놓여있다. 이를 편향-분산 트레이드오프라 한다. 흔히 머신러닝에 있어서 중요한 것으로 비용함수를 최적화 하거나 차원을 축소한다거나 하는 이야기를 하기 쉽다. 하지만 편향-분산 트레이드오프를 잘 맞춰주는 것이 훨씬, 머신러닝의 정말 기본중의 기본이라고 할 수 있겠다. 편향-분산 트레이드오프를 잘 맞춰주기 위해서는 그리드검색등을 이용한 파라미터 튜닝의 좋은 기법등이 있을 수 있겠으나 역시 기본이 되면서 사람에게 설득력을 갖는 것은 눈으로 보여지는 것이다. 학습곡선과 검증곡선을 이용하여 바이어스와 분산 문제를 진단하는 것이 여전히 좋은 방법이다. sklearn에서는 learning-curve를 아주 쉽게 그려주는 모듈을 제공한다. 이것을 이용하는 것이 전자보다 더 의미가 있다. 그리드 검색의 하이퍼 파라미터 튜닝, 중첩 교차검증 등의 고급 기법은 학습곡선과 검증곡선을 토대로 이 문제를 사람의 직관으로 판단하는 요인을 코드로 구현한 것에 지나지 않기 때문이다. 아래의 예제는 학습곡선과 검증곡선으로 편향-분산 트레이드 오프 상황을 핸들링하는 상황을 재현한 것이다. 예제에서는 편향-분산 트레이드오프가 x축의 값의 증감에 따라 크게 민감하지 않기 때문에, 데이터 수나 샘플링에 큰 영향을 받지 않고 모델의 성능을 잘 유지하는 좋은 모델이라고 할 수 있다. 예제와 달리 위의 두번째 그림같은 상황이 된다면 트레이드 오프 상황이 벌어지기 시작하는, 두 곡선이 갈래길로 분기하는 상황에서 모델의 조건이 가장 좋다고 할 수있는 것이다. 사람의 패턴 인식능력을 십분 활용하는 이런 방식이 개인적으로는 더 좋은 것 같다. 물론 더욱 고급기법의 경우는 오히려 코드로는 훨씬 쉽다. 또한 GridSearchCV등의 클래스에 매우 직관적이면서 쉽게 정리가 되어있기 때문에 sklearn의 튜토리얼을 한 번 쯤 따라해보는 것만으로도 충분하다.
%matplotlib inline import matplotlib.pyplot as plt from sklearn.learning_curve import learning_curve pipe_lr = Pipeline([('scl', StandardScaler()), ('clf', LogisticRegression(penalty='l2', random_state=0))]) train_sizes, train_scores, test_scores =\ learning_curve(estimator=pipe_lr, X=X_train, y=y_train, train_sizes=np.linspace(0.1, 1.0, 10), cv=10, n_jobs=1) train_mean = np.mean(train_scores, axis=1) train_std = np.std(train_scores, axis=1) test_mean = np.mean(test_scores, axis=1) test_std = np.std(test_scores, axis=1) plt.plot(train_sizes, train_mean, color='blue', marker='o', markersize=5, label='training accuracy') plt.fill_between(train_sizes, train_mean + train_std, train_mean - train_std, alpha=0.15, color='blue') plt.plot(train_sizes, test_mean, color='green', linestyle='--', marker='s', markersize=5, label='validation accuracy') plt.fill_between(train_sizes, test_mean + test_std, test_mean - test_std, alpha=0.15, color='green') plt.grid() plt.xlabel('Number of training samples') plt.ylabel('Accuracy') plt.legend(loc='lower right') plt.ylim([0.8, 1.0]) plt.tight_layout() # plt.savefig('./figures/learning_curve.png', dpi=300) plt.show()
'Programming & Machine Learning > 풀어쓰는 머신러닝' 카테고리의 다른 글
연속형 회귀분석에 대한 전반적인 내용들 (1) 2017.08.23 교차검증(Cross Validation)을 통한 모델 평가방법 (2) 2017.08.11 커널 주성분 분석(KPCA)로 차원 축소하기 (0) 2017.08.10 선형판별분석(LDA)로 차원 축소하기 (0) 2017.08.10 차원 축소, 차원의 저주에 관하여 (2) 2017.08.10 댓글