Cross-validation + Grid Search
- 데이터를 train, validation, test set으로 나누는 방법은 성능이 좋고 널리 사용되지만, 전 게시글과 같이 데이터를 나누는 방법에 매우 민감
- 일반화 성능을 더 잘 평가하기 위해서는 훈련세트와 검증세트를 한번만 나누지 않고, 교차 검증을 사용해서 각 매개 변수의 조합의 성능을 평가 할 수 있음
# 1. 데이터 분할
iris = datasets.load_iris()
X = iris.data
y = iris.target
X_trainval, X_test, y_trainval, y_test = train_test_split(X,y,test_size=0.25, random_state=0)
# 2. Cross-validation + Grid Search
best_score = 0
for gamma in [0.001,0.01,0.1,1,10,100]:
for C in [0.001,0.01,0.1,1,10,100]:
# train SVC using combination of gamma and C
svm = SVC(gamma = gamma, C = C)
# evaluate model
scores = cross_val_score(svm, X_trainval, y_trainval, cv=5) # svm 모델 사용, 검증 나누지 않고 train데이터 사용
# mean of cross-validation
score = np.mean(scores)
# restore the highest score with its parameter
if score > best_score:
best_score = score
best_parameter = {'gamma':gamma, 'C':C}
svm = SVC(**best_parameter)
svm.fit(X_trainval,y_trainval) # train + validation 모두 합한 데이터 가지고 평가
train_score = svm.score(X_trainval, y_trainval) # 테스트에 대한 점수
test_score = svm.score(X_test, y_test)
train_score,test_score
# output : (0.9821428571428571, 0.9736842105263158)
< GridSearchCV >
- 교차 검증을 사용한 그리드 서치를 매개변수 조정 방법으로 널리 사용하므로, scikit-learn은 GridSearchCV를 제공하고 있음
- 검색 대상이 되는 매개변수를 딕셔너리 자료형으로 구성해야 함
from sklearn.model_selection import GridSearchCV
# 1. parameter grid 생성
param_grid = {'C':[0.001,0.01,0.1,1,10,100],'gamma':[0.001,0.01,0.1,1,10,100] }
# 2. GridSearchCV 이용하여 객체 생성
grid_search = GridSearchCV(SVC(), param_grid, cv =5, return_train_score=True)
# 3. 데이터 분할
## 데이터가 과대적합 되는 것을 방지하기 위해, 또한 최종 모델의 객관적인 정확도 평가를 위해 test data를 분리하고
## gridsearch 및 cross-validation에 사용되지 않도록 한다
X_train, X_test, y_train, y_test = train_test_split(iris.data, iris.target, random_state=0 ,test_size=0.2)
# 4. gridsearch model
grid_search.fit(X_train, y_train)
# 5. model evaluation
print("test set score : {}".format(grid_search.score(X_test, y_test)))
# output : test set score : 1.0
# 6. best parameter and best score
print("best parameters : {}".format(grid_search.best_params_))
print("best score : {}".format(grid_search.best_score_))
# output : best parameters : {'C': 1, 'gamma': 0.1}
# best score : 0.9583333333333334
- 여기서 5. 과 6. 의 결과를 구분하는 것이 필요
- 5. : 교차 검증과 그리드 서치의 결과로 산정한 최적 매개변수를 적용하여 전체 훈련 데이터 셋에 대해 훈련한 최종 모델에 테스트 데이터로 적용했을 때의 결과
- 6. : best_score_ 속성은 훈련 세트에서 수행한 교차검증의 평균 정확도가 저장된 결과
* GridSearchCV.fit 메서드는 최적의 매개변수를 찾는 일뿐만 아니라, 교차 검증 성능이 가장 좋은 매개변수로 전체 훈련 데이터 세트에 대해 새로운 모델을 자동으로 만든다.
[교차 검증 결과 분석]
- 결과를 시각화하면 검색 대상 매개변수가 모델의 일반화에 영향을 주는 정도를 이해하는데 도움을 준다
- grid search는 연산 비용이 높으므로, 비교적 간격을 넓게 하여 적은 수의 그리드로 시작하는 것이 좋다.
- 이후 결과를 분석하여 검색을 확장해 나갈 수 있다
- 그리드 서치의 결과는 cv_results_ 속성에 있다
import pandas as pd
import numpy as np
import matplotlib.pyplot as plt
# 1. cv_results_ dictionary -> dataFrame
results = pd.DataFrame(grid_search.cv_results_)
# 2. first 5 rows
results.head(5)
# 여기서 grid_search.cv_results_ 의 값들을 확인 할 수 있다.
# 3. heatmap
scores = np.array(results.mean_test_score.sort_values(ascending=False)).reshape(6,6)
fig, ax = plt.subplots()
im = ax.imshow(scores, cmap='PiYG')
cbar = ax.figure.colorbar(im, ax=ax)
cbar.ax.set_ylabel(ylabel="parameter C ", rotation=-90, va = "bottom")
ax.set_xticks(np.arange(len(set(results.param_gamma))))
ax.set_yticks(np.arange(len(set(results.param_C))))
ax.set_xticklabels(param_grid['gamma'])
ax.set_yticklabels(param_grid['C'])
for i in range(len(param_grid['C'])):
for j in range(len(param_grid['gamma'])):
text = ax.text(j,i,np.round(scores[i,j],2),ha='center', va='center',color='k')
ax.set_title("Mean Test Score Heatmap by GridSearchCV")
ax.set_xlabel("gamma")
'머신러닝 in Python' 카테고리의 다른 글
[Python] openCV 이용한 얼굴인식 (0) | 2019.09.03 |
---|---|
[Python] PCA(주성분 분석) (0) | 2019.09.03 |
[Python] Grid Search (0) | 2019.08.30 |
[Python] Cross-validation(교차검증) (1) | 2019.08.30 |
[Python] 분류분석 - SVM(Support Vector Machine) (1) | 2019.08.29 |