본문 바로가기

ML with SckitLearn

train_test_split()의 사용과 교차 검증 cross_val_score 이용하기

반응형

train_test_split()

train_test_split()은 데이터 세트를 학습 데이터와 테스트 데이터로 분리할 때 사용하는 함수입니다. 

 

from sklearn.model_selection import train_test_split
from sklearn.datasets import load_iris
from sklearn.model_selection import cross_val_score
import pandas as pd
import numpy as np

iris = load_iris()
iris_data = iris.data
iris_label = iris.taget

X_train, X_test, y_train, y_test = train_test_split(iris_data, iris_label, test_size=0.2, random_state=11)

train_test_split()의 파라미터는

+ iris_data : feature data set

+ iris_label : label data set

+ test_size=0.2 : 전체 데이터 세트 중 테스트 데이터 세트의 비율입니다.

+ random_state=11 : 호출할 때마다 같은 학습/테스트 용 데이터 세트를 생성하기 위해 주어지는 난수 발생 값입니다. train_test_split()는 호출 시 무작위로 데이터를 분리하므로 random_state를 지정하지 않으면 수행할 때마다 다른 학습/테스트 용 데이터를 만들 수 있습니다. 동일한 데이터 세트로 분리하기 위해 random_state를 일정한 숫자 값으로 부여하면 됩니다. 

+ 결과값으로 X_train, X_test, y_train, y_train의 의미

X_train은 학습용 피처 데이터 세트, X_test는 테스트용 피처 데이터 세트, y_train은 학습용 레이블 데이터  세트, y_test는 테스트용 레이블 데이터 세트입니다.

 

fit(), predict()에 대한 자세한 사항은 이곳으로 이동합니다.

 

 

여기서 잠시!

데이터에는 성질에 따라 Train, Validation, Test가 있습니다. 

  • Train: 모델을 학습시키기 위한 dataset입니다. 중요한 것은 "모델을 학습하는데에는 오직 유익하게 Train Dataset만 이용한다"입니다.
  • Test: 학습과 검증이 검증이 완료된 모델의 성능을 평가하기 위한 dataset
  • Validation: 이미 학습된 완료된 모델을 검증하기 위한 dataset으로 Train에서 일부를 차용하며 8:2의 비율로 Validation에서 2를 가져오게 됩니다.

validation set과 test set의 공통점은 이 데이터를 통해 모델을 update 즉, 학습을 시키지 않는다는 것이다. 이렇게 validation set과 test set은 둘다 이미 학습을 완료한 모델에 대해 평가하고 학습을 시키지 않는데 "그렇다면 둘의 차이는 과연 무엇일까?" 결론부터 말하자면 둘의 차이는 Validation set은 모델을 update, 즉 학습을 시키진 않지만 학습에 '관여'는 한다. Test set은 학습에 전혀 관여하지 않고 오직 '최종 성능'을 평가하기 위해 쓰이게 됩니다. 

 

위 그림을 보면 파란색 baseline을 기준으로 더 학습시키면 overfitting되어 test set에 대한 결과가 점점 안 좋아지며. 따라서 우리는 파란색 baseline 까지만 학습을 해야합니다. 다시말해, 파란색 baseline에 해당하는 epoch를 찾아야하는데 이때 test set은 '최종 성능' 평가할때만 사용하므로 학습에 이처럼 관여해서는 안되어 결국 여기서 validation set이 사용되는 것이다.

 


교차 검증

아무리 학습데이터와 이에 대한 예측 성능을 평가하기 위한 별도의 테스트용 데이터가 필요하다고 하여도 과적합(Overfitting)에 취약한 약점을 가질 수 있습니다. 과적합은 모델이 학습 데이터에만 과도하게 최적화되어, 실제 예측을 다른 데이터로 수행할 경우에는 예측 성능이 과도하게 떨어지는 것을 말합니다.

 

그런데 고정된 학습 데이터와 테스트 데이터로 평가를 하다 보면 테스트 데이터에만 최적의 성능을 발휘할 수 있도록 편향되게 모델을 유도하는 경향이 생기게 됩니다. 결국 해당 데이터에만 과적합되는 학습 모델이 만들어져 다른 테스트용 데이터가 들어올 경우에는 성능이 저하됩니다. 이러한 문제점을 개선하기 위해 교차 검증을 이용해 더 다양한 학습과 평가를 수행합니다.

 

교차 검증은 이러한 데이터 편증을 막기 위해서 별도의 여러 세트로 구성된 학습 데이터 세트와 검증 데이터 세트에서 학습과 평가를 수행하는 것입니다.  그리고 각 세트에서 수행한 평가 결과에 따라 하이퍼 파라미터 튜닝 등의 모델 최적화를 손쉽게 할 수 있습니다.

 

대부분의 ML 모델의 성능 평가는 교차 검증 기반으로 1차 평가를 한 뒤에 최종적으로 테스트 데이터 세트에 적용해 평가하는 프로세스입니다. K폴드 검증, Stratified K 폴드 검증도 있으나 사이킷런에서는 교차 검증을 좀 더 편리하게 수행할 수 있게 해주는 API가 있습니다. 

 

바로 cross_val_score()입니다.

 


cross_val_score()

cross_val_score()는 하기와 같은 형식을 가지고 있습니다.

cross_val_score(estimator, X, y=None, *, groups=None, scoring=None, cv=None, n_jobs=None, verbose=0, fit_params=None, pre_dispatch='2*n_jobs', error_score=nan)

+estimator : 사이킷런의 분류 알고리즘 클래스인 Classfier 또는 회귀 알고리즘 클래스인 Regressor를 의미

+x : 피처 데이터 세트

+y : 레이블 데이터 세트

+scoring : 예측 성능 평가 지표 기술, 원하는 지표를 정확하게 넣어주어야 합니다. [이곳을 참고하세요]

+cv : 교차 검증 폴드 수를 의미

 

from sklearn.model_selection import train_test_split
from sklearn.metrics import accuracy_score
from sklearn.model_selection import cross_val_score
from sklearn.datasets import load_iris
from sklearn.tree import DecisionTreeClassifier
import pandas as pd
import numpy as np

iris = load_iris()
iris_data = iris.data
iris_label = iris.target

X_train, X_test, y_train, y_test = train_test_split(iris_data, iris_label, test_size=0.2, random_state=15)

dt_clf = DecisionTreeClassifier(random_state=11)
dt_clf.fit(X_train, y_train)
pred = dt_clf.predict(X_test)
print('예측 정확도: {0:.4f}'.format(accuracy_score(y_test, pred)))

scores = cross_val_score(dt_clf, iris_data, iris_label, scoring='accuracy', cv=3)
print('교차 검증별 정확도\n', np.round(scores,4))
print('평균 검증 정확도\n', np.round(np.mean(scores),4))

 

예측 정확도: 0.9667

교차 검증별 정확도
 [0.98 0.92 0.98]

평균 검증 정확도
 0.96
반응형