[머신러닝] Hyper-parameter tunning

홍랑·2021년 12월 13일
0

MachineLearning

목록 보기
4/4
with python 3.8.12 & scikit-learn 1.0.1

모델을 적용할 때 줘야할 옵션들이 있다. 일종의 옵션들을 하이퍼파라미터라고 할 수 있는데, 모델의 성능을 확보하기 위해 조절하는 설정 값이다.
그런데 처음에는 어떤 값을 줘야 좋은 성능이 나오는지 알 수 없다.
단순히 여러번 다양한 값을 주며 확인할 수 도 있겠지만, scikit-learn에서는 좋은 도구들을 제공한다.

📚 GridSearchCV

모델을 정해지고 하이퍼파라미터를 수정할 때 사용할수도 있고, 모델을 여러개 적용할 때도 사용할 수 있다.
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 적용한 모델에도 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를 활용해 해결할 수 있다.

  1. pipeline에 DecisionClassifier, RandomForestClassifier 적용
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에 지정된 모델로 평가한다고 착각했는데, 아니였다!

  1. GridSearchCV 통해 최적의 모델 도출
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))])



[참고]
https://tensorflow.blog/%ED%95%B8%EC%A6%88%EC%98%A8-%EB%A8%B8%EC%8B%A0%EB%9F%AC%EB%8B%9D-1%EC%9E%A5-2%EC%9E%A5/2-7-%EB%AA%A8%EB%8D%B8-%EC%84%B8%EB%B6%80-%ED%8A%9C%EB%8B%9D/
profile
호랑이 기운이 솟아나요🐯

0개의 댓글