다중 평가 지표: cross_validate()

Scikit-Learn 0.19 버전에 추가된 새로운 기능 시리즈 마지막으로 다중 평가 지표에 대해 알아보겠습니다. 다중 평가 지표란 말 그대로 모델을 평가할 때 여러개의 지표를 이용할 수 있다는 뜻입니다. 0.19 버전에 새롭게 추가된 cross_validate() 함수가 이 기능을 제공합니다.

5.3.5절과 유사한 예제를 만들어 보겠습니다. 먼저 숫자 데이터셋을 불러들여 타깃을 9로 하는 이진 분류 문제로 데이터셋을 훈련 세트와 테스트 세트로 나눕니다.

digits = load_digits()
X_train, X_test, y_train, y_test = train_test_split(
    digits.data, digits.target == 9, random_state=42)

지금까지 교차 검증에 사용했던 cross_val_score() 함수를 훈련 세트에 적용해 보겠습니다. 분류 모델은 SVC()를 사용합니다.

from sklearn.svm import SVC
cross_val_score(SVC(), X_train, y_train)
array([0.90200445, 0.90200445, 0.90200445])

cross_val_score() 함수는 scoring 매개변수에 원하는 평가 지표를 지정할 수 있습니다. 분류 문제일 경우 기본은 정확도를 의미하는 ‘accuracy’입니다. 따라서 다음 코드는 위와 동일한 결과를 출력합니다.

cross_val_score(SVC(), X_train, y_train, scoring='accuracy')

여러개의 평가 지표를 사용하려면 새롭게 추가된 cross_validate() 함수를 사용합니다. cross_val_score()와 마찬가지로 scoring 매개변수에서 평가 지표를 지정할 수 있습니다. 여러개의 평가 지표를 지정하려면 리스트로 만들어 전달하면 됩니다. 이 함수는 디폴트 설정에서 테스트 폴드에 대한 점수 뿐만 아니라 훈련 폴드에 대한 점수도 반환합니다. 향후 버전에서 기본으로 훈련 폴드 점수가 반환되지 않는다는 경고 메세지가 출력되므로 return_train_score 매개변수에서 명시적으로 훈련 폴드의 점수를 받을지 여부를 설정하는 것이 좋습니다.

from sklearn.model_selection import cross_validate
cross_validate(SVC(), X_train, y_train, 
               scoring=['accuracy', 'roc_auc'], 
               return_train_score=True)
{'fit_time': array([0.07761502, 0.07732582, 0.07719207]),
 'score_time': array([0.06746364, 0.06803942, 0.06800795]),
 'test_accuracy': array([0.90200445, 0.90200445, 0.90200445]),
 'test_roc_auc': array([0.99657688, 0.99814815, 0.99943883]),
 'train_accuracy': array([1., 1., 1.]),
 'train_roc_auc': array([1., 1., 1.])}

이 함수는 각 폴드에서 훈련과 테스트에 걸린 시간을 반환하고 scoring 매개변수에 지정한 평가 지표마다 훈련 점수와 테스트 점수를 반환합니다. 훈련 점수와 테스트 점수를 반환된 딕셔너리에서 추출하려면 ‘train_XXXX’, ‘test_XXXX’와 같은 스타일의 키를 사용하면 됩니다.

사실 0.19 버전부터는 cross_val_score() 함수도 cross_validate()를 사용합니다. 그래서 다음 코드는 cross_val_score() 함수와 동일한 결과를 반환합니다.

cross_validate(SVC(), X_train, y_train, 
               scoring=['accuracy'], 
               return_train_score=False)['test_accuracy']

cross_validate() 함수의 scoring 매개변수에 리스트 대신 딕셔너리로 평가 지표를 전달할 수 있습니다. 딕셔너리의 키는 임의의 문자열이 가능합니다. 이렇게 하면 결과 딕셔너리의 키 이름을 간략하게 나타낼 수 있습니다. 다음과 같이 씁니다.

