사이킷런 그리드서치를 통한 파라미터 튜닝, 중첩 교차 검증으로 모델 평가
April 5, 2022, 10:53 p.m.
머신러닝에서는 모델 자체의 파라미터(하이퍼파라미터)들이 있어서 이것을 데이터에 적합한 값으로 정해주어야 합니다. 어떤 파라미터가 적합할지 알아내는 방법은 여러가지가 있습니다. 검증 곡선을 분석해서 파라미터를 정할 수도 있을 것입니다.
그렇지만 가장 간단하지만 무식한 방법으로 모든 값을 넣어서 성능을 평가해 그 중에서 가장 성능이 좋았던 모델을 쓰면 되는 방법도 있을 것입니다. 이것을 파라미터들의 조합으로 이루어진 격자위를 움직이며 성능을 평가한다는 뜻의 그리드 서치라고 합니다.
이번 포스트에서는 사이킷런에 구현되어있는 그리드서치를 통해서 모델의 하이퍼 파라미터를 튜닝하는 방법을 알아보고 응용해서 중첩 교차 검증으로 모델 자체의 성능을 비교하는 법도 알아보겠습니다.
1. 그리드서치
먼저 학습할 데이터를 가져오고 파이프라인을 이용해 모델을 생성하겠습니다. 모델은 표준화, 주성분 분석(PCA), 커널 svm(kernel support vector machine, SVC)을 연결하였습니다.
import pandas as pd
df = pd.read_csv('/content/drive/MyDrive/Kaggle/hand_gesture_data/train.csv')
X, y = df.iloc[:, :-1].values, df.iloc[:, -1].values
from sklearn.pipeline import make_pipeline
from sklearn.preprocessing import StandardScaler
from sklearn.decomposition import KernelPCA
from sklearn.svm import SVC
model = make_pipeline(StandardScaler(), KernelPCA(), SVC())
그 다음에는 그리드서치로 조사할 파라미터들의 범위를 지정해 주어야합니다. 이때 각 파라미터의 이름은 아래의 규칙으로 정해집니다.
모델이름(소문자)__파라미터이름
예를 들어 KernelPCA의 n_components면 'kernelpca__n_components가 되겠지요!
저는 이번 그리드서치로 KernelPCA의 n_components를 5 혹은 10, SVC의 C와 gamma값을 0.001 부터 1000까지 지수적스케일로 증가시키면서 조사하고 또한 SVC의 kernel을 'linear'와 'rbf'로 설정하여 조사할 것입니다.
이렇게 되면 총 즉 432가지의 파라미터 조합이 생기게 됩니다. 그리드서치는 자동으로 이 모든 조합을 사용해 모델을 학습, 평가합니다.
리스트와 딕셔너리로 파라미터 조합을 만들어 보겠습니다.
c_range = [0.0001, 0.001, 0.01, 0.1, 1, 10, 100, 1000]
param_grid = [{'kernelpca__n_components':[5,10], 'svc__C': c_range,'svc__kernel':['linear']}, {'kernelpca__n_components':[5,10], 'svc__C': c_range,'svc__gamma': c_range, 'svc__kernel':['rbf']}]
그리드서치는 모델을 학습, 평가할때 K-fold 방식을 사용합니다. K-fold 방식에 대해서는 저의 K-fold포스팅 을 참고해주세요.
여기서는 k=5, 즉 5개의 폴드로 모델의 성능을 평가하겠습니다.
from sklearn.model_selection import GridSearchCV
gs = GridSearchCV(estimator=model, param_grid=param_grid, scoring='accuracy', cv=5)
gs = gs.fit(X_train, y_train)
fit()으로 그리드서치를 진행했습니다. 파라미터의 조합이 많고 모델이 복잡하고 학습 데이터의 양이 많다면 꽤나 오랜 시간이 걸릴 것입니다.
평가가 완료되었다면 gs의 파라미터로 최고 성능 점수와 이때의 파라미터 조합, 그리고 이 파라미터를 적용한 모델을 얻어낼 수 있습니다.
gs.best_score_
0.6395302151929607
gs.best_params_
{'kernelpca__n_components': 10,
'svc__C': 100,
'svc__gamma': 0.01,
'svc__kernel': 'rbf'}
best_model = gs.best_estimator_
2. 중첩 교차 검증
그리드 서치와 교차 검증을 이용하면 모델 자체의 가치, 즉 그 모델을 얼마나 잘 만들었는지에 대한 평가도 할 수 있습니다. 즉 어떤 모델이 처음 본 데이터에서 파라미터 튜닝을 했을 때 기대할 수 있는 성능의 추정 값을 알 수 있는 것이죠. 이것을 중첩 교차 검증이라고 합니다.
먼저 K-fold 방식을 이용해서 테스트 폴드와 훈련 폴드로 나누고 훈련 폴드를 다시 K-fold를 이용해 훈련 폴드와 검증 폴드로 나눕니다. 훈련 폴드와 검증 폴드로 그리드서치를 통해 파라미터 튜닝을 진행하고 이를 다시 처음에 나누었던 테스트 폴드로 모델의 성능을 측정합니다.
사이킷런으로 중첩 교차 검증을 통해 SVC와 로지스틱 회귀의 모델 비교를 구현해 보겠습니다.
from sklearn.pipeline import make_pipeline
from sklearn.preprocessing import StandardScaler
from sklearn.decomposition import KernelPCA
from sklearn.svm import SVC
from sklearn.linear_model import LogisticRegression
import numpy as np
c_range = [0.0001, 0.001, 0.01, 0.1, 1, 10, 100, 1000]
param_grid_svc = [{'kernelpca__n_components':[5,10], 'svc__C': c_range,'svc__kernel':['linear']}, {'kernelpca__n_components':[5,10], 'svc__C': c_range,'svc__gamma': c_range, 'svc__kernel':['rbf']}]
param_grid_lr = [{'kernelpca__n_components':[5,10], 'logisticregression__C': c_range}] //그리드 서치용 파라미터 정의
from sklearn.model_selection import GridSearchCV, cross_val_score
svc = make_pipeline(StandardScaler(), KernelPCA(), SVC())
lr = make_pipeline(StandardScaler(), KernelPCA(), LogisticRegression())
gs_svc = GridSearchCV(estimator=svc, param_grid=param_grid_svc, scoring='accuracy', cv=2) //2겹 교차 검증으로 그리드 서치
gs_lr = GridSearchCV(estimator=lr, param_grid=param_grid_lr, scoring='accuracy', cv=2)
scores_svc = cross_val_score(gs_svc, X_train, y_train, scoring='accuracy', cv=5) // 5겹 교차 검증으로 그리드 서치 된 모델 성능 평가
scores_lr = cross_val_score(gs_lr, X_train, y_train, scoring='accuracy', cv=5)
print(np.mean(scores_svc))
print(np.mean(scores_lr))
0.6370874842873493
0.25521097165156376
내부에 2겹, 외부에 5겹으로 중첩 교차 검증을 진행해 보았습니다. svc모델이 기댓값이 훨씬 큰 모습을 볼 수 있네요. 데이터가 선형적으로 구분이 될 수 없는 복잡한 데이터라서 그런것 같습니다. 이렇게 중첩된 K-fold, 즉 중첩 교차 검증을 통해서 해당 모델이 파라미터 튜닝을 마쳤을 때의 성능 기댓값을 알아낼 수 있는 것입니다. 즉, 파라미터에 상관 없이 모델 자체를 비교해 볼 수 있는 것이죠.
이상으로 모델의 하이퍼파라미터를 튜닝하는 사이킷런의 그리드서치, 그리고 중첩교차검증에 대해서 알아보았습니다.
사이킷런 scikit-learn GridSearch