AI/Machine Learning

[Machine Learning] 크로스-밸리데이션 (cross-validation)

byunghyun23 2022. 9. 13. 16:55

크로스-밸리데이션(cross-validation)은 오버피팅(overfitting)을 해결하기 위한 방법 중 하나입니다.

오버피팅이란 모델이 학습 데이터에 대한 예측 성능이 좋고, 테스트 데이터에 대한 예측 성능은 좋지 않은 것을 말합니다.

 

일반적으로 학습을 위한 데이터는 훈련, 검증, 테스트 데이터로 나눠집니다.

훈련 및 검증 데이터로 모델 학습을 진행하고, 테스트 데이터로 모델을 평가합니다.

Train / Validation / Test

 

하지만 데이터 수가 적거나 편향되어 있을 경우 오버피팅 될 수 있기 때문에, 아래와 같이 K개의 폴드로 나눠 학습 및 검증하는 방법이 K-fold cross validation 입니다.

K=5 일 경우, 데이터를 5개의 폴드로 나눠 흰색 부분 4개를 학습 데이터로 사용하고 회색 부분 1개를 검증에 사용합니다.

그리고 이것을 슬라이딩하여 총 5번 진행합니다.

이러한 방법은 모든 데이터를 학습 및 검증에 사용하기 때문에 모델의 일반화 성능을 향상시킬 수 있는 장점이 있습니다.

K-fold cross-validation

sklearn.model_selection의 kFold 를 이용하여 교차 검증을 해보겠습니다.

import pandas as pd
from sklearn.model_selection import train_test_split
import xgboost as xgb
from sklearn.model_selection import KFold
from sklearn.metrics import mean_absolute_error

train_df = pd.read_csv('train_full.csv')
X_train = train_df[train_df.columns.difference(['img_name', 'PSNR'])].to_numpy()

y_train = train_df['PSNR'].to_numpy()
y_train = y_train.reshape(len(y_train), 1)
print('X_train.shape, y_train.shape', X_train.shape, y_train.shape)		
# X_train.shape, y_train.shape (13210, 1442) (13210, 1)

X_train, X_test, y_train, y_test = train_test_split(X_train, y_train, shuffle=False, test_size=0.2)

xg = xgb.XGBRegressor()

kfold = KFold(n_splits=5)
for train_idx, val_idx in kfold.split(X_train):
    X_train_fold, X_val_fold = X_train[train_idx], X_train[val_idx]
    y_train_fold, y_val_fold = y_train[train_idx], y_train[val_idx]

    xg.fit(X_train_fold, y_train_fold, eval_set=[(X_val_fold, y_val_fold)], eval_metric='mae', early_stopping_rounds=100)

y_pred = xg.predict(X_test)
mae = mean_absolute_error(y_test, y_pred)
print('MAE:', mae)		# MAE: 0.7912489080464503