교차 검증으로 학습 데이터에 오버 피트하는 사례에 대해서

소개



기계 학습에서 일반화 성능을 평가하는 방법으로 교차 검증 (교차 검증)이 자주 사용됩니다.

이 크로스 밸리데이션이지만, 학습 데이터에 오버 피트하는 일도 있으므로, 실시하기 전에 테스트 데이터를 남겨 두고, 크로스 밸리데이션 후에 테스트 데이터를 사용해 미지의 데이터에 대한 정밀도를 검증하는 것이 일반적으로 추천합니다.

그렇다고는 해도, 5분할이라든지 분할해 검증하고 있는데, 학습 데이터에 오버피트하는 것은 있는 것인가? 라고 반신반의였다. 이번, 훌륭하게 오버 피트하는 케이스를 발견했으므로 공유하고 싶다.

전제



이번에는, ht tp // //도 ぇぇね t. 아이 / 달래 ts-1 로 공개되고 있는 FreeSolv(회귀)의 데이터를 이용한다. MoleculeNet에 의하면 이 데이터의 최고 정밀도는 R^2로 0.92 정도가 되고 있다.

해보자



데이터를 학습 449건, 테스트 193건으로 분할하고, 420개의 많은 특징량을 사용하여 학습 데이터에 대해 scikit-learn의 SequentialFeatureSelector를 사용하여 특징량을 5~50까지 5개씩 새기면서 특징 선택 를 해 보았다.
from sklearn.feature_selection import SequentialFeatureSelector
from sklearn.cross_decomposition import PLSRegression

#select_features = [] 
for feature_num in [5,10,15,20,25,30,35,40,45,50]:
    pls = PLSRegression(n_components=5)
    sfs = SequentialFeatureSelector(pls, n_features_to_select=feature_num)
    sfs.fit(train_X_scaled, train_t)
    select_features.append(sfs.get_support())

계속해서, 선택된 5~50의 특징량 세트마다 크로스 밸리데이션 스코어, 외부 검증 스코어를 구해 그래프화해 보았다.
from sklearn.model_selection import cross_validate
scores = []
stds = []
test_scores = []

# 選択された特徴セット(5~50)毎にクロスバリデーションスコア、外部検証スコアをグラフ化する
for featuers in select_features:
    # クロスバリデーションスコア
    train_X_scaled_tmp = train_X_scaled[:, featuers]
    pls = PLSRegression(n_components=5)    
    cv_results = cross_validate(pls, train_X_scaled_tmp, train_t)
    scores.append(cv_results["test_score"].mean())
    stds.append(cv_results["test_score"].std())

    # 外部データに対するスコア
    test_X_scaled_tmp = test_X_scaled[:, featuers]
    pls = PLSRegression(n_components=5)    
    pls.fit(train_X_scaled_tmp, train_t)
    test_scores.append(pls.score(test_X_scaled_tmp, test_t))

# 可視化
figure = plt.figure(figsize=(8,4))
ax = figure.add_subplot(111)
ax.set_title("PLS score plot")
ax.set_xlabel("n_components")
ax.set_ylabel("r2 score")
ax.plot(range(len(scores)), scores)
ax.fill_between(range(len(scores)), np.array(scores)-np.array(stds), np.array(scores)+np.array(stds), scores, alpha=0.5, color="lightgray")
ax.plot(range(len(scores)), test_scores)

그러면 아래 그림에서 크로스 검증 점수가 파란색이고 외부 데이터에 대한 점수가 주황색으로 얻어집니다.
크로스 밸리데이션 스코어는 무려, MoleculeNet의 최고 정밀도를 넘고 있다. 그러나 외부 검증 점수는 10을 피크로 계속 떨어지고 있다.



그래프를 보면 알 수 있지만, 20 이상의 특징량 세트는 학습 데이터에 오버 피트되어 버리고 있다.

왜 이렇게 되었습니까?



한마디로, 크로스 밸리데이션 스코어가 좋아지는 특징이 선택되었다는 것이다.
오버핏이라고 하면 하이퍼 파라미터에 눈이 가기 쉽지만, 이와 같이 특징 선택에서도 일어날 수 있다는 것을 몸으로 알게 된 대로이다. 이론적 근거를 설명할 수 없지만, 선형 수법에 있어서 일어나기 쉽다.
특징 선택은 안쪽이 깊다.

좋은 웹페이지 즐겨찾기