교차 검증
교차검증이 필요한 이유
학습데이터와 검증데이터를 분류한다 해도 과적합에 취약하다. 과적합이란 모델이 학습 데이터에만 과도하게 최적화되어 다른 데이터를 예측할 때 성능이 상당히 떨어지는 것을 말한다. 이러한 편향모델이 생기지 않도록 교차 검증을 이용한다.
K 폴드(KFold) 교차검증
k-음식, k-팝 그런 k 아니다.
아무튼. KFold cross validation은 가장 보편적으로 사용되는 교차 검증 방법이다. 아래 사진처럼 k개의 데이터 폴드 세트를 만들어서 k번만큼 각 폴드 세트에 학습과 검증 평가를 반복적으로 수행하는 방법이다.
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=1)
# 5개의 폴드 세트로 분리하는 KFold 객체와 폴드 세트별 정확도를 담을 리스트 객체 생성.
kfold = KFold(n_splits=5)
cv_accuracy = []
# 붓꽃 데이터 세트 크기를 알아보자
print(features.shape[0])
이후 kfold.split()을 이용해 교차검증 해본다.
n_iter = 0
# KFold객체의 split( ) 호출하면 폴드 별 학습용, 검증용 테스트의 로우 인덱스를 array로 반환
for train_index, test_index in kfold.split(features):
# kfold.split( )으로 반환된 인덱스를 이용하여 학습용, 검증용 테스트 데이터 추출
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]
cv_accuracy.append(accuracy)
print('평균 검증 정확도:', np.mean(cv_accuracy))
Stratified K 폴드(KFold)
데이터가 전부 일정한 것이 아닌 불균형한 분포도를 가진 데이터 집합을 위한 k 폴드 방식이다. 예를 들어서 전세 데이터가 10억 개 있는 상황에서 전세사기 데이터가 수십 개 정도로 가정한다. 그럼 매우 작은 비율이기에 상대적으로 어느 데이터에는 전세사기 피처값이 아예 없거나 다른 데이터에는 몰려있거나 할 수 있다. 이 전세사기 데이터는 수가 매우 적지만 전세사기를 예측하기 위한 가장 중요한 피처 값이기에 원본 데이터와 유사하게 분포를 학습해야 한다.
즉 결론적으로 fold에서 학습 데이터셋과 검증 데이터셋을 나누기 전에 피처 클래스 불균형을 균형해지도록 데이터셋을 분할하는 것을 말한다.
from sklearn.model_selection import StratifiedKFold
skf = StratifiedKFold(n_splits=3)
n_iter=0
for train_index, test_index in skf.split(iris_df, iris_df['label']):
n_iter += 1
label_train= iris_df['label'].iloc[train_index]
label_test= iris_df['label'].iloc[test_index]
이런 식으로 사용해 준다.
이렇게 되면 동일한 분포도를 보일 수 있다.
하지만! 이걸 우리가 일일이 계속 치기에는 우리는 프로그래머스럽지 못하기 때문에 착한 사이킷런 개발자들이 API를 제공해 준다.
cross_val_score()
앞에 있는 일련의 과정들을 한꺼번에 해주는 API이다. 이 함수는 StratifiedKfold방식으로 진행한다.
from sklearn.tree import DecisionTreeClassifier
from sklearn.model_selection import cross_val_score , cross_validate
from sklearn.datasets import load_iris
iris_data = load_iris()
dt_clf = DecisionTreeClassifier(random_state=156)
data = iris_data.data
label = iris_data.target
# 성능 지표는 정확도(accuracy) , 교차 검증 세트는 3개
scores = cross_val_score(dt_clf , data , label , scoring='accuracy',cv=3)
print('교차 검증별 정확도:',np.round(scores, 4))
print('평균 검증 정확도:', np.round(np.mean(scores), 4))
cross_val_score(estimator, X, y=none, scoring=none, cv=none, ~~)
estimator - 사이킷런 의 분류 알고리즘 클래스
X - 피쳐 데이터 세트(문제지 개념)
y - 레이블 데이터 세트 (정답지 개념)
scoring - 예측 성능 평가 지표
cv - 교차 검증 폴드 수
즉, 우리는 한 줄로 머신러닝 모델의 정확도를 올릴 수 있게 되었다.