모델을 적용할 때 줘야할 옵션들이 있다. 일종의 옵션들을 하이퍼파라미터라고 할 수 있는데, 모델의 성능을 확보하기 위해 조절하는 설정 값이다.
그런데 처음에는 어떤 값을 줘야 좋은 성능이 나오는지 알 수 없다.
단순히 여러번 다양한 값을 주며 확인할 수 도 있겠지만, scikit-learn에서는 좋은 도구들을 제공한다.
모델을 정해지고 하이퍼파라미터를 수정할 때 사용할수도 있고, 모델을 여러개 적용할 때도 사용할 수 있다.
GridSearchCV는 cross-validation을 기반으로 최적의 값을 찾아준다. 그래서 데이터를 train, validation용으로 자동 분할된 다음에 값을 변경해나갈 파라미터를 지정된 시도해보고 싶은 값들로 바꿔가며 모델 성능을 확인한다.
GridSearchCV의 주 파라미터를 알아보자.
estimator
classifier, regressor, pipeline 등 모델 들어가는 곳 param_grid
{'파라미터 명':[적용할 값들]} scoring
모델 성능 측정 방법, default = accuracy cv
cross-validation 기반이기 때문에 교차 검증을 위한 분할 fold 수 지정 refit
최적의 하이퍼파라미터를 찾은 뒤 해당 estimator로 재학습, default = True n_jobs
값을 높여주면 CPU의 코어를 병렬로 활용, 속도 빨라짐. default = 1먼저 한 모델의 파라미터를 수정하는 경우를 예로 들어보자.
DecisionTreeClassifier()의 max_depth에 2,4,7,10을 적용해보도록 하자.
from sklearn.model_selection import GridSearchCV
from sklearn.tree import DecisionTreeClassifier
params = {'max_depth':[2,4,7,10]}
dtc = DecisionTreeClassifier(max_depth=2, random_state=13)
gridsearch = GridSearchCV(estimator=dtc, param_grid=params, cv=5)
gridsearch.fit(X, y)
이후에 최적의 성능을 가진 모델은 어떻게 찾을까?
# 최고 정확도
gridsearch.best_score_
# 최적 파라미터
gridsearch.best_params_
# GridSearchCV 과정 결과 확인
gridsearch.cv_results_
# 나눈 테스트 데이터에 대한 최적의 파라미터로 학습된 모델 테스트 진행
best = gridsearch.best_estimator_
pred = best.predict(X_test)
accuracy_score(y_test, pred)
pipeline 적용한 모델에도 GridSearchCV 적용이 가능하다.
먼저, pipeline을 간단하게 구현해보자.
from sklearn.pipeline import Pipeline
from sklearn.tree import DecisionTreeClassifier
from sklearn.preprocessing import StandardScaler
# scaler 적용 후 DecisionTreeClassifier 모델 정의
estimators = [('scaler', StandardScaler()),
('clf', DecisionTreeClassifier(random_state=13))]
pipe = Pipeline(estimators)
pipeline의 특정 요소 파라미터에 접근하는 방법은 지정이름__파라미터명
이니까 접근해서 위에처럼 시도할 파라미터 값들을 지정해주면 된다.
param_grid = [{'clf__max_depth':[2,4,7,10]}]
gridsearch =
GridSearchCV(estimator=pipe, param_grid=param_grid, cv=5)
gridsearch.fit(X, y)
그리고서 똑같이 최적의 파라미터, estimator를 확인하고 모델 테스트를 진행할 수 있다.
참고로, 위에서 gridsearch.cv_results_
로 모델 성능 결과를 확인할 수 있다고 했는데, 이를 DataFrame으로 정리해두면 유용하다.
import pandas as pd
score_df = pd.DataFrame(gridsearch.cv_results_)
score_df[['params', 'rank_test_score', 'mean_test_score', 'std_test_score']]
위처럼 하면 각 파라미터 시도별 테스트 score를 확인할 수 있다.
그러면,
하나의 모델만 적용하지 않고 scaler 같은 전처리 후에 몇가지 모델을 적용해보고 각 모델들의 하이퍼파라미터도 몇가지 시도해보고 싶다면 어떻게 해야할까? 🧐
💡 역시나 pipeline과 GridSearchCV를 활용해 해결할 수 있다.
pipe = Pipeline([('clf', RandomForestClassifier())])
search_space = [{'clf': [DecisionTreeClassifier()],
'clf__max_depth': [3, 5, 10]},
{'clf': [RandomForestClassifier()],
'clf__n_estimators': [10, 100, 1000],
'clf__max_depth': [3, 5, 10]}]
이때 처음에 pipe에 지정한 clf
의 모델은 사실상 무의미한 변수 초기화라고 생각해도 된다. 뒤에 파이프라인 파라미터 딕셔너리에 들어간 모델이 실제 적용하고 싶은 모델이 된다.
각 모델의 하이퍼파라미터도 시도하고 싶은 값들로 지정해준다.
처음에 코드를 잘못해석해 뒤의 파라미터 딕셔너리의 모델의 최적을 찾는 것을 pipe에 지정된 모델로 평가한다고 착각했는데, 아니였다!
from sklearn.model_selection import GridSearchCV
clf = GridSearchCV(pipe, search_space, cv=5, verbose=0)
best_model = clf.fit(X_train, y_train)
best_model.best_estimator_
참고로 verbose는 각 iteration 시 메세지 출력 여부인데, 0(default)이면 출력하지 않는다.
이렇게 GridSearchCV가 끝나고 나면 두가지 모델과 각 하이퍼파라미터 중 최적의 모형을 도출할 수 있게 된다.
Pipeline(steps=[('clf', DecisionTreeClassifier(max_depth=3, random_state=13))])