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는 트레이닝데이터셋을 기준으로 최적의 하이퍼파라미터를 튜닝한다!
'PL > Python' 카테고리의 다른 글
Ensemble Learning 4: 그래디언트 부스트 GBM (0) | 2022.12.22 |
---|---|
Ensemble Learning 3: 부스팅 기초, Adaboost (0) | 2022.12.22 |
Ensemble learning 2: 배깅 Bagging, 랜덤 포레스트 (0) | 2022.12.16 |
[코드 스터디] UCI-HAR 데이터셋3: 결정트리 적용 (0) | 2022.12.15 |
Decision Tree Classifier: 하이퍼파라미터 정리 (0) | 2022.12.15 |
댓글