교차검증(Cross-Validation)
scikit-learn.org/stable/modules/cross_validation.html
3.1. Cross-validation: evaluating estimator performance — scikit-learn 0.23.2 documentation
3.1. Cross-validation: evaluating estimator performance Learning the parameters of a prediction function and testing it on the same data is a methodological mistake: a model that would just repeat the labels of the samples that it has just seen would have
scikit-learn.org
train data만을 가지고 학습이 잘 되었지만 test data로 평가할때는 score가 안나오는 경우가 발생할 수 있다. 모델이 train data에만 과적합(overfitting)이 되어 test data에는 맞지 않게 되는 것이다. 그래서 test 이전에 validation 과정이 꼭 병행되어야 한다. validation할 data를 잘 뽑아서 train data를 평가하면 과적합을 어느정도 막을 수 있다.
이때, validation할 때 어떠한 data를 가지고 하는지에 대한 부분도 중요하다. train data중 일부를 남겨서 test하는데에 쓰게되면 자칫 일부 남겨진 data에서 중요한 정보를 알지 못하거나 편향된 data가 나올 수 있기 때문에 train data가 모두 학습에 쓰이면서도 validation을 할수 있는 방법이 Cross-Validation(교차검증)이다.
Train set를 Fold 단위로 k개를 무작위로 나눈다. fold 1개를 validation test로 사용하고, 나머지 fold(4개)는 train용으로 사용한다. 그다음에는 다른 fold를 validation test로 정하고 나머지를 train으로 사용하는 방법으로 fold수 만큼 validation을 test하고 최적의 모델을 찾는다.
교차 검증 반복자(Cross Validation iterators)
데이터 성격에 따라서 교차 검증 반복자를 잘 선택해야 한다.
1. 독립적이고 동일한 분포를 가진 경우
KFold, RepeatedKFold, LeaveOneOut(LOO), LeavePOutLeaveOneOut(LPO)
2. 분포가 동일하지 않은 경우
StratifiedKFold, RepeatedStratifiedKFold, StratifiedShuffleSplit
3. 그룹 데이터인 경우
GroupKFold, LeaveOneGroupOut, LeavePGroupsOut, GroupShuffleSplit
4. 시계열 데이터인 경우
TimeSeriesSplit
동일분포
- KFold
import numpy as np from sklearn.model_selection import KFold X = ["a", "b", "c", "d"] kf = KFold(n_splits=2) for train, test in kf.split(X): print("%s %s" % (train, test)) [2 3] [0 1] [0 1] [2 3] |
- Leave One Out(LOO)
from sklearn.model_selection import LeaveOneOut X = [1, 2, 3, 4] loo = LeaveOneOut() for train, test in loo.split(X): print("%s %s" % (train, test)) [1 2 3] [0] [0 2 3] [1] [0 1 3] [2] [0 1 2] [3] |
시계열인 경우
- Time Series Split
from sklearn.model_selection import TimeSeriesSplit X = np.array([[1, 2], [3, 4], [1, 2], [3, 4], [1, 2], [3, 4]]) y = np.array([1, 2, 3, 4, 5, 6]) tscv = TimeSeriesSplit(n_splits=3) print(tscv) TimeSeriesSplit(max_train_size=None, n_splits=3) for train, test in tscv.split(X): print("%s %s" % (train, test)) [0 1 2] [3] [0 1 2 3] [4] [0 1 2 3 4] [5] |
사용법
cross_score = cross_val_score(lin_reg, X_train, Y_train, scoring='neg_mean_squared_error', cv=10) rmse_score = nq.sqrt(-cross_score) rmse_mean = rmse_score.mean() rmse_std = rmse_score.std() |
from sklearn.model_selection import cross_validate cross_validate(SVC(gamma='auto'), X_train, y_train, scoring=['accuracy', 'roc_auc'], return_train_score=True) |