지난 글에서는 XGBoost를 이용한 산탄데르 고객 만족 예측에 대해 정리하였다. 이번 글에서는 LightGBM을 이용한다.
아래와 같이 동일한 데이터 로드 및 전처리 과정을 수행한다.
## 1) 검색 공간 설정
from hyperopt import hp
## LightGBM이 XBGoost에 비해 깊이가 깊음
lgbm_search_space = {
'num_leaves':hp.quniform('num_leaves', 32, 64, 1),
'max_depth':hp.quniform('max_depth', 100, 169, 1), ## 정수형 하이퍼 파라미터 => quniform 사용
'min_child_weight':hp.quniform('min_child_weight', 60, 100, 1), ## 정수형 하이퍼 파라미터 => quniform 사용
'learning_rate':hp.uniform('learning_rate', 0.01, 0.2),
'subsample':hp.uniform('subsample', 0.7, 1),
}
## 2) 목적 함수 설정
from sklearn.model_selection import KFold
from sklearn.metrics import roc_auc_score
from lightgbm import LGBMClassifier
from sklearn.metrics import roc_auc_score
def objective_func(search_space):
lgbm_clf = LGBMClassifier(
n_estimators=100,
max_depth=int(search_space['max_depth']), ## int형으로 형변환 필요
min_child_weight=int(search_space['min_child_weight']), ## int형으로 형변환 필요
learning_rate=search_space['learning_rate'],
subsample=search_space['subsample'],
num_leaves=int(search_space['num_leaves']),
#eval_metric='logloss' => 불균형 데이터셋이므로 성능 평가 지표를 roc-auc로 설정
)
## XGBoost와 LightGBM에서는 cross_val_score()를 적용하면 early stopping 지원 불가, KFold 방식으로 직접 구현해야 함
## 3개의 k-fold 방식으로 평가된 roc-auc 지표를 담는 list
roc_auc_list = []
## 3개의 k-fold 방식 적용
kf = KFold(n_splits=3)
for tr_index, val_index in kf.split(X_train):
X_tr, y_tr = X_train.iloc[tr_index], y_train.iloc[tr_index]
X_val, y_val = X_train.iloc[val_index], y_train.iloc[val_index]
lgbm_clf.fit(
X_tr, y_tr,
early_stopping_rounds=30,
eval_metric='auc',
eval_set=[(X_tr, y_tr), (X_val, y_val)]
)
score = roc_auc_score(
y_val,
lgbm_clf.predict_proba(X_val)[:, 1]
)
roc_auc_list.append(score)
return (-1) * np.mean(roc_auc_list)
## 3) fmin()을 사용하여 최적 하이퍼 파라미터 찾기
from hyperopt import fmin, tpe, Trials
trials = Trials()
best = fmin(
fn=objective_func,
space=lgbm_search_space,
algo=tpe.suggest,
max_evals=30, ## 30번 만큼 반복하며 최적의 하이퍼 파라미터 찾음
trials=trials,
)
## 획득한 최적의 하이퍼 파라미터를 이용하여 모델 선언
lgbm_wrapper = LGBMClassifier(
n_estimators=500,
num_leaves=int(best['num_leaves']),
learning_rate=round(best['learning_rate'], 5),
max_depth=int(best['max_depth']),
min_child_weight=int(best['min_child_weight']),
subsample=round(best['subsample'], 5)
)
lgbm_wrapper.fit(
X_tr, y_tr,
early_stopping_rounds=100,
eval_metric='auc',
eval_set=[(X_tr, y_tr), (X_test, y_test)]
)
lgbm_roc_score = roc_auc_score(
y_test,
lgbm_wrapper.predict_proba(X_test)[:, 1]
)
lgbm_roc_score