[파머완] ch4.7 LightGBM

­반소희·2022년 7월 7일
1

ch4.7 LightGBM

LightGBMXGBoost와 함께 부스팅 계열 알고리즘에서 가장 많이 사용된다. XGBoost는 GBM 보다는 빠르지만 여전히 학습 시간이 오래 걸린다는 단점이 있다. LightGBM은 이러한 학습 시간을 개선한 알고리즘이라 할 수 있겠다. (메모리 사용량도 적음!)

  • 장점

    • 더 빠른 학습과 예측 수행 시간
    • 메모리 사용량이 적음
    • XGBoost와 예측 성능에서 큰 차이가 없음
    • 카테고리형 피처의 자동 변환과 최적 분할
      (원-핫 인코딩을 사용하지 않아도 피처를 최적으로 분할함)
  • 단점

    • 적은 데이터셋에 대해서는 과적합 우려가 있음 (기준 - 공식 문서에 의하면 약 1 만건 이하의 데이터셋)

일반적인 GBM 계열의 트리 분할 방법은 트리의 깊이를 효과적으로 줄이기 위해 '균형 트리 분할 방식'을 사용한다. (오버피팅에 더 강한 구조이기 때문) 이러한 방식은 균형을 맞추기 위한 시간이 필요하다는 상대적인 단점이 존재한다.

LightGBM은 '균형 트리 분할 방식' (Level Wise) 이 아닌 '리프 중심 트리 분할 방식' (Leaf Wise) 을 사용한다. 최대 손실 값을 가지는 리프 노드를 지속적으로 분할하면서 트리의 깊이가 깊어지고 비대칭적인 규칙 트리가 생성되는 것이 특징이다.

결국 학습을 반복할수록 균형 트리 분할 방식보다 예측 오류 손실을 최소화할 수 있다는 것이 해당 알고리즘의 사상이라 할 수 있겠다.

ch4.7 사이킷런 래퍼 LightGBM 하이퍼 파라미터

  • n_estimators

    • 반복을 수행하려는 트리의 개수
    • 기본값은 100
  • learning_rate

    • 기본값은 0.1
  • max_depth

    • Depth wise 방식이 아닌 Leaf Wise 방식이므로 깊이가 상대적으로 더 깊다는 점을 참고
    • 0보다 작은 값을 지정하면 깊이에 제한이 없음
    • 기본값은 -1
  • min_child_samples

    • 결정트리의 min_samples_leaf와 같은 파라미터
    • 기본값은 20
  • num_leaves

    • 하나의 트리가 가질 수 있는 최대 리프 개수
    • 기본값은 31
  • 위에서 언급한 파라미터 외에도 reg_lambda, reg_alpha, feature_fraction 등 다양한 하이퍼 파라미터가 존재함

ch4.7 LightGBM 과적합 감소 방법

LightGBM 모델 복잡도를 제어하는 주요 파라미터는 아래와 같다. 세 파라미터 모두 값이 커질수록 정확도가 올라갈 수 있지만 모델 복잡도가 커져 과적합 영향도 또한 커진다.

  • num_leaves
  • min_child_samples
  • max_depth

ch4.7 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()

profile
행복한 소히의 이것저것

0개의 댓글

관련 채용 정보