교차 검증
교차 검증 (Cross-validation)
모델의 성능을 평가할 때 가장 큰 함정은 "같은 데이터로 학습하고 같은 데이터로 평가"하는 거예요. 학습에 쓴 데이터로 평가하면 모델이 방금 본 샘플의 라벨을 그대로 반복할 뿐, 새 데이터를 예측하지 못하는 과적합(overfitting) 상태를 성능이 좋은 것으로 착각할 수 있어요. 이를 피하기 위해 데이터의 일부를 학습에서 떼어 놓고 평가하는 습관이 필요한데, 그 기법을 체계적으로 다루는 게 교차 검증이에요.
출처: scikit-learn 공식 문서 — Cross-validation: evaluating estimator performance
train_test_split으로 시작하기
예측 함수의 파라미터를 학습하고 같은 데이터로 테스트하는 것은 방법론적 실수예요. 그래서 보통 데이터 일부를 테스트 세트로 떼어 놓아요. scikit-learn에서 훈련 세트와 테스트 세트로 무작위 분할하는 가장 빠른 방법은 train_test_split 헬퍼예요.
>>> import numpy as np
>>> from sklearn.model_selection import train_test_split
>>> from sklearn import datasets
>>> from sklearn import svm
>>> X, y = datasets.load_iris(return_X_y=True)
>>> X_train, X_test, y_train, y_test = train_test_split(
... X, y, test_size=0.4, random_state=0)
>>> X_train.shape, y_train.shape
((90, 4), (90,))
>>> X_test.shape, y_test.shape
((60, 4), (60,))
>>> clf = svm.SVC(kernel='linear', C=1).fit(X_train, y_train)
>>> clf.score(X_test, y_test)
0.96
검증 세트의 필요성
하이퍼파라미터(예: SVM의 C)를 조정하면서 평가하면, 파라미터를 성능이 잘 나오도록 계속 튜닝하는 과정에서 테스트 세트의 정보가 모델로 "샐" 수 있어요. 이러면 평가 메트릭이 일반화 성능을 말해 주지 못해요. 이 문제를 풀려면 데이터의 또 다른 일부를 검증 세트(validation set) 로 떼어 놓아요. 훈련 세트로 학습, 검증 세트로 평가를 하고, 실험이 잘 되면 마지막에 테스트 세트로 최종 평가를 하는 식이에요.
다만 데이터를 세 갈래로 나누면 학습에 쓸 샘플 수가 크게 줄고, 결과가 훈련·검증 분할의 우연한 선택에 의존할 수 있어요.
교차 검증(CV)의 해법
이 문제를 푸는 절차가 바로 교차 검증(cross-validation, CV) 이에요. 최종 평가용 테스트 세트는 여전히 따로 떼어 두되, 검증 세트는 고정하지 않고 여러 번 나눠 평가해요. 데이터를 k개 폴드(fold)로 나누고, 각 폴드를 한 번씩 검증용으로 쓰며 나머지로 학습하는 k-fold 교차 검증이 대표적이에요. 이렇게 하면 모든 데이터가 학습과 검증에 골고루 사용돼서 평가가 훨씬 견고해져요.