-
[사이킷런] 교차 검증 (KFold, Statified KFold)머신러닝 & 딥러닝 2021. 9. 28. 14:54
교차 검증
- 학습 데이터 세트 : 학습 데이터를 분할하여 학습 데이터와 검증 데이터로 나눔.
- 테스트 데이트 세트 : 모든 학습/검증 과정이 완료된 후 최종적으로 성능을 평가하기 위함.
- 교차 검증은 수능을 보기 전, 모의 고사를 여러차례 보는 개념이다.
- 데이터 편증을 막기 위해 여러 세트로 구성된 학습 데이터 세트와 검증 데이터 세트에서 학습과 평가를 수행한다.
- 대부분의 ML 모델의 성능 평가는 교차 검증 기반으로 1차 평가를 한 뒤, 테스트 데이터 세트를 적용해 평가는 프로세스다.
K-Fold 교차 검증
- 가장 보편적인 교차 검증 기법이다.
- K개의 데이터 폴드 세트를 만든 뒤, k번 만큼 각 폴드 세트에 학습과 검증 평가를 반복적으로 수행한다.
- k=5 일 경우, 총 5개의 폴드 세트에 5번의 학습과 검증 평가 반복 수행
- 교차 검증 최종 평가 = 평균(평가 1, 2, 3, 4, 5)
- 일반 k 폴드
- Stratified K 폴드 : 불균형한 분포드를 가진 레이블 데이터를 위한 방식.
- 학습 데이터와 검증 데이터 세트가 가지는 레이블 분포도가 유사하도록 검증 데이터 추출
- KFold 클래스를 이용한 교차 검증 방법
- 폴드 세트 설정
- for 루프에서 반복적으로 학습/검정 데이터 추출 및 학습과 예측 수행
- 폴드 세트별로 예측 성능을 평균화하여 최종 성능 평가
K-Fold 예시
from sklearn.datasets import load_iris from sklearn.tree import DecisionTreeClassifier from sklearn.metrics import accuracy_score from sklearn.model_selection import KFold import numpy as np iris = load_iris() features = iris.data label = iris.target dt_clf = DecisionTreeClassifier(random_state=156) # 5개의 폴드 세트로 분리하는 KFold 객체 생성 kfold = KFold(n_splits=5) cv_accuracy = [] # 폴드 세트별 정확도를 담을 리스트 print('붓꽃 데이터 세트 크기: ', features.shape[0]) n_iter = 0 # 전체 붓꽃 데이터를 5개의 폴드 데이터 세트로 분리. 전체 데이터는 150개 이므로, 학습용 데이터는 120개, 검증 테스트 데이터 세트는 30개로 분류. for train_index, test_index in kfold.split(features): X_train, X_test = features[train_index], features[test_index] y_train, y_test = label[train_index], label[test_index] # 학습, 예측 dt_clf.fit(X_train, y_train) pred = dt_clf.predict(X_test) n_iter += 1 # 정확도 계산 accuracy = np.round(accuracy_score(y_test, pred), 4) train_size = X_train.shape[0] test_size = X_test.shape[0] print('\n#{0} 교차 검증 정확도 : {1}, 학습 데이터 크기: {2}, 검증 데이터 크기: {3}' .format(n_iter, accuracy, train_size, test_size)) print('#{0} 검증 세트 인덱스: {1}'.format(n_iter, test_index)) cv_accuracy.append(accuracy) print('\n## 평균 검증 정확도: ', np.mean(cv_accuracy))
결과
Stratified K 폴드
- 불균형한 분포도를 가진 레이블(결정 클래스) 데이터 집합을 위한 K 폴드 방식이다.
- 불균형한 분포도를 가진 레이블이란 특정 레이블 값이 유독 많거나 적어서 한쪽으로 치우진 경우를 뜻한다.
- K폴드가 레이블 데이터 집합이 원본 데이터 집합의 레이블 분포를 학습 및 테스트 세트에 제대로 분배하지 못하는 경우 해걸한다.
- 원본 데이터의 레이블 분포를 먼저 고려한 뒤, 이 분포와 동일하게 학습과 검증 데이터 세트를 분배한다.
- 분류(Classification)에서 교차검증을 할 때, Stratified K폴드로 분할되어야 한다.
- 회귀(Regression)에서는 Stratified K폴드가 지원되지 않는다.
Stratified K폴드 예시
from sklearn.model_selection import StratifiedKFold dt_clf = DecisionTreeClassifier(random_state=156) skfold = StratifiedKFold(n_splits = 3) n_iter = 0 cv_accuracy = [] # skfold.split()의 경우 반드시 레이블 데이터 세트를 입력해야 한다. for train_index, test_index in skfold.split(features, label): # 학습용, 검증용 테스트 데이터 추출 X_train, X_test = features[train_index], features[test_index] y_train, y_test = label[train_index], label[test_index] # 학습, 예측 dt_clf.fit(X_train, y_train) pred = dt_clf.predict(X_test) n_iter += 1 accuracy = np.round(accuracy_score(y_test, pred), 4) train_size = X_train.shape[0] test_size = X_test.shape[0] print('\n#{0} 교차 검증 정확도 : {1}, 학습 데이터 크기: {2}, 검증 데이터 크기: {3}' .format(n_iter, accuracy, train_size, test_size)) print('#{0} 검증 세트 인덱스: {1}'.format(n_iter, test_index)) cv_accuracy.append(accuracy) print('\n## 평균 검증 정확도: ', np.mean(cv_accuracy))
cross_val_score()
- cross_val_score() 함수로 폴드 세트 추출, 학습/예측, 평가를 한번에 수행 가능.
- cross_val_score()의 파라마타
- estimator: classifier 또는 regressor
- X: 피처 데이터 세트
- y: 레이블 데이터 세트
- scoring: 예측 성능 평가 지표
- cv: 교차 검증 폴드 수
cross_val_score() 예시
from sklearn.datasets import load_iris from sklearn.tree import DecisionTreeClassifier from sklearn.model_selection import cross_val_score, cross_validate iris_data = load_iris() dt_clf = DecisionTreeClassifier(random_state=156) data = iris_data.data label = iris_data.target scores = cross_val_score(dt_clf, data, label, scoring='accuracy', cv=3) print('교차 검증별 정확도: ', np.round(scores, 4)) print('평균 검증 정확도: ', np.round(np.mean(scores), 4))
교차 검증별 정확도: [0.98 0.94 0.98]
평균 검증 정확도: 0.9667
GridSearchCV
- 교차 검증과 최적 하이퍼 파라미터 튜닝을 한번에 할 수 있다.
- 머신러닝 알고리즘을 튜닝하기 위한 파라미터가 하이퍼 파라미터.
- 촘촘하게 파라미터를 입력하면서 테스트 하는 방식이다.
- 데이터 세트를 cross-validation을 위한 학습/테스트 세트로 자동으로 분할 한 뒤에 하이퍼 파라미터 그리드에 기술된 모든 파라미터를 순차적으로 적용하여 최적의 파라미터를 찾는다.
- 파라미터
- estimator: classifier, regressor, pipeline
- param_grid: 딕셔너리로 주어진다.
- scoring : 예측 성능을 측정할 평가 방법
- cv: 학습 / 테스트 세트의 개수
- refit: 디폴트가 true, true일 때 가장 최적의 파라미터를 찾은 뒤 하이퍼 파라미터로 재학습 시킨다.
GridSearchCV 예시
from sklearn.datasets import load_iris from sklearn.tree import DecisionTreeClassifier from sklearn.model_selection import GridSearchCV, train_test_split import pandas as pd iris_data = load_iris() X_train, X_test, y_train, y_test = train_test_split(iris_data.data, iris_data.target, test_size = 0.2, random_state=121) dtree = DecisionTreeClassifier() # 파라미터는 딕셔너리 형태로 입력 parameters = {'max_depth': [1, 2, 3], 'min_samples_split' : [2, 3] } # param_grid의 하이퍼 파라미터를 3개의 train, test set fold로 나누어서 테스트를 수행한다. grid_dtree = GridSearchCV(dtree, param_grid=parameters, cv=3, refit=True) # 붓꽃 학습 데이터로 param_grid의 하이퍼 파라미터를 순차적으로 학습 및 평가 grid_dtree.fit(X_train, y_train) scores_df = pd.DataFrame(grid_dtree.cv_results_) scores_df[['params', 'mean_test_score', 'rank_test_score', 'split0_test_score', 'split1_test_score', 'split2_test_score']]
'머신러닝 & 딥러닝' 카테고리의 다른 글
[분류] 앙상블 (0) 2021.10.14 [분류] 결정 트리 (0) 2021.10.13 [평가] 정확도/정밀도/재현율/F1 스코어/ROC AUC (0) 2021.10.05 [사이킷런] 타이타닉 생존자 예측하기 (0) 2021.10.01 [사이킷런] 데이터 전처리 (Preprocessing) (0) 2021.09.29