#!/usr/bin/env python3
parameter overfitting
이전 포스팅에서 평가를 위해서는 모델을 만들 때 사용하지 않은 독립된 데이터셋이 필요하다고 했습니다.
독립된 데이터셋을 사용하는 방법에는 2가지가 있습니다.
첫 번째는 train_test_split을 2번 사용하여 데이터를 3등분하는 것이고
두 번째는 cross-validation을 사용하는 것입니다.
우선 첫 번째 방법부터 살펴보겠습니다. 이 방법은 아래 소스를 통해 그래프로 확인할 수 있습니다.
# library import
import mglearn
import matplotlib
import matplotlib.pyplot as plt
# matplotlib 설정
matplotlib.rc('font', family='AppleGothic') # 한글폰트
plt.rcParams['axes.unicode_minus'] = False # 축 -
mglearn.plots.plot_threefold_split()
plt.show()
training set, validation set, test set의 3개의 폴드로 나눈 데이터
1. train_test_split을 이용한 iris데이터의 grid search
이번에는 iris 데이터로 살펴보겠습니다.
# load library
from sklearn.svm import SVC
from sklearn.model_selection import train_test_split
from sklearn.datasets import load_iris
# data load
iris = load_iris()
# train_test_split 1번
x_trainvalid, x_test, y_trainvalid, y_test=\
train_test_split(iris.data, iris.target, random_state=0)
# train_test_split 2번
x_train, x_valid, y_train, y_valid =\
train_test_split(x_trainval, y_trainval, random_state=1)
print('x_train size:{}\nx_valid size:{}\nx_test size:{}'.format(x_train.shape, x_valid.shape, x_test.shape))
# x_train size:(84, 4)
# x_valid size:(28, 4)
# x_test size:(38, 4)
# grid search
values = [0.001, 0.01, 0.1, 1, 10, 100]
best_score = 0
for g in values:
for c in values:
svc = SVC(C=c, gamma=g).fit(x_train, y_train)
scores = svc.score(x_valid, y_valid) # 검증세트로 svc를 평가
if scores > best_score:
best_score = scores
best_param = {'C':c, 'gamma':g}
svc = SVC(**best_param).fit(x_trainvalid, y_trainvalid) # **kwargs: 딕셔너리 형태로 함수에 인자를 넘김
score_svc = svc.score(x_test, y_test)
print('최적 매개변수 점수 ==> {:.3f}'.format(best_score))
print('최적 매개변수 ==> {}'.format(best_param))
print('최적 매개변수에서 test ==> {:.3f}'.format(score_svc))
# 최적 매개변수 점수 ==> 0.964
# 최적 매개변수 ==> {'C': 10, 'gamma': 0.001}
# 최적 매개변수에서 test ==> 0.921
>> 최적 매개변수에서 최고점수는 96.4%이며 테스트 세트 점수는 92.1%입니다.
즉 새로운 데이터에 대해 92.1%만 정확하게 분류한다고 볼 수 있습니다.
테스트 세트로 둘 이상의 모델을 평가해서 그 중 더 나은 하나를 선택하는 것은 모델의 정확도를 매우 낙관적으로 추정하거나,
overfitting이 생길 수 있으므로 주의해야합니다.
2. cross-validaion을 이용한 iris데이터의 grid search
일반화 성능을 더 잘 평가하려면 훈련 세트와 검증 세트를 한 번만 나누지 않고
cross-validation을 사용해서 각 매개변수 조합의 성능을 평가할 수 있습니다.
cross-validation을 통해 어떤 매개변수가 선택되는지를 살펴보면
# library import
import mglearn
import matplotlib.pyplot as plt
mglearn.plots.plot_cross_val_selection()
plt.show()
cross-validation을 사용한 grid search의 결과
>> [0.001, 0.01, 0.1, 1, 10, 100]를 C와 gamma로 각각 설정한 후, cross-validation 에 한개씩, 모두 5개의 값을 계산합니다.
총 6x6x5 = 180개의 모델을 만들어서 모델 검정을 하기때문에 시간이 오래 걸립니다.
# library import
import numpy as np
from sklearn.svm import SVC
from sklearn.datasets import load_iris
from sklearn.model_selection import train_test_split
# datasets
iris = load_iris()
# data partition
x_train, x_test, y_train, y_test = \
train_test_split(iris.data, iris.target,
random_state=0, test_size=0.3)
# grid search
values = [0.001, 0.01, 0.1, 1, 10, 100]
best_score = 0
for g in values:
for c in values:
svc = SVC(gamma=g, C=c).fit(x_train, y_train)
kfold = KFold(n_splits=5, shuffle=True, random_state=0)
scores = cross_val_score(svc, x_train, y_train, cv=kfold)
score = np.mean(scores)
if score > best_score:
best_score = score
best_param = {'gamma':g, 'C':c}
# 최적 매개변수로 모델을 다시 만듬
svc = SVC(**best_param).fit(x_train, y_train)
print('최적 매개변수 점수 ==> {:.3f}'.format(best_score))
print('최적 매개변수 ==> {}'.format(best_param))
print('최적 매개변수에서 test ==> {:.3f}'.format(svc.score(x_test, y_test)))
# 최적 매개변수 점수 ==> 0.981
# 최적 매개변수 ==> {'gamma': 0.01, 'C': 100}
# 최적 매개변수에서 test ==> 0.978
cross-validation을 사용한 grid search를 매개변수 조정 방법으로 많이 사용하기 때문에
scikit-learn은 GridSearchCV를 제공합니다.
GridSearchCV는 딕셔너리 형태로 검색 대상 매개변수를 지정하며 필요한 모든 모델을 학습합니다. 아래 소스는 위의 소스와 같은 결과를 냅니다.
# library import
from sklearn.svm import SVC
from sklearn.datasets import load_iris
from sklearn.model_selection import train_test_split, GridSearchCV, KFold
# data load
iris = load_iris()
# data parition
x_train, x_test, y_train, y_test = \
train_test_split(iris.data, iris.target,
random_state=0, test_size=0.3)
# create object
svc = SVC() # SVC모델 생성
kfold = KFold(n_splits=5, shuffle=True, random_state=0) # cross-validation
values = [0.001, 0.01, 0.1, 1, 10, 100]
param_grid = {'gamma':values, 'C':values} # GridSearchCV의 딕셔너리 생성
grid_search = GridSearchCV(svc, param_grid, cv=kfold)
grid_search.fit(x_train, y_train)
score = grid_search.score(x_test, y_test)
print('GridSearchCV를 이용한 최적 매개변수 점수 ==> {:.3f}'.format(grid_search.best_score_))
print('GridSearchCV를 이용한 최적 매개변수 ==> {}'.format(grid_search.best_params_))
print('GridSearchCV를 이용한 test점수 ==> {:.3f}'.format(score))
print('GridSearchCV를 이용한 최고 성능 모델 ==> \n{}'.format(grid_search.best_estimator_))
# GridSearchCV를 이용한 최적 매개변수 점수 ==> 0.981
# GridSearchCV를 이용한 최적 매개변수 ==> {'C': 10, 'gamma': 0.1}
# GridSearchCV를 이용한 test점수 ==> 0.978
# GridSearchCV를 이용한 최고 성능 모델 ==>
#SVC(C=10, cache_size=200, class_weight=None, coef0=0.0, decision_function_shape='ovr', degree=3, gamma=0.1, kernel='rbf', max_iter=-1, probability=False, random_state=None, shrinking=True, tol=0.001, verbose=False)
>> 이 소스는 더 간결해졌지만 많은 내용을 함축하고 있습니다.
다음에는 GridSearchCV를 통해 cross-validation 결과를 시각화 해보겠습니다.
참고 자료:
[1]Introduction to Machine Learning with Python, Sarah Guido
'모델 평가와 성능 향상 > 그리드 서치' 카테고리의 다른 글
nested cross-validation (1) | 2018.04.05 |
---|---|
asymmetric parameter with grid search (0) | 2018.04.05 |
cross-validation result analysis (2) | 2018.04.05 |
simple grid search (1) | 2018.04.03 |