Data

검증세트 활용방법 - 교차 검증

HC-Kang 2021. 5. 12. 17:46

혼자 공부하는 머신러닝+딥러닝 / 박해선 저

 

검증세트

  - 기존처럼 데이터를 triain set과 test set으로만 분할해서 활용하면, 내가 구축한 모델이 과대적합인지 과소적합인지 판단하기 어려움.

  - 이 때 테스트 세트를 활용하지 않고 내 모델을 평가하기 위해 별도로 검증세트를 두는 개념임.

  - 일반적으로 전체 100의 데이터 중 훈련 세트를 약 60%, 검증과 테스트 세트를 각 20%씩으로 분할해서 활용.

 

1. 검증세트의 개념 직접 만들어보기

import pandas as pd
import numpy as np

wine = pd.read_csv('https://bit.ly/wine_csv_data')

data = wine[['alcohol', 'sugar', 'pH']].to_numpy()
target = wine['class'].to_numpy()
        # 자료 불러오고 독립변수 data와 종속변수 target으로 분할.

from sklearn.model_selection import train_test_split
        # train 과 test 데이터로 나누기 위한 train_test_split 함수 불러오기

train_input, test_input, train_target, test_target = train_test_split(
    data, target, test_size = 0.2, random_state = 42)
        # 1차적으로 train, test 셋 나눠주기, test_size는 설정 안하면 0.25 / random_state는 seed를 고정하기 위함.

sub_input, val_input, sub_target, val_target = train_test_split(
    train_input, train_target, test_size = 0.2, random_state = 42)
        # train 셋을 검증셋과 트레인셋으로 다시 한 번 8:2로 분할.

print(sub_input.shape, val_input.shape)
        # (4157, 3) (1040, 3)
        # 분할이 제대로 되었는지 shape 함수를 통해 확인

from sklearn.tree import DecisionTreeClassifier
        # sklearn의 의사결정나무 분류기 불러오기

dt = DecisionTreeClassifier(random_state=42)
dt.fit(sub_input, sub_target)
        # 훈련셋을 통한 학습

print(dt.score(sub_input, sub_target))
        # 0.977
print(dt.score(val_input, val_target))
        # 0.864

 

2. 교차 검증

from sklearn.model_selection import cross_validate
        # 교차검증 함수 불러오기
scores = cross_validate(dt, train_input, train_target)
print(scores)

cross_validate 함수를 불러와 scores로 인스턴스 생성.

이 함수는 cv = None 인 경우 기본적으로 5-Fold cross validation을 수행함.

이후 그 결과값으로

 - 'fit_time' : 모델 훈련 소요시간

 - 'score_time' : 모델 검증 소요시간

 - 'test_score' : 교차검증의 최종 점수

 위 세 가지 키를 가진 딕셔너리를 반환함. 지금 수준에서 내가 가장 관심있는 것은 세번째인 test_score뿐

 

print(np.mean(scores['test_score']))
        # 0.8697

이 값은 현재 가진 테스트세트를 가지고 5종류의 검증세트를 만들어 돌려봤을 때의 평균으로, 대략적인 내 모델의 성능을 가늠할수 있음.

 

다만, 방금은 train_test_split 함수로 한 번 섞어서 미리 분할을 했기때문에 바로 사용해도 무관하지만 

cross_validate 함수는 훈련세트를 섞어주지 않음. 때문에 훈련세트를 섞기 위한 분할기(splitter)를 별도로 지정해야 함.

 

cross_validate 함수는 회귀 모델일 경우 KFold 분할기를 사용하고 분류 모델일 경우 StratifiedKFold를 사용.

from sklearn.model_selection import StratifiedKFold
splitter = StratifiedKFold(n_splits = 10, shuffle = True, random_state = 42)
scores = cross_validate(dt, train_input, train_target, cv = splitter)
print(np.mean(scores['test_score']))
        # 0.8574181117533719

StratifiedKFold의 기본값은 n_splits = 5로 5-fold 검증을 수행하나 여기서는 10으로 지정하였음.