• 데이터를 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")

 

3.1 heatmap

 

+ Recent posts