하이퍼파라미터 최적화의 중요성

 - 하이퍼파라미터를 어떻게 선택하느냐에 따라 overfit, underfit 모델이 될 수 있다. 따라서 최적화된 파라미터를 찾기 위해 값을 조정하면서 모델을 수행 및 검증해야 한다. 이 과정을 손쉽게 도와주는 프레임워크가 'optuna'이다.

Optuna

 - 하이퍼파라미터 튜닝에 쓰고 있는 최신 Automl 기법

 - 빠르게 튜닝 가능

 - 하이퍼파라미터 튜닝 방식을 지정 가능 -> lightgbm 제공

- 다른 라이브러리들에 비해 직관적인 장점이 있음

 

from sklearn.model_selection import train_test_split
from sklearn.experimental import enable_hist_gradient_boosting
from sklearn.ensemble import AdaBoostRegressor,  HistGradientBoostingRegressor, StackingRegressor, RandomForestRegressor
from sklearn.metrics import mean_squared_error
from sklearn.model_selection import KFold
from sklearn.neural_network import MLPRegressor
from sklearn.linear_model import SGDRegressor

import xgboost as xgb

from lightgbm import LGBMRegressor
from xgboost import XGBRegressor
from catboost import CatBoostRegressor

import optuna 
from optuna import Trial, visualization
from optuna.samplers import TPESampler

# optuna.logging.set_verbosity(optuna.logging.WARNING)

def train(model):
    X_train, X_test, y_train, y_test = train_test_split(X, y.flatten(), test_size=0.1, random_state=156)
    y_train = y_train.reshape(-1, 1)
    y_test  = y_test.reshape(-1, 1)
        
    model = model.fit(X_train, y_train, early_stopping_rounds=100, verbose=False, eval_set=[(X_test, y_test)])
    score = mean_squared_error(model.predict(X_train), y_train, squared=False)
    print(score)
    return model
def objectiveXGB(trial: Trial, X, y, test):
    param = {
        "n_estimators" : trial.suggest_int('n_estimators', 500, 4000),
        'max_depth':trial.suggest_int('max_depth', 8, 16),
        'min_child_weight':trial.suggest_int('min_child_weight', 1, 300),
        'gamma':trial.suggest_int('gamma', 1, 3),
        'learning_rate': 0.01,
        'colsample_bytree':trial.suggest_discrete_uniform('colsample_bytree',0.5, 1, 0.1),
        'nthread' : -1,
        'tree_method': 'gpu_hist',
        'predictor': 'gpu_predictor',
        'lambda': trial.suggest_loguniform('lambda', 1e-3, 10.0),
        'alpha': trial.suggest_loguniform('alpha', 1e-3, 10.0),
        'subsample': trial.suggest_categorical('subsample', [0.6,0.7,0.8,1.0] ),
        'random_state': 42
    }
    X_train, X_test, y_train, y_test = train_test_split(X, y.flatten(), test_size=0.1)
    
    y_train = y_train.reshape(-1, 1)
    y_test  = y_test.reshape(-1, 1)

    model = xgb.XGBRegressor(**param)
    xgb_model = model.fit(X_train, y_train, verbose=False, eval_set=[(X_test, y_test)])
    score = mean_squared_error(xgb_model.predict(X_test), y_test, squared=False)

    return score
study = optuna.create_study(direction='minimize',sampler=TPESampler())
study.optimize(lambda trial : objectiveXGB(trial, X,  y, X_test), n_trials=50)
print('Best trial: score {},\nparams {}'.format(study.best_trial.value,study.best_trial.params))

best_param = study.best_trial.params
xgbReg = train(xgb.XGBRegressor(**best_param, tree_method='gpu_hist', random_state=42, predictor='gpu_predictor', learning_rate=0.01, nthread=-1))

#params =  {'n_estimators': 3520, 'max_depth': 11, 'min_child_weight': 231, 'gamma': 2, 'colsample_bytree': 0.7, 'lambda': 0.014950936465569798, 'alpha': 0.28520156840812494, 'subsample': 0.6}
#xgbReg = train(xgb.XGBRegressor(**params, tree_method='gpu_hist', random_state=42, predictor='gpu_predictor', learning_rate=0.01, nthread=-1))

# 0.6744648190960726

하이퍼파라미터 최적화 진행 과정

- 최적화 기능 이외에도 다양한 시각화 기법을 제공한다. 그 중 2가지를 가장 잘 쓸 것 같아 메모한다!

 

1. 하이퍼파라미터별 중요도를 확인할 수 있는 그래프

optuna.visualization.plot_optimization_history(study)

2. 매 trial 마다 loss가 어떻게 감소하였는지 확인할 수 있는 함수

optuna.visualization.plot_param_importances(study)

- 코드 참고: https://www.kaggle.com/code/ssooni/xgboost-lgbm-optuna/notebook

+ Recent posts