PL/Python

쉬어가기: GridSearchCV 하이퍼파라미터 튜닝 관련 질문

PIYA 2022. 12. 22.

Introduction

Random Forest를 실습하던 도중 생긴 의문점에 대해

직접 해결하려고 했는데 해결하지 못했다.

 

나중에 혹시 해답을 얻을까,

혹시 지나가던 누군가 알려줄까 해서 기록해놓는다.

 

코드

GridSearchCV를 적용하였는데도 불구하고, f1스코어가 더 낮아졌다.

물론 샘플 수가 작아서 그런것이겠지만,

GridSearchCV가 max_depth=4일 경우가 None일 경우보다 더 낫다고 생각하여 고른것으로 보이는데,

왜 최종 예측값은 더 낮아진 것인지 궁금하다.

from sklearn.datasets import load_breast_cancer
from sklearn.model_selection import train_test_split
from sklearn.ensemble import RandomForestClassifier
from sklearn.metrics import f1_score
from sklearn.model_selection import GridSearchCV
import random
import pandas as pd

# 위스콘신 유방암 데이터 로드, train_test_split으로 데이터 나누기
cancer = load_breast_cancer()
X_train, X_test, y_train, y_test = train_test_split(cancer.data, cancer.target, test_size=0.2)

# 대조군과 변수를 통일시키기 위해 같은 난수 이용
rs = random.randrange(1,50)

# 기본설정 랜덤포레스트 돌려보기. 디폴트 n_estimators=100
rf = RandomForestClassifier(n_jobs=-1, random_state=rs) # 모든 코어 사용
rf.fit(X_train, y_train)
pred = rf.predict(X_test)
f1 = f1_score(y_test, pred)
print('랜덤 포레스트 f1스코어: {0:.4f}'.format(f1))
print('\trf max_depth:', rf.get_params()['max_depth'])
print('\trf min_samples_split:', rf.get_params()['min_samples_split'])
print('\trf min_samples_leaf:', rf.get_params()['min_samples_leaf'])
print('\trf random_state:', rf.get_params()['random_state'], '\n')

# 그리드서치 적용해보기
# 비교를 위해 디폴트값인 None, 2, 1을 모두 포함했다.
params = {
    'max_depth': [None, 4,9,16],
    'min_samples_split':[2,6,12],
    'min_samples_leaf':[1,4,8]
}

# 같은 random_state로 RF 랜덤포레스트 재생성
rf = RandomForestClassifier(n_jobs=-1, random_state=rs)
grid = GridSearchCV(rf, param_grid = params, n_jobs=-1, scoring='f1')
grid.fit(X_train, y_train)

# refit된 rf에 테스트데이터를 돌려보기
pred = grid.best_estimator_.predict(X_test)
f1 = f1_score(y_test, pred)

print('GridSearchCV 후 refit된 RF f1스코어: {0:.4f}'.format(f1))
print('\tgrid max_depth:', grid.best_params_['max_depth'])
print('\tgrid min_samples_split:', grid.best_params_['min_samples_split'])
print('\tgrid min_samples_leaf:', grid.best_params_['min_samples_leaf'])
print('\trf random_state:', rf.get_params()['random_state'])

 

 

 

 

Solution

딱 하루만에 답을 찾았다.

위의 코드를 읽고 무엇이 문제였는지 알았는가?

 

Random Forest Classifier는 학습 데이터셋에 fit을 하였고,

학습 데이터셋을 기준으로 최고의 f1스코어를 내는 파라미터를 선택했을 뿐이다.

즉 학습 데이터셋 기준 f1스코어는 max_depth=4일 때가 max_depth=None일 때보다 더 높은것이다!

 

 

 

Conclusion

도저히 이해가 안가서 너무 찝찝했는데,

다행히 해결되었다.

다음날 다시 천천히 생각해보니 내가 놓치고 있던 부분이 보였다.

 

즉 결론을 정리하자면,

GridSearchCV는 트레이닝데이터셋을 기준으로 최적의 하이퍼파라미터를 튜닝한다!

 

댓글