4 분 소요

분류

LightGBM

LightGBM 개요

XGBoost 대비 장점
- 더 빠른 학습과 예측 수행 시간
- 더 작은 메모리 사용량
- 카테고리형 피처의 자동 변환과 최적 분할 (원-핫 인코딩 등을 사용하지 않고도 카테고리형 피처를 최적으로 변환하고 이에 따른 노드 분할 수행)

LightGBM 트리 분할 방식 - 리프 중심

IMG_2555

LightGBM은 일반 GBM 계열의 트리 분할 방법과 다르게 리프 중심 트리 분할(Leaf Wise) 방식을 사용한다.

LightGBM 파이썬 구현

  1. C/C++ Native Module
    • 원래는 Windows 기반의 C/C++로 작성
    • 현재는 Linux 등 타 기반 OS 지원
  2. 파이썬 Wrapper
    • C/C++ 모듈을 호출하는 파이썬 Wrapper
  3. 사이킷런 Wrapper
    • 사이킷런 프레임과 통함 될 수 있는 파이썬 Wrapper Class 지원
      • LGBMClassifier
      • LGBMRegressor
    • 학습과 예측을 다른 사이킷런 API와 동일하게 fit( )과 predict( )로 수행
    • GridSearchCV와 같은 다른 사이킷런 모듈과 같이 사용 가능

LightGBM 설치

아나콘다 프롬프트를 관리자 권한으로 실행한 후 conda install -c conda-forge lightgbm 명령어를 입력한다.

LightGBM 하이퍼 파라미터

유형 파이썬 래퍼 LightGBM 사이킷런 래퍼 LightGBM  
  num_iterations n_estimators 약한 학습기의 개수 (반복 수행 횟수)
  learning_rate learning_rate 학습률 (learning rate)
0에서 1 사이의 값을 지정하며 부스팅 스텝을 반복적으로 수행할 때 업데이트되는 학습률 값
파라미터명 max_depth max_depth 결정트리의 max_depth와 동일
트리의 최대 깊이
  min_data_in_leaf min_child_samples 리프 노드가 될 수 있는 최소 데이터 건수 (Sample 수)
  bagging_fraction subsample 트리가 커져서 과적합되는 것을 제어하기 위해 데이터를 샘플링하는 비율 지정
sub_sample=0.5로 지정하면 전체 데이터의 절반을 트리를 생성하는 데 사용
  feature_fraction colsample_bytree GBM의 max_features와 유사
트리 생성에 필요한 피처(칼럼)를 임의로 샘플링 하는 데 사용
매우 많은 피처가 있는 경우 과적합을 조정하는 데 적용

lightGBM 사이킷런 래퍼는 XGBoost 사이킷런 래퍼에 해당 하이퍼 파라미터가 있으면 이를 그대로 사용하고 그렇지 않으면 파이썬 래퍼 LightGBM 하이퍼 파라미터 사용

하이퍼 파라미터 튜닝 방안

유형 파이썬 래퍼 LightGBM 사이킷런 래퍼 LightGBM  
  lambda_l2 reg_lambda L2 규제(Regularization) 적용 값
기본값은 1
값이 클수록 규제 값이 커짐
과적합 제어
  lambda_l1 reg_alpha L1 규제(Regularization) 적용 값
기본값은 0
값이 클수록 규제 값이 커짐
과적합 제어
파라미터명 early_stopping_round early_stopping_rounds 학습 조기 종료를 위한 early stopping interval 값
  num_leaves num_leaves 최대 리프 노드 개수
  min_sum_hessian_in_leaf min_child_weight 결정트리의 min_child_leaf와 유사
과적합 조절용

num_leaves의 개수를 중심으로 min_child_samples(min_data_in_leaf), max_depth를 함께 조정하면서 모델의 복잡도를 줄이는 것이 기본 튜닝 방안

파이썬 래퍼 LightGBM과 사이킷런 래퍼 XGBoost, LightGBM 하이퍼 파라미터 비교

유형 파이썬 래퍼 LightGBM 사이킷런 래퍼 LightGBM 사이킷런 래퍼 XGBoost
  num_iterations n_estimators n_estimators
  learning_rate learning_rate learning_rate
