머신러닝/Optuna 활용 Hyperparameter 튜닝

Optuna를 활용한 하이퍼파라미터 튜닝(오류 수정)

Stevelee_HMC 2022. 8. 25. 08:07

하이퍼파라미터를 튜닝하는 방식은 대표적으로 gridsearch와 같은 격자 방식의 파라미터 조합으로 튜닝하는 방식이 있으며 연속성 있는 파라미터를 선정하는 Optuna와 같은 방식이 있다.

비교적 간편하고 직관적인 gridsearchCV보다 까다롭지만 결과는 통상 더 성능이 상대적으로 뛰어난 Optuna를 활용해서 튜닝하는것을 설명해보고자 한다.

 

우선 Optuna 설치가 되지 않았다면 , 

 

pip install optuna

를 통해서 설치를 진행한다.

 

설치가 끝난 후 

 

optuna 패키지를 import 합니다.

import optuna 
from optuna.samplers import TPESampler

 

objective func을 만들어야하는데 이때 trial.suggest_int (정수형 파라미터) , trial.sugget_float(실수형 파라미터)등으로 구분해서

하이퍼파라미터 구간을 세팅하는 param 딕셔너리를 정의합니다.

 

def objective(trial):
  param = {
      "random_state":42,
      'learning_rate' : trial.suggest_float('learning_rate', 0.01, 0.3), ## 0.01~0.3 사이 최적값 찾아준다는 의미
      "max_depth":trial.suggest_int("max_depth", 4, 16), ## 4~16 사이 최적값 찾아준다는 의미
      'random_strength' :trial.suggest_int('random_strength', 0, 100),
      "iterations" : trial.suggest_int('iterations' , 1000, 10000)
  }
  ### 위의 param은 아래의 모델을 어떤것을 선택할지에 달라 달라짐 , 모델에 맞는 파라미터와 범위 설정 

  X_train, X_valid, y_train, y_valid = train_test_split(X,y,test_size=0.2)
  
  cat = CatBoostRegressor(**param) ### 위의 param을 통으로 넣어서 최적을 찾는 모델을 선언
  cat.fit(X_train, y_train,
          eval_set=[(X_train, y_train), (X_valid,y_valid)],
          early_stopping_rounds=35)  ### ealry_stopping_rounds는 큰 변동폭이 없는 결과가 35개 이상 나오면 모든 회차를 돌기전에 종료 
  cat_pred = cat.predict(X_valid)
 
  score = np.sqrt(np.mean(np.square(y_valid - cat_pred)))

  return score

sampler를 통해 최적의 parameter를 찾는다.

sampler = TPESampler(seed=42) ### random_state값과 동일 
study = optuna.create_study(
    study_name = 'cat_opt', ### 이름은 편한대로 설정 
    direction = 'minimize', ### 지금은 회귀분석 - 에러값이니 최소값을 기준으로 설정
    sampler = sampler,
)
study.optimize(objective, n_trials=10) ### 몇번 할건지 설정 
print("Best Score:",study.best_value)
print("Best trial",study.best_trial.params)
[I 2021-05-24 14:43:51,592] A new study created in memory with name: cat_parameter_opt
0:	learn: 1.0829973	test: 1.0829973	test1: 1.0828206	best: 1.0828206 (0)	total: 12.8ms	remaining: 1m 37s
100:	learn: 0.8836407	test: 0.8836407	test1: 0.8787194	best: 0.8787194 (100)	total: 898ms	remaining: 1m 6s
200:	learn: 0.8834658	test: 0.8834658	test1: 0.8783854	best: 0.8783854 (200)	total: 1.76s	remaining: 1m 4s
300:	learn: 0.8834656	test: 0.8834656	test1: 0.8783811	best: 0.8783811 (300)	total: 2.62s	remaining: 1m 3s
400:	learn: 0.8834656	test: 0.8834656	test1: 0.8783810	best: 0.8783810 (400)	total: 3.49s	remaining: 1m 2s
500:	learn: 0.8834656	test: 0.8834656	test1: 0.8783810	best: 0.8783810 (500)	total: 4.34s	remaining: 1m 1s
600:	learn: 0.8834656	test: 0.8834656	test1: 0.8783810	best: 0.8783810 (599)	total: 5.21s	remaining: 1m
700:	learn: 0.8834656	test: 0.8834656	test1: 0.8783810	best: 0.8783810 (694)	total: 6.07s	remaining: 59.6s
[I 2021-05-24 14:43:58,511] Trial 0 finished with value: 0.8783809642307818 and parameters: {'learning_rate': 0.03574712922600244, 'bagging_temperature': 63.512210106407046, 'n_estimators': 7588, 'max_depth': 11, 'random_strength': 15, 'colsample_bylevel': 0.49359671220172163, 'l2_leaf_reg': 1.7519275289243016e-06, 'min_child_samples': 88, 'max_bin': 380, 'od_type': 'IncToDec'}. Best is trial 0 with value: 0.8783809642307818.
 

위와 같이 Trial을 계속해서 진행하다가 최종적으로 

아래와 같이 Best trial 결론을 도출하는데  이때의 파라미터를 활용해서 모델을 재학습 시켜서 결과를 도출해내면 된다.

(아래 값은 예시임)

Best Score: 0.6647759577222054
Best trial {'learning_rate': 0.01443340240633889, 'iterations': 6728, 'max_depth': 8, 'random_strength': 51}