cross_validate(SVC(), X_train, y_train, 
               scoring={'acc':'accuracy', 'ra':'roc_auc'}, 
               return_train_score=False)
{'fit_time': array([0.07760668, 0.07740569, 0.07696486]),
 'score_time': array([0.06791329, 0.06786489, 0.06783247]),
 'test_acc': array([0.90200445, 0.90200445, 0.90200445]),
 'test_ra': array([0.99657688, 0.99814815, 0.99943883])}

평가 지표 mean_squared_error 같이 긴 이름을 자주 참조해야 한다면 이름을 간소하게 나타내는 것이 좋을 것 같습니다.

다중 평가 지표는 cross_validate()는 물론 그리드서치에서도 사용할 수 있습니다. GridSearchCV()의 scoring 매개변수도 마찬가지로 리스트 또는 딕셔너리로 설정할 수 있습니다. 다만 평가 지표를 리스트나 딕셔너리로 설정하려면 refit 매개변수에서 어떤 평가 지표로 선택한 최종 모델을 학습할 것인지 지정해야 합니다.

param_grid = {'gamma': [0.0001, 0.01, 0.1, 1, 10]}
grid = GridSearchCV(SVC(), param_grid=param_grid, 
                    scoring=['accuracy'], refit='accuracy',
                    return_train_score=True)
grid.fit(X_train, y_train)

최적의 파라미터와 교차 검증 점수를 출력해 보겠습니다.

grid.best_params_
{'gamma': 0.0001}
grid.best_score_
0.9651076466221232

gamma가 0.0001이 선택되었습니다. 전체 교차 검증 결과를 출력해 보기 위해서 판다스의 DataFrame으로 만든 다음 넘파이로 행과 열을 바꾸겠습니다(컬럼 제목을 좌측에 놓기 위해서입니다).

np.transpose(pd.DataFrame(grid.cv_results_))

스크린샷 2018-03-13 오후 4.34.44.png

확실히 gamma가 0.0001일 때 mean_test_accuracy가 가장 높습니다. 이제 roc_auc를 추가해 그리드서치를 실행해 보겠습니다.

grid = GridSearchCV(SVC(), param_grid=param_grid, 
                    scoring={'acc':'accuracy', 'ra':'roc_auc'}, refit='ra',
                    return_train_score=True)
grid.fit(X_train, y_train)

최적의 파라미터와 교차 검증 점수를 출력합니다.

grid.best_params_
{'gamma': 0.01}
grid.best_score_
0.9983352038907595

앞에서와 같이 교차 검증 결과를 출력해 보겠습니다. accuracy와 roc_auc에 대해 모두 점수가 출력되므로 꽤 긴 출력이 됩니다. 위에서처럼 gamma가 0.0001일 때는 mean_test_acc가 가장 높지만 gamma가 0.01일 때는 mean_test_ra가 제일 높습니다. refit 매개변수를 ‘ra’로 주었기 때문에 최적 파라미터와 최종 모델은 gamma가 0.01입니다.

스크린샷 2018-03-13 오후 4.37.26

grid.best_estimator_
SVC(C=1.0, cache_size=200, class_weight=None, coef0=0.0,
  decision_function_shape='ovr', degree=3, gamma=0.01, kernel='rbf',
  max_iter=-1, probability=False, random_state=None, shrinking=True,
  tol=0.001, verbose=False)

이 글의 샘플 코드는 ‘파이썬 라이브러리를 활용한 머신러닝‘ 깃허브(https://github.com/rickiepark/introduction_to_ml_with_python/blob/master/cross_validate.ipynb)에서 확인할 수 있습니다.

답글 남기기

아래 항목을 채우거나 오른쪽 아이콘 중 하나를 클릭하여 로그 인 하세요:

WordPress.com 로고

WordPress.com의 계정을 사용하여 댓글을 남깁니다. 로그아웃 /  변경 )

Google+ photo

Google+의 계정을 사용하여 댓글을 남깁니다. 로그아웃 /  변경 )

Twitter 사진

Twitter의 계정을 사용하여 댓글을 남깁니다. 로그아웃 /  변경 )

Facebook 사진

Facebook의 계정을 사용하여 댓글을 남깁니다. 로그아웃 /  변경 )

w

%s에 연결하는 중