max_depth max_depth max_depth
min_data_in_leaf min_child_samples N/A
bagging_fraction subsample subsample
feature_fraction colsample_bytree colsample_bytree
lambda_l2 reg_lambda reg_lambda
  lambda_l1 reg_alpha reg_alpha
  early_stopping_round early_stopping_rounds early_stopping_rounds
  num_leaves num_leaves N/A
  min_sum_hessian_in_leaf min_child_weight min_child_weight

LightGBM 적용 – 위스콘신 유방암 예측

<실습>

import lightgbm

print(lightgbm.__version__)
3.3.2
# LightGBM의 파이썬 패키지인 lightgbm에서 LGBMClassifier 임포트
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
import warnings
warnings.filterwarnings('ignore')

dataset = load_breast_cancer()

cancer_df = pd.DataFrame(data=dataset.data, columns=dataset.feature_names)
cancer_df['target']= dataset.target

cancer_df.head()
mean radius mean texture mean perimeter mean area mean smoothness mean compactness mean concavity mean concave points mean symmetry mean fractal dimension ... worst texture worst perimeter worst area worst smoothness worst compactness worst concavity worst concave points worst symmetry worst fractal dimension target
0 17.99 10.38 122.80 1001.0 0.11840 0.27760 0.3001 0.14710 0.2419 0.07871 ... 17.33 184.60 2019.0 0.1622 0.6656 0.7119 0.2654 0.4601 0.11890 0
1 20.57 17.77 132.90 1326.0 0.08474 0.07864 0.0869 0.07017 0.1812 0.05667 ... 23.41 158.80 1956.0 0.1238 0.1866 0.2416 0.1860 0.2750 0.08902 0
2 19.69 21.25 130.00 1203.0 0.10960 0.15990 0.1974 0.12790 0.2069 0.05999 ... 25.53 152.50 1709.0 0.1444 0.4245 0.4504 0.2430 0.3613 0.08758 0
3 11.42 20.38 77.58 386.1 0.14250 0.28390 0.2414 0.10520 0.2597 0.09744 ... 26.50 98.87 567.7 0.2098 0.8663 0.6869 0.2575 0.6638 0.17300 0
4 20.29 14.34 135.10 1297.0 0.10030 0.13280 0.1980 0.10430 0.1809 0.05883 ... 16.67 152.20 1575.0 0.1374 0.2050 0.4000 0.1625 0.2364 0.07678 0

5 rows × 31 columns

X_features = cancer_df.iloc[:, :-1]
y_label = cancer_df.iloc[:, -1]

# 전체 데이터 중 80%는 학습용 데이터, 20%는 테스트용 데이터 추출
X_train, X_test, y_train, y_test=train_test_split(X_features, y_label,
                                         test_size=0.2, random_state=156 )

# 위에서 만든 X_train, y_train을 다시 쪼개서 90%는 학습과 10%는 검증용 데이터로 분리  
X_tr, X_val, y_tr, y_val= train_test_split(X_train, y_train,
                                         test_size=0.1, random_state=156 )

# 앞서 XGBoost와 동일하게 n_estimators는 400 설정. 
lgbm_wrapper = LGBMClassifier(n_estimators=400, learning_rate=0.05)

# LightGBM도 XGBoost와 동일하게 조기 중단 수행 가능. 
evals = [(X_tr, y_tr), (X_val, y_val)]
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)[:, 1]
[1]	training's binary_logloss: 0.625671	valid_1's 
.
. (생략)
.
[61]	training's binary_logloss: 0.0532381	valid_1's binary_logloss: 0.260236
.
. (생략)
.
[111]	training's binary_logloss: 0.00850714	valid_1's binary_logloss: 0.280894
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

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 = roc_auc_score(y_test, pred_proba)
    print('오차 행렬')
    print(confusion)
    # ROC-AUC print 추가
    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)
오차 행렬
[[34  3]
 [ 2 75]]
정확도: 0.9561, 정밀도: 0.9615, 재현율: 0.9740,    F1: 0.9677, AUC:0.9877
# plot_importance( )를 이용하여 feature 중요도 시각화
from lightgbm import plot_importance
import matplotlib.pyplot as plt
%matplotlib inline

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

output_7_01