머신러닝 앙상블 학습(Ensemble Learning) - 부스팅(Boosting) (3) : LightGBM

2 minute read

1. LightGBM

LightGBM은 XGBoost를 보완하여 나온 알고리즘으로, XGBoost보다 속도가 더 빠르고 메모리 사용량도 더 적다. 그러면서도 예측 성능은 XGBoost와 거의 같다.

LightGBM은 일반적인 GBM 계열이 균형 트리 분할(Level Wise) 방식을 사용했던 것과 다르게 리프 중심 트리 분할(Leaf Wise) 방식을 사용한다. LightGBM에 따르면, 이처럼 트리의 균형을 맞추지 않고 최대 손실값을 가지는 리프 노드를 지속적으로 분할해 생성한 규칙 트리는 학습을 반복할수록 균형 트리 분할 방식보다 예측 오류 손실을 최소화할 수 있고 시간도 적게 걸리게 된다.

image

뿐만 아니라 LightGBM은 카테고리형 피처 자동 변환 및 최적 분할을 지원하기도 한다.

2. LightGBM 주요 파라미터 (사이킷런 Wrapper)

사이킷런 Wrapper에서 사용하는 LightGBM 파라미터들은 기본적으로 XGBoost의 파라미터와 유사하며, XGBoost에 해당하는 파라미터가 없다면 파이썬 Wrapper의 하이퍼 파라미터를 가져온다.

XGBoost 하이퍼 파라미터 설명글 보기

이전 글들에서 다루지 않았던 부분이나 차이가 나는 부분만 정리해보자.

  • max_depth : 결정 트리의 max_depth와 동일하나, 리프 중심 트리 분할 방식을 사용하는만큼 max_depth를 매우 크게 가짐 (디폴트는 -1 : 0보다 작은 값이면 깊이 제한 없음)
  • min_child_samples : 결정트리의 min_samples_leaf와 같은 파라미터로, 최종 결정 클래스인 리프 노드가 되기 위해 최소한으로 필요한 레코드 수 (디폴트는 20)
  • num_leaves : 하나의 트리가 가질 수 있는 최대 리프 개수 (디폴트는 31)
  • early_stopping_roudnds : 학습 조기종료를 위한 early stopping interval 값
  • boosting_type : 부스팅의 트리를 생성하는 알고리즘으로, 일반적인 그래디언트 부스팅 결정 트리인 gbdt와 랜덤 포레스트인 rf가 있음 (디폴트는 gbdt)

3. 사이킷런에서 구현하기

데이터셋을 로딩하고 train_test_split()을 진행해보자.

import pandas as pd
import numpy as np
from sklearn.datasets import load_breast_cancer
from sklearn.model_selection import train_test_split

dataset = load_breast_cancer()
X_features= dataset.data
y_label = dataset.target

X_train, X_test, y_train, y_test=train_test_split(X_features, y_label, test_size=0.2, random_state=156)
print(X_train.shape, X_test.shape) # (455, 30) (114, 30)

사이킷런 Wrapper LightGBM을 적용해보자.

from lightgbm import LGBMClassifier

lgbm_wrapper = LGBMClassifier(n_estimators=400)

evals = [(X_test, y_test)] # 원래는 이렇게 하면 과적합
lgbm_wrapper.fit(X_train, y_train, early_stopping_rounds=100, eval_metric="logloss", eval_set=evals, verbose=True)

preds = lgbm_wrapper.predict(X_test)
pred_proba = lgbm_wrapper.predict_proba(X_test)[:, 1]
[1]	valid_0's binary_logloss: 0.565079
Training until validation scores don't improve for 100 rounds
[2]	valid_0's binary_logloss: 0.507451
.
.
.
[145]	valid_0's binary_logloss: 0.19712
Early stopping, best iteration is:
[45]	valid_0's binary_logloss: 0.122818

early_stopping_rounds 값을 100으로 했기 때문에 n_estimators 값인 400회에 도달하지 않더라도 예측 오류가 100번 동안 더 이상 개선되지 않으면 반복을 중지해 수행 시간을 줄일 수 있다. 단, early_stopping_rounds를 사용하기 위해서는 조기중단을 위한 평가지표인 eval_metric과 성능평가를 수행할 데이터셋인 eval_set을 함께 지정해줘야 한다.

  • logloss : Negative log-likelihood
  • eval_set : [(X_train, y_train), (X_test, y_test)]로 입력해도 되지만 [(X_test, y_test)]가 좀 더 명확한 설정이다. 그리고 원래는 지금처럼 테스트 데이터를 사용하는 것이 아니라 별도의 validation 데이터를 사용해야 한다.

LGBMClassifier 예측 성능을 확인해보자.

from sklearn.metrics import confusion_matrix, accuracy_score
from sklearn.metrics import precision_score, recall_score
from sklearn.metrics import f1_score, roc_auc_score

confusion = confusion_matrix(y_test, preds)
accuracy = accuracy_score(y_test, preds)
precision = precision_score(y_test, preds)
recall = recall_score(y_test, preds)
f1 = f1_score(y_test, preds)
roc_auc = roc_auc_score(y_test, pred_proba)

print(confusion)
print('정확도: {0:.4f}, 정밀도: {1:.4f}, 재현율: {2:.4f}, F1: {3:.4f}, AUC:{4:.4f}'.format(accuracy, precision, recall, f1, roc_auc))
[[33  4]
 [ 1 76]]
정확도: 0.9561, 정밀도: 0.9500, 재현율: 0.9870, F1: 0.9682, AUC:0.9905

4. plot_importance()

LightGBM에서도 XGBoost에서처럼 plot_importance() API를 사용하면 피처의 중요도를 쉽게 시각화할 수 있다.

from lightgbm import plot_importance
import matplotlib.pyplot as plt

fig, ax = plt.subplots(figsize=(10, 12))
plot_importance(lgbm_wrapper, ax=ax)

image

Leave a comment