Notice
Recent Posts
Recent Comments
Link
| 일 | 월 | 화 | 수 | 목 | 금 | 토 |
|---|---|---|---|---|---|---|
| 1 | 2 | 3 | 4 | |||
| 5 | 6 | 7 | 8 | 9 | 10 | 11 |
| 12 | 13 | 14 | 15 | 16 | 17 | 18 |
| 19 | 20 | 21 | 22 | 23 | 24 | 25 |
| 26 | 27 | 28 | 29 | 30 |
Tags
- 파레토그림
- 코딩테스트
- 천선란
- 칵테일러브좀비
- 로맹가리
- 점도표
- 백준
- 정세랑
- 주피터노트북
- 레귤러
- 진짜 게으른 사람이 쓴 게으름 탈출법
- 천개의파랑
- 보스턴숄더백
- 자기앞의생
- K-NN
- 선량한차별주의자
- 도수다각형
- 사이킷런
- 붕대감기
- 파이썬
- 알고리즘
- Bostonshoulderbag
- 시선으로부터
- scikit-learn
- 여름의빌라
- 에밀아자르
- 백수린
- 점프투파이썬
- Python
- 머신러닝
Archives
- Today
- Total
Blog
[Python] 그리드서치(Grid search) 실습 본문
패키지 불러오기¶
In [1]:
%matplotlib inline
from IPython.display import display
import numpy as np
import matplotlib.pyplot as plt
import pandas as pd
import mglearn
In [2]:
from sklearn.svm import SVC
from sklearn.model_selection import train_test_split
from sklearn.datasets import load_iris
iris = load_iris()
X_train, X_test, y_train, y_test = train_test_split(iris.data, iris.target, random_state=0)
print('Training set의 크기: {} Test set의 크기: {}'.format(X_train.shape[0], X_test.shape[0]))
best_score = 0
# SVM 매개변수: gamma(커널의 폭), C(규제 관련)
# cf)
# C: 선형 모델에서 사용한 것과 비슷한 규제 매개변수, 각 포인트의 중요도(정확히는 dual_coef_ 값) 제한
# => ★ C 값이 작을수록 제한 강해짐 -> 모델 복잡도 ↓
# gamma: 하나의 Training sample이 미치는 영향의 범위 결정
# -> 가우시안 커널의 반경이 클수록 Training sample의 영향 범위도 커짐
# -> gamma는 가우시안 커널 폭의 역수
# => ★ gamma 값이 작을수록 데이터 포인터의 영향 범위 커짐 -> 모델 복잡도 ↓
for gamma in [0.001, 0.01, 0.1, 1, 10, 100]:
for C in [0.001, 0.01, 0.1, 1, 10, 100]:
# 매개변수의 각 조합에 대해 SVC 훈련
svm = SVC(gamma=gamma, C=C)
svm.fit(X_train, y_train)
# Test set로 SVC 평가
score = svm.score(X_test, y_test)
# 점수가 더 높으면 매개변수와 함께 기록
if score > best_score:
best_score = score
best_parameters = {'C': C, 'gamma': gamma}
print('최고 점수: {:.2f}'.format(best_score))
print('최적 매개변수:', best_parameters)
Training set의 크기: 112 Test set의 크기: 38
최고 점수: 0.97
최적 매개변수: {'C': 100, 'gamma': 0.001}
5.2.2 매개변수 과대적합과 검증 세트¶
- 매개변수 튜닝을 위한 그리드 서치와 모델 성능 평가를 위한 데이터셋은 각각 배타적이어야함
→ 데이터셋을 Training set(모델 훈련), Validation set(매개변수 선택), Test set(모델 평가) 세 개로 분할 - 최적 매개변수 선택 후 Training set와 Validation set를 합쳐서 모형 재적합
In [3]:
mglearn.plots.plot_threefold_split()
In [4]:
# 데이터를 훈련+검증 세트 그리고 테스트 세트로 분할
X_trainval, X_test, y_trainval, y_test = train_test_split(iris.data, iris.target, random_state=0)
# 훈련+검증 세트를 훈련 세트와 검증 세트로 분할
X_train, X_valid, y_train, y_valid = train_test_split(X_trainval, y_trainval, random_state=1)
print('훈련 세트의 크기: {} 검증 세트의 크기: {} 테스트 세트의 크기: {}\n'.format(X_train.shape[0], X_valid.shape[0], X_test.shape[0]))
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]:
# 매개변수의 각 조합에 대해 SVC 훈련
svm = SVC(gamma=gamma, C=C)
svm.fit(X_train, y_train)
# 검증 세트로 SVC 평가
score = svm.score(X_valid, y_valid)
# 점수가 더 높으면 매개변수와 함께 기록
if score > best_score:
best_score = score
best_parameters = {'C': C, 'gamma': gamma}
# 훈련 세트와 검증 세트를 합쳐 모델을 다시 만든 후
# 테스트 세트를 사용하여 평가
svm = SVC(**best_parameters)
svm.fit(X_trainval, y_trainval)
test_score = svm.score(X_test, y_test)
print('검증 세트에서 최고 점수: {:.2f}'.format(best_score))
print('최적 매개변수:', best_parameters)
print('최적 매개변수에서 테스트 세트 점수: {:.2f}'.format(test_score))
훈련 세트의 크기: 84 검증 세트의 크기: 28 테스트 세트의 크기: 38
검증 세트에서 최고 점수: 0.96
최적 매개변수: {'C': 10, 'gamma': 0.001}
최적 매개변수에서 테스트 세트 점수: 0.92
5.2.3 교차 검증을 위한 그리드 서치¶
In [5]:
from sklearn.model_selection import cross_val_score
for gamma in [0.001, 0.01, 0.1, 1, 10, 100]:
for C in [0.001, 0.01, 0.1, 1, 10, 100]:
# 매개변수의 각 조합에 대해 SVC 훈련
svm = SVC(gamma=gamma, C=C)
# 교차 검증 적용
scores = cross_val_score(svm, X_trainval, y_trainval, cv=5)
# 교차 검증 정확도의 평균 계산
score = np.mean(scores)
svm.fit(X_train, y_train)
# 점수가 더 높으면 매개변수와 함께 기록
if score > best_score:
best_score = score
best_parameters = {'C': C, 'gamma': gamma}
# 훈련 세트와 검증 세트를 합쳐 모델 다시 만들기
svm = SVC(**best_parameters)
svm.fit(X_trainval, y_trainval)
# 교차 검증을 사용한 그리드 서치 결과
# *** error
# mglearn.plots.plot_cross_val_selection()
Out[5]:
SVC(C=10, gamma=0.1)
교차 검증과 그리드 서치를 사용한 매개변수 선택과 모델 평가의 작업 흐름¶
In [6]:
mglearn.plots.plot_grid_search_overview()
교차 검증을 사용한 그리드 서치: GridSearchCV 사용¶
In [7]:
# 딕셔너리 형태로 검색 대상 매개변수 설정 -> GridSearchCV 함수의 매개변수로 전달
param_grid = {'C': [0.001, 0.01, 0.1, 1, 10, 100],
'gamma': [0.001, 0.01, 0.1, 1, 10, 100]}
print('매개변수 그리드:\n', param_grid)
from sklearn.model_selection import GridSearchCV
grid_search = GridSearchCV(SVC(), param_grid, cv=5, return_train_score=True)
X_train, X_test, y_train, y_test = train_test_split(iris.data, iris.target, random_state=0)
# fit 매서드: param_grid에 설정된 매개변수 조합에 대한 교차 검증 수행
# -> 최적의 매개변수를 찾을뿐만 아니라, 교차 검증 성능이 가장 좋은 매개변수로 전체 훈련 데이터셋에 대해 새로운 모델을 자동으로 만듦
# -> predict, score 매서드 제공
grid_search.fit(X_train, y_train)
print('\n테스트 세트 점수: {:.2f}'.format(grid_search.score(X_test, y_test)))
매개변수 그리드:
{'C': [0.001, 0.01, 0.1, 1, 10, 100], 'gamma': [0.001, 0.01, 0.1, 1, 10, 100]}
테스트 세트 점수: 0.97
In [8]:
print('최적 매개변수:', grid_search.best_params_)
print('최고 교차 검증 점수: {:.2f}'.format(grid_search.best_score_))
print('\n최고 성능 모델:\n', grid_search.best_estimator_)
최적 매개변수: {'C': 10, 'gamma': 0.1}
최고 교차 검증 점수: 0.97
최고 성능 모델:
SVC(C=10, gamma=0.1)
1) 교차 검증 결과 분석¶
In [9]:
pd.set_option('display.max_columns', None)
# cv_results_: 그리드 서치 결과와 관련된 상세 정보 저장(딕셔너리)
# DataFrame으로 변환
results = pd.DataFrame(grid_search.cv_results_)
# 처음 다섯 개 행 출력
display(np.transpose(results.head()))
| 0 | 1 | 2 | 3 | 4 | |
|---|---|---|---|---|---|
| mean_fit_time | 0.00141282 | 0.00160818 | 0.00119519 | 0.00140166 | 0.00139065 |
| std_fit_time | 0.000512594 | 0.000499204 | 0.00041299 | 0.000505818 | 0.00100914 |
| mean_score_time | 0.000797796 | 0.000795269 | 0.000210953 | 0.000805807 | 0.000997019 |
| std_score_time | 0.000398899 | 0.000745442 | 0.000421906 | 0.00040404 | 2.05463e-05 |
| param_C | 0.001 | 0.001 | 0.001 | 0.001 | 0.001 |
| param_gamma | 0.001 | 0.01 | 0.1 | 1 | 10 |
| params | {'C': 0.001, 'gamma': 0.001} | {'C': 0.001, 'gamma': 0.01} | {'C': 0.001, 'gamma': 0.1} | {'C': 0.001, 'gamma': 1} | {'C': 0.001, 'gamma': 10} |
| split0_test_score | 0.347826 | 0.347826 | 0.347826 | 0.347826 | 0.347826 |
| split1_test_score | 0.347826 | 0.347826 | 0.347826 | 0.347826 | 0.347826 |
| split2_test_score | 0.363636 | 0.363636 | 0.363636 | 0.363636 | 0.363636 |
| split3_test_score | 0.363636 | 0.363636 | 0.363636 | 0.363636 | 0.363636 |
| split4_test_score | 0.409091 | 0.409091 | 0.409091 | 0.409091 | 0.409091 |
| mean_test_score | 0.366403 | 0.366403 | 0.366403 | 0.366403 | 0.366403 |
| std_test_score | 0.0224845 | 0.0224845 | 0.0224845 | 0.0224845 | 0.0224845 |
| rank_test_score | 22 | 22 | 22 | 22 | 22 |
| split0_train_score | 0.370787 | 0.370787 | 0.370787 | 0.370787 | 0.370787 |
| split1_train_score | 0.370787 | 0.370787 | 0.370787 | 0.370787 | 0.370787 |
| split2_train_score | 0.366667 | 0.366667 | 0.366667 | 0.366667 | 0.366667 |
| split3_train_score | 0.366667 | 0.366667 | 0.366667 | 0.366667 | 0.366667 |
| split4_train_score | 0.355556 | 0.355556 | 0.355556 | 0.355556 | 0.355556 |
| mean_train_score | 0.366092 | 0.366092 | 0.366092 | 0.366092 | 0.366092 |
| std_train_score | 0.00558129 | 0.00558129 | 0.00558129 | 0.00558129 | 0.00558129 |
In [10]:
# C와 gamma 값에 따른 평균 CV 점수 히트맵
# 평균 CV 점수(mean_test_score)를 뽑아서 C와 gamma 축에 맞도록 배열 차원 바꾸기
scores = np.array(results.mean_test_score).reshape(6, 6)
# 교차 검증 평균 점수 히트맵 그래프
# 매개변수 탐색 순서가 먼저 C가 고정되고 gamma가 변하는 식이므로 C는 행(y축), gamma는 열(x축)
mglearn.tools.heatmap(scores, xlabel='gamma', xticklabels=param_grid['gamma'], ylabel='C', yticklabels=param_grid['C'], cmap='viridis')
# -> 각 매개변수의 최적값이 그래프 끝에 놓이지 않도록 매개변수의 범위가 충분히 넓어야함
Out[10]:
<matplotlib.collections.PolyCollection at 0x2677b256fd0>
In [11]:
# 적절하지 않은 매개변수 그리드의 히트맵 ★예제
fig, axes = plt.subplots(1, 3, figsize=(13, 5))
param_grid_linear = {'C': np.linspace(1, 2, 6),
'gamma': np.linspace(1, 2, 6)}
param_grid_one_log = {'C': np.linspace(1, 2, 6),
'gamma': np.logspace(-3, 2, 6)}
param_grid_range = {'C': np.logspace(-3, 2, 6),
'gamma': np.logspace(-7, -2, 6)}
for param_grid, ax in zip([param_grid_linear, param_grid_one_log, param_grid_range], axes):
grid_search = GridSearchCV(SVC(), param_grid, cv=5)
grid_search.fit(X_train, y_train)
scores = grid_search.cv_results_['mean_test_score'].reshape(6, 6)
# 교차 검증 평균 점수의 히트맵 그래프
scores_image = mglearn.tools.heatmap(scores, xlabel='gamma', xticklabels=param_grid['gamma'], ylabel='C', yticklabels=param_grid['C'], cmap='viridis', ax=ax)
plt.colorbar(scores_image, ax=axes.tolist())
Out[11]:
<matplotlib.colorbar.Colorbar at 0x2677b2e8d30>
2) 비대칭 매개변수 그리드 탐색¶
In [12]:
# ★예제 참조
param_grid = [{'kernel': ['rbf'],
'C': [0.001, 0.01, 0.1, 1, 10, 100],
'gamma': [0.001, 0.01, 0.1, 1, 10, 100]},
{'kernel': ['linear'],
'C': [0.001, 0.01, 0.1, 1, 10, 100]}]
print('그리드 목록:\n', param_grid)
grid_search = GridSearchCV(SVC(), param_grid, cv=5, return_train_score=True)
grid_search.fit(X_train, y_train)
print('\n최적 파라미터:', grid_search.best_params_)
print('최고 교차 검증 점수: {:.2f}'.format(grid_search.best_score_))
그리드 목록:
[{'kernel': ['rbf'], 'C': [0.001, 0.01, 0.1, 1, 10, 100], 'gamma': [0.001, 0.01, 0.1, 1, 10, 100]}, {'kernel': ['linear'], 'C': [0.001, 0.01, 0.1, 1, 10, 100]}]
최적 파라미터: {'C': 10, 'gamma': 0.1, 'kernel': 'rbf'}
최고 교차 검증 점수: 0.97
In [13]:
results = pd.DataFrame(grid_search.cv_results_)
# 좀 더 나은 출력을 위해 결과 전치
display(results.T)
| 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | |
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| mean_fit_time | 0.00148921 | 0.00117359 | 0.0011497 | 0.00141821 | 0.00126181 | 0.00239959 | 0.00182743 | 0.00200324 | 0.00266304 | 0.00223036 | 0.00235472 | 0.00270653 | 0.00161557 | 0.00208726 | 0.00194359 | 0.00160165 | 0.00166225 | 0.00218897 | 0.00140448 | 0.00167127 | 0.00117831 | 0.0011271 | 0.00222387 | 0.00277743 | 0.00140891 | 0.00105715 | 0.00118566 | 0.00139303 | 0.0021997 | 0.00260162 | 0.00141029 | 0.00131755 | 0.00123987 | 0.00142441 | 0.00196261 | 0.00260477 | 0.00166678 | 0.00112262 | 0.00138135 | 0.00100589 | 0.00138755 | 0.00110435 |
| std_fit_time | 0.000569588 | 0.000419796 | 0.000228145 | 0.000487523 | 0.000490598 | 0.000466468 | 0.000776167 | 0.000629872 | 0.000490514 | 0.000451535 | 0.000609394 | 0.000416988 | 0.000486496 | 0.000177425 | 0.000134469 | 0.00054093 | 0.000531921 | 0.000402169 | 0.000475143 | 0.000384119 | 0.000411173 | 0.000313365 | 0.000385328 | 0.000392072 | 0.000500609 | 5.08709e-05 | 0.00041279 | 0.000490872 | 0.000378162 | 0.000457361 | 0.000479048 | 0.000535077 | 0.000378346 | 0.000468595 | 2.62106e-05 | 0.000495368 | 0.000539456 | 0.000402878 | 0.000445278 | 9.06739e-05 | 0.000498932 | 0.000123704 |
| mean_score_time | 0.000404119 | 0.000402546 | 0.000384569 | 0 | 0.000714636 | 0.000842285 | 0.000982952 | 0.000823164 | 0.000554371 | 0.00118475 | 0.000982952 | 0.00113187 | 0.000850105 | 0.000540352 | 0.000878239 | 0.000926161 | 0.000574398 | 0.000817585 | 0.000844288 | 0.00082469 | 0.000777674 | 0.000899744 | 0.000611687 | 0.000994587 | 0.0007658 | 0.000569773 | 0.000606966 | 0.000650692 | 0.000202465 | 0.001302 | 0.000823021 | 0.000880909 | 0.00057354 | 0.00069561 | 0.00100636 | 0.00102115 | 0.000575447 | 0.000778151 | 0.000776625 | 0.000648117 | 0.000642538 | 0.000887918 |
| std_score_time | 0.000495131 | 0.000493043 | 0.00047159 | 0 | 0.000399951 | 0.000422316 | 5.34356e-05 | 0.000414759 | 0.000420039 | 0.000405407 | 4.05638e-05 | 0.000253887 | 0.000427323 | 0.000471194 | 0.000794846 | 0.000266136 | 0.000482372 | 0.000411007 | 0.000378943 | 0.00030666 | 0.000389889 | 0.000467108 | 0.000503934 | 1.70616e-05 | 0.000384627 | 0.000466419 | 0.000501311 | 0.000484734 | 0.00040493 | 0.000420023 | 0.000414364 | 0.000452546 | 0.000456098 | 0.000351564 | 1.82965e-05 | 4.64247e-05 | 0.000470985 | 0.000391025 | 0.000337259 | 0.000398421 | 0.000482437 | 0.000122998 |
| param_C | 0.001 | 0.001 | 0.001 | 0.001 | 0.001 | 0.001 | 0.01 | 0.01 | 0.01 | 0.01 | 0.01 | 0.01 | 0.1 | 0.1 | 0.1 | 0.1 | 0.1 | 0.1 | 1 | 1 | 1 | 1 | 1 | 1 | 10 | 10 | 10 | 10 | 10 | 10 | 100 | 100 | 100 | 100 | 100 | 100 | 0.001 | 0.01 | 0.1 | 1 | 10 | 100 |
| param_gamma | 0.001 | 0.01 | 0.1 | 1 | 10 | 100 | 0.001 | 0.01 | 0.1 | 1 | 10 | 100 | 0.001 | 0.01 | 0.1 | 1 | 10 | 100 | 0.001 | 0.01 | 0.1 | 1 | 10 | 100 | 0.001 | 0.01 | 0.1 | 1 | 10 | 100 | 0.001 | 0.01 | 0.1 | 1 | 10 | 100 | NaN | NaN | NaN | NaN | NaN | NaN |
| param_kernel | rbf | rbf | rbf | rbf | rbf | rbf | rbf | rbf | rbf | rbf | rbf | rbf | rbf | rbf | rbf | rbf | rbf | rbf | rbf | rbf | rbf | rbf | rbf | rbf | rbf | rbf | rbf | rbf | rbf | rbf | rbf | rbf | rbf | rbf | rbf | rbf | linear | linear | linear | linear | linear | linear |
| params | {'C': 0.001, 'gamma': 0.001, 'kernel': 'rbf'} | {'C': 0.001, 'gamma': 0.01, 'kernel': 'rbf'} | {'C': 0.001, 'gamma': 0.1, 'kernel': 'rbf'} | {'C': 0.001, 'gamma': 1, 'kernel': 'rbf'} | {'C': 0.001, 'gamma': 10, 'kernel': 'rbf'} | {'C': 0.001, 'gamma': 100, 'kernel': 'rbf'} | {'C': 0.01, 'gamma': 0.001, 'kernel': 'rbf'} | {'C': 0.01, 'gamma': 0.01, 'kernel': 'rbf'} | {'C': 0.01, 'gamma': 0.1, 'kernel': 'rbf'} | {'C': 0.01, 'gamma': 1, 'kernel': 'rbf'} | {'C': 0.01, 'gamma': 10, 'kernel': 'rbf'} | {'C': 0.01, 'gamma': 100, 'kernel': 'rbf'} | {'C': 0.1, 'gamma': 0.001, 'kernel': 'rbf'} | {'C': 0.1, 'gamma': 0.01, 'kernel': 'rbf'} | {'C': 0.1, 'gamma': 0.1, 'kernel': 'rbf'} | {'C': 0.1, 'gamma': 1, 'kernel': 'rbf'} | {'C': 0.1, 'gamma': 10, 'kernel': 'rbf'} | {'C': 0.1, 'gamma': 100, 'kernel': 'rbf'} | {'C': 1, 'gamma': 0.001, 'kernel': 'rbf'} | {'C': 1, 'gamma': 0.01, 'kernel': 'rbf'} | {'C': 1, 'gamma': 0.1, 'kernel': 'rbf'} | {'C': 1, 'gamma': 1, 'kernel': 'rbf'} | {'C': 1, 'gamma': 10, 'kernel': 'rbf'} | {'C': 1, 'gamma': 100, 'kernel': 'rbf'} | {'C': 10, 'gamma': 0.001, 'kernel': 'rbf'} | {'C': 10, 'gamma': 0.01, 'kernel': 'rbf'} | {'C': 10, 'gamma': 0.1, 'kernel': 'rbf'} | {'C': 10, 'gamma': 1, 'kernel': 'rbf'} | {'C': 10, 'gamma': 10, 'kernel': 'rbf'} | {'C': 10, 'gamma': 100, 'kernel': 'rbf'} | {'C': 100, 'gamma': 0.001, 'kernel': 'rbf'} | {'C': 100, 'gamma': 0.01, 'kernel': 'rbf'} | {'C': 100, 'gamma': 0.1, 'kernel': 'rbf'} | {'C': 100, 'gamma': 1, 'kernel': 'rbf'} | {'C': 100, 'gamma': 10, 'kernel': 'rbf'} | {'C': 100, 'gamma': 100, 'kernel': 'rbf'} | {'C': 0.001, 'kernel': 'linear'} | {'C': 0.01, 'kernel': 'linear'} | {'C': 0.1, 'kernel': 'linear'} | {'C': 1, 'kernel': 'linear'} | {'C': 10, 'kernel': 'linear'} | {'C': 100, 'kernel': 'linear'} |
| split0_test_score | 0.347826 | 0.347826 | 0.347826 | 0.347826 | 0.347826 | 0.347826 | 0.347826 | 0.347826 | 0.347826 | 0.347826 | 0.347826 | 0.347826 | 0.347826 | 0.695652 | 0.913043 | 1 | 0.347826 | 0.347826 | 0.695652 | 0.913043 | 1 | 0.956522 | 0.913043 | 0.391304 | 0.913043 | 1 | 1 | 0.956522 | 0.869565 | 0.521739 | 1 | 1 | 1 | 0.956522 | 0.869565 | 0.521739 | 0.347826 | 0.869565 | 1 | 1 | 1 | 0.956522 |
| split1_test_score | 0.347826 | 0.347826 | 0.347826 | 0.347826 | 0.347826 | 0.347826 | 0.347826 | 0.347826 | 0.347826 | 0.347826 | 0.347826 | 0.347826 | 0.347826 | 0.695652 | 0.913043 | 0.913043 | 0.347826 | 0.347826 | 0.695652 | 0.913043 | 0.956522 | 0.913043 | 0.956522 | 0.434783 | 0.913043 | 0.956522 | 0.956522 | 0.956522 | 0.913043 | 0.521739 | 0.956522 | 0.913043 | 0.956522 | 0.956522 | 0.913043 | 0.521739 | 0.347826 | 0.869565 | 0.913043 | 0.956522 | 1 | 0.956522 |
| split2_test_score | 0.363636 | 0.363636 | 0.363636 | 0.363636 | 0.363636 | 0.363636 | 0.363636 | 0.363636 | 0.363636 | 0.363636 | 0.363636 | 0.363636 | 0.363636 | 0.681818 | 0.909091 | 1 | 0.363636 | 0.363636 | 0.681818 | 1 | 1 | 1 | 1 | 0.545455 | 1 | 1 | 1 | 1 | 1 | 0.590909 | 1 | 1 | 1 | 1 | 1 | 0.590909 | 0.363636 | 0.772727 | 1 | 1 | 1 | 1 |
| split3_test_score | 0.363636 | 0.363636 | 0.363636 | 0.363636 | 0.363636 | 0.363636 | 0.363636 | 0.363636 | 0.363636 | 0.363636 | 0.363636 | 0.363636 | 0.363636 | 0.681818 | 0.863636 | 0.909091 | 0.363636 | 0.363636 | 0.681818 | 0.909091 | 0.909091 | 0.909091 | 0.818182 | 0.5 | 0.909091 | 0.909091 | 0.954545 | 0.863636 | 0.818182 | 0.590909 | 0.909091 | 0.954545 | 0.863636 | 0.863636 | 0.818182 | 0.590909 | 0.363636 | 0.772727 | 0.909091 | 0.954545 | 0.909091 | 0.909091 |
| split4_test_score | 0.409091 | 0.409091 | 0.409091 | 0.409091 | 0.409091 | 0.409091 | 0.409091 | 0.409091 | 0.409091 | 0.409091 | 0.409091 | 0.409091 | 0.409091 | 0.727273 | 0.909091 | 0.954545 | 0.409091 | 0.409091 | 0.727273 | 0.954545 | 0.954545 | 0.954545 | 0.954545 | 0.636364 | 0.954545 | 0.954545 | 0.954545 | 0.954545 | 0.954545 | 0.681818 | 0.954545 | 0.954545 | 0.954545 | 0.954545 | 0.954545 | 0.681818 | 0.409091 | 0.909091 | 0.954545 | 0.954545 | 0.954545 | 0.954545 |
| mean_test_score | 0.366403 | 0.366403 | 0.366403 | 0.366403 | 0.366403 | 0.366403 | 0.366403 | 0.366403 | 0.366403 | 0.366403 | 0.366403 | 0.366403 | 0.366403 | 0.696443 | 0.901581 | 0.955336 | 0.366403 | 0.366403 | 0.696443 | 0.937945 | 0.964032 | 0.94664 | 0.928458 | 0.501581 | 0.937945 | 0.964032 | 0.973123 | 0.946245 | 0.911067 | 0.581423 | 0.964032 | 0.964427 | 0.954941 | 0.946245 | 0.911067 | 0.581423 | 0.366403 | 0.838735 | 0.955336 | 0.973123 | 0.972727 | 0.955336 |
| std_test_score | 0.0224845 | 0.0224845 | 0.0224845 | 0.0224845 | 0.0224845 | 0.0224845 | 0.0224845 | 0.0224845 | 0.0224845 | 0.0224845 | 0.0224845 | 0.0224845 | 0.0224845 | 0.0166102 | 0.0190545 | 0.0397936 | 0.0224845 | 0.0224845 | 0.0166102 | 0.0352112 | 0.0339185 | 0.0333049 | 0.0616195 | 0.0856933 | 0.0352112 | 0.0339185 | 0.0219572 | 0.0447077 | 0.0634877 | 0.0589635 | 0.0339185 | 0.0327611 | 0.0497992 | 0.0447077 | 0.0634877 | 0.0589635 | 0.0224845 | 0.0557943 | 0.0397936 | 0.0219572 | 0.0363636 | 0.0287643 |
| rank_test_score | 27 | 27 | 27 | 27 | 27 | 27 | 27 | 27 | 27 | 27 | 27 | 27 | 27 | 22 | 20 | 8 | 27 | 27 | 22 | 15 | 5 | 12 | 17 | 26 | 15 | 5 | 1 | 13 | 18 | 24 | 5 | 4 | 11 | 13 | 18 | 24 | 27 | 21 | 8 | 1 | 3 | 8 |
| split0_train_score | 0.370787 | 0.370787 | 0.370787 | 0.370787 | 0.370787 | 0.370787 | 0.370787 | 0.370787 | 0.370787 | 0.370787 | 0.370787 | 0.370787 | 0.370787 | 0.696629 | 0.898876 | 0.94382 | 0.382022 | 0.370787 | 0.696629 | 0.94382 | 0.977528 | 0.977528 | 1 | 1 | 0.94382 | 0.977528 | 0.988764 | 0.988764 | 1 | 1 | 0.977528 | 0.988764 | 0.988764 | 1 | 1 | 1 | 0.370787 | 0.853933 | 0.966292 | 0.988764 | 0.988764 | 0.977528 |
| split1_train_score | 0.370787 | 0.370787 | 0.370787 | 0.370787 | 0.370787 | 0.370787 | 0.370787 | 0.370787 | 0.370787 | 0.370787 | 0.370787 | 0.370787 | 0.370787 | 0.696629 | 0.932584 | 0.977528 | 0.393258 | 0.370787 | 0.696629 | 0.932584 | 0.966292 | 1 | 1 | 1 | 0.932584 | 0.977528 | 0.988764 | 0.988764 | 1 | 1 | 0.977528 | 0.988764 | 0.988764 | 1 | 1 | 1 | 0.370787 | 0.910112 | 0.966292 | 0.977528 | 0.988764 | 0.988764 |
| split2_train_score | 0.366667 | 0.366667 | 0.366667 | 0.366667 | 0.366667 | 0.366667 | 0.366667 | 0.366667 | 0.366667 | 0.366667 | 0.366667 | 0.366667 | 0.366667 | 0.7 | 0.877778 | 0.944444 | 0.366667 | 0.366667 | 0.7 | 0.922222 | 0.966667 | 0.977778 | 1 | 1 | 0.922222 | 0.966667 | 0.977778 | 0.977778 | 1 | 1 | 0.966667 | 0.977778 | 0.977778 | 1 | 1 | 1 | 0.366667 | 0.844444 | 0.944444 | 0.977778 | 0.977778 | 0.988889 |
| split3_train_score | 0.366667 | 0.366667 | 0.366667 | 0.366667 | 0.366667 | 0.366667 | 0.366667 | 0.366667 | 0.366667 | 0.366667 | 0.366667 | 0.366667 | 0.366667 | 0.7 | 0.888889 | 0.966667 | 0.4 | 0.366667 | 0.7 | 0.944444 | 0.977778 | 1 | 1 | 1 | 0.933333 | 0.988889 | 0.988889 | 1 | 1 | 1 | 0.988889 | 0.988889 | 1 | 1 | 1 | 1 | 0.366667 | 0.766667 | 0.966667 | 0.988889 | 0.988889 | 1 |
| split4_train_score | 0.355556 | 0.355556 | 0.355556 | 0.355556 | 0.355556 | 0.355556 | 0.355556 | 0.355556 | 0.355556 | 0.355556 | 0.355556 | 0.355556 | 0.355556 | 0.688889 | 0.933333 | 0.955556 | 0.355556 | 0.355556 | 0.688889 | 0.933333 | 0.977778 | 0.977778 | 1 | 1 | 0.933333 | 0.977778 | 1 | 0.988889 | 1 | 1 | 0.977778 | 0.988889 | 1 | 1 | 1 | 1 | 0.355556 | 0.877778 | 0.966667 | 0.988889 | 1 | 1 |
| mean_train_score | 0.366092 | 0.366092 | 0.366092 | 0.366092 | 0.366092 | 0.366092 | 0.366092 | 0.366092 | 0.366092 | 0.366092 | 0.366092 | 0.366092 | 0.366092 | 0.696429 | 0.906292 | 0.957603 | 0.379501 | 0.366092 | 0.696429 | 0.935281 | 0.973208 | 0.986617 | 1 | 1 | 0.933059 | 0.977678 | 0.988839 | 0.988839 | 1 | 1 | 0.977678 | 0.986617 | 0.991061 | 1 | 1 | 1 | 0.366092 | 0.850587 | 0.962072 | 0.98437 | 0.988839 | 0.991036 |
| std_train_score | 0.00558129 | 0.00558129 | 0.00558129 | 0.00558129 | 0.00558129 | 0.00558129 | 0.00558129 | 0.00558129 | 0.00558129 | 0.00558129 | 0.00558129 | 0.00558129 | 0.00558129 | 0.00406048 | 0.0227747 | 0.0130113 | 0.0164556 | 0.00558129 | 0.00406048 | 0.00822781 | 0.00549631 | 0.0109278 | 0 | 0 | 0.00683543 | 0.00702835 | 0.00702755 | 0.00702755 | 0 | 0 | 0.00702835 | 0.00441983 | 0.00832835 | 0 | 0 | 0 | 0.00558129 | 0.0476952 | 0.00881557 | 0.00548484 | 0.00702755 | 0.00840169 |
3) 그리드 서치에 다양한 교차 검증 적용¶
- ex) GridSearchCV(~, cv=KFold(n_splits=5))
4) 중첩 교차 검증(nested CV)¶
- 지금까지 GridSearchCV를 사용한 방법은,
① 처음에 데이터셋을 Training set, Test set로 나누고,
② Training set를 대상으로 CV를 적용하여 그리드 서치(Training set, Validation set로 여러 번 분할)
→ Training set와 Test set로 한 번만 나누기 때문에 결과가 불안정하고 테스트 데이터의 분할에 크게 의존 - ①번 과정에도 CV 적용
In [14]:
param_grid = {'C': [0.001, 0.01, 0.1, 1, 10, 100],
'gamma': [0.001, 0.01, 0.1, 1, 10, 100]}
# cross_val_score: 각 Test set fold에 대한 CV 점수 반환
scores = cross_val_score(GridSearchCV(SVC(), param_grid, cv=5), iris.data, iris.target, cv=5)
print('교차 검증 점수:', scores)
print('교차 검증 평균 점수:', scores.mean())
교차 검증 점수: [0.96666667 1. 0.96666667 0.96666667 1. ] 교차 검증 평균 점수: 0.9800000000000001
In [15]:
# nested CV Process
def nested_cv(X, y, inner_cv, outer_cv, Classifier, parameter_grid):
outer_scores = []
# 1st for loop: Circuit 'outer_cv' split
# (split method: Return index corresponded Training set and Test set)
for training_samples, test_samples in outer_cv.split(X, y):
# Find optimal parameters
best_params = {}
best_score = -np.inf
# Circuit parameter grid
for parameters in parameter_grid:
# Record inner CV score
cv_scores = []
# 2nd for loop: Circuit 'inner_cv' split
for inner_train, inner_test in inner_cv.split(X[training_samples], y[training_samples]):
# Make classifier using Training data and given parameters
clf = Classifier(**parameters)
clf.fit(X[inner_train], y[inner_train])
# Evaluate using Validation set
score = clf.score(X[inner_test], y[inner_test])
cv_scores.append(score)
# Calculate mean of inner CV score
mean_score = np.mean(cv_scores)
if mean_score > best_score:
# Record mean_score with parameters, if mean_score is greater than best_score
best_score = mean_score
best_params = parameters
# Make classifier using outer total Training data
clf = Classifier(**best_params)
clf.fit(X[training_samples], y[training_samples])
# Evaluate using Test set
outer_scores.append(clf.score(X[test_samples], y[test_samples]))
return np.array(outer_scores)
# Apply iris dataset
from sklearn.model_selection import ParameterGrid, StratifiedKFold
scores = nested_cv(iris.data, iris.target, StratifiedKFold(5), StratifiedKFold(5), SVC, ParameterGrid(param_grid))
print('CV score:', scores)
CV score: [0.96666667 1. 0.96666667 0.96666667 1. ]
5) 교차 검증과 그리드 서치 병렬화¶
출처: 파이썬 라이브러리를 활용한 머신러닝
'Machine Learning' 카테고리의 다른 글
| [Python] 모형 평가 지표와 측정 실습 (0) | 2021.04.14 |
|---|---|
| 분류 성능 평가 지표 ─ Precision(정밀도), Recall(재현율), F1 Score, ROC Curve (0) | 2021.04.13 |
| [Python] 교차검증(Cross Validation, CV) 실습 (0) | 2021.04.09 |
| [Python] 4-4. 자전거 대여 횟수 예측 실습 (0) | 2021.04.07 |
| [Python] 4-3. 변수선택 실습 (0) | 2021.04.07 |
Comments