LightGBM은 XGBoost와 함께 부스팅 계열 알고리즘에서 가장 많이 사용된다. XGBoost는 GBM 보다는 빠르지만 여전히 학습 시간이 오래 걸린다는 단점이 있다. LightGBM은 이러한 학습 시간을 개선한 알고리즘이라 할 수 있겠다. (메모리 사용량도 적음!)
장점
단점
일반적인 GBM 계열의 트리 분할 방법은 트리의 깊이를 효과적으로 줄이기 위해 '균형 트리 분할 방식'을 사용한다. (오버피팅에 더 강한 구조이기 때문) 이러한 방식은 균형을 맞추기 위한 시간이 필요하다는 상대적인 단점이 존재한다.
LightGBM은 '균형 트리 분할 방식' (Level Wise) 이 아닌 '리프 중심 트리 분할 방식' (Leaf Wise) 을 사용한다. 최대 손실 값을 가지는 리프 노드를 지속적으로 분할하면서 트리의 깊이가 깊어지고 비대칭적인 규칙 트리가 생성되는 것이 특징이다.
결국 학습을 반복할수록 균형 트리 분할 방식보다 예측 오류 손실을 최소화할 수 있다는 것이 해당 알고리즘의 사상이라 할 수 있겠다.
n_estimators
learning_rate
max_depth
min_child_samples
num_leaves
위에서 언급한 파라미터 외에도 reg_lambda, reg_alpha, feature_fraction 등 다양한 하이퍼 파라미터가 존재함
LightGBM 모델 복잡도를 제어하는 주요 파라미터는 아래와 같다. 세 파라미터 모두 값이 커질수록 정확도가 올라갈 수 있지만 모델 복잡도가 커져 과적합 영향도 또한 커진다.
from lightgbm import LGBMClassifier
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()
dataset
## dataframe 생성
cancer_df = pd.DataFrame(data=dataset.data, columns=dataset.feature_names)
## dataframe에 레이블 열 추가
cancer_df['target'] = dataset.target
## dataframe에서 feature과 label 구분
X_features = cancer_df.iloc[:, :-1]
y_label = cancer_df.iloc[:, -1]
## data split => train / test
X_train, X_test, y_train, y_test = train_test_split(X_features, y_label, test_size=0.2, random_state=156)
## data split => train => train / val
X_tr, X_val, y_tr, y_val = train_test_split(X_train, y_train, test_size=0.1, random_state=156)
## lgbm model
lgbm_wrapper = LGBMClassifier(n_estimators=400, learning_rate=0.05) ## 400번 epochs, lr = 0.05 지정
## learly stopping
evals = [(X_tr, y_tr), (X_val, y_val)]
## model_training => early stopping으로 인해 조기 중단됨
lgbm_wrapper.fit(X_tr, y_tr,
early_stopping_rounds=50,
eval_metric="logloss",
eval_set=evals,
verbose=True
)
preds = lgbm_wrapper.predict(X_test)
pred_proba = lgbm_wrapper.predict_proba(X_test)
pred_proba = pred_proba[:, 1]
## 모델 성능 평가 함수 선언
from sklearn.metrics import accuracy_score, confusion_matrix, precision_score, recall_score, f1_score, roc_auc_score
def get_clf_eval(y_test, pred=None, pred_proba=None):
confusion = confusion_matrix(y_test, pred)
accuracy = accuracy_score(y_test, pred)
precision = precision_score(y_test, pred)
recall = recall_score(y_test, pred)
f1 = f1_score(y_test, pred)
roc_auc = roc_auc_score(y_test, pred_proba)
print('오차 행렬')
print(confusion)
print('정확도: {0:.4f}, 정밀도: {1:.4f}, 재현율: {2:.4f}, F1: {3:.4f}, AUC: {4:.4f}'.format(accuracy, precision, recall, f1, roc_auc))
get_clf_eval(y_test, preds, pred_proba)
import matplotlib.pyplot as plt
import seaborn as sns
%matplotlib inline
ftr_importances_values = lgbm_wrapper.feature_importances_ ## feature_importances_
ftr_importances = pd.Series(ftr_importances_values, index=X_train.columns)
ftr_top20 = ftr_importances.sort_values(ascending=False)[:20]
plt.figure(figsize=(8, 6))
plt.title('Feature importances Top 20')
sns.barplot(x=ftr_top20, y=ftr_top20.index)
plt.show()