본문 바로가기

파이썬/머신러닝

light GBM이란? 파라미터 설명과 코드 실습

LightGBM은 XGBoost에 비해 훈련 시간이 짧고 성능도 좋아 부스팅 알고리즘에서 가장 많은 주목을 받고 있다.

GradientBoosting을 발전시킨 것이 XGBoost, 여기서 속도를 더 높인 것이 LightGBM이다.

 

※참고

부스팅과 배깅의 차이점과 AdaBoosting / GradientBoosting 개념

 

 

 

LightGBM이란?

리프 기준 분할(불균형 트리)
트리 기준 분할(균형 트리)

 

LightGBM은 트리 기준 분할이 아닌 리프 기준 분할 방식을 사용한다. 트리의 균형을 맞추지 않고 최대 손실 값을 갖는 리프 노드를 지속적으로 분할하면서 깊고 비대칭적인 트리를 생성한다. 이렇게 하면 트리 기준 분할 방식에 비해 예측 오류 손실을 최소화할 수 있다.

 

 

 

LightGBM 파라미터

파라미터 default 설명
num_iterations 100 반복 수행하려는 트리의 개수 (너무 크면 오버피팅 발생)
objective regression 수치예측이면 regression, 이진분류이면 binary
learning_rate 0.1 부스팅 스탭 반복할 때 학습률, 0~1 사이의 값
max_depth 1 트리의 깊이
min_data_in_leaf 20 한 리프의 최소 데이터 수
(decision tree의 min_sample_leaf와 동일, 오버피팅 제어)
num_leaves 31 하나의 트리가 가질 수 있는 최대 리프 개수
boosting gbdt 부스팅 방법 (gbdt: Gradient Boosting DecisionTree / rf: RandomForest)
bagging_fraction 1.0 데이터 샘플링 비율, 오버피팅 제어
feature_fraction 1.0 개별 트리 학습 시 무작위로 선택하는 feature의 비율
lambda_l1 0.0 L1 regulation 제어
lambda_l2 0.0 L2 regulation 제어
metric "" 성능평가를 어떤 것으로 할 것인지 (auc, l1, l2 등)

 

lightGBM의 파라미터는 Control, Core, Metric, IO 총 4가지 카테고리의 파라미터가 있고 총 100개가 넘는다. 그래서 모든 파라미터에 대해 다 세세하게 알 수는 없지만 자주 사용되고 중요한 몇 가지 파라미터에 대해서는 숙지가 필요하다.

 

 

num_leaves: 클수록 정확도는 높아지지만 오버피팅 발생 가능

min_data_in_leaf: 클수록 오버피팅 방지

max_depth: 위 두개 파라미터와 결합하여 오버피팅 방지

objective: 사용하는 데이터셋의 타겟팅 값의 형태에 따라 조정 필요

metric: 성능 평가를 어떤 것으로 할 것인지 조정 필요 

 

 

LightGBM 장단점

 

장점

1. 학습하는데 시간이 짧다. (통상 XGBoost 학습속도의 1.3~1.5배)

2. 메모리 사용량이 상대적으로 적다.

3. 대용량 데이터 처리 가능

 

단점

1. 적은 데이터셋(공식문서 기준 만건 이하)에서는 오버피팅 발생 가능

 

 

LightGBM 코드 실습

 

코드는 heart attack 데이터를 사용해서 실습했다. 전처리는 이전에 

 

import pandas as pd
import numpy as np
from sklearn.model_selection import train_test_split
from sklearn.preprocessing import StandardScaler

heart = pd.read_csv('heart.csv')

#범주형/연속형 변수 분리
cat_col = ['sex', 'cp', 'fbs', 'restecg', 'exng', 'slp', 'caa', 'thall']
con_col = ['age', 'trtbps', 'thalachh', 'oldpeak']

heart_raw = heart.copy() #원본 데이터 copy

#get_dummies()로 범주형 변수 원핫인코딩
heart = pd.get_dummies(heart, columns=cat_col, drop_first=True)

#train, test, val 분리
X = heart.drop(['output'], axis=1)
y = heart[['output']]

X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.4, random_state=42)
X_test, X_val, y_test, y_val = train_test_split(X_test, y_test, test_size=0.5, random_state=42)

#연속형 변수 스케일링
scaler = StandardScaler()
scaler.fit(X_train.loc[:,con_col])

X_train.loc[:,con_col] = scaler.transform(X_train.loc[:,con_col])
X_test.loc[:,con_col]  = scaler.transform(X_test.loc[:,con_col])
X_val.loc[:,con_col]   = scaler.transform(X_val.loc[:,con_col])

 

여기까지 EDA를 끝내고 본격적으로 LGB 모델에 학습을 시켜보자.

 

import lightgbm as lgb

lgb_clf = lgb.LGBMClassifier(num_leaves=31, objective='binary')
lgb_clf.fit(X_train, y_train)
y_pred = lgb_clf.predict(X_val)
accuracy_score(y_val, y_pred)
>>>0.7377049180327869

 

여기서는 LGBMClassifier를 사용했다. 이렇게 하면 기존의 사이킷런 모델들과 거의 동일하게 fit, predict로 모델을 학습, 예측하고 accuracy_score로 성능 평가가 가능하다.

 

 

이렇게 classifier를 사용하지 않고 lgb 그 자체를 사용해서 모델 학습도 가능하다.

 

import lightgbm as lgb

#파라미터는 dict에
param = {'num_leaves': 31, 'objective': 'binary', 'metric':'auc'}

#train data를 별도의 Dataset객체로 만들어야 함
train_data = lgb.Dataset(X_train, label=y_train.values)

#boosting을 몇 번 할건지 결정
num_round = 10 

#모델에 훈련
bst = lgb.train(param, train_data, num_round)

#예측
y_pred_val = bst.predict(X_val)
print(y_pred_val)

lgb에서 predict 메서드는 사이킷런의 predict와 달리 확률값을 반환한다. (마치 predict_proba처럼!)

accuracy_score로 성능을 평가하려면 1 또는 0의 binary 값으로 바꿔줘야 하기 때문에 확률값이 0.5 이상이면 1, 미만이면 0으로 라벨값을 설정해줘야 한다.

 

#확률값을 라벨값으로
y_pred_val = pd.Series(y_pred_val).apply(lambda x: 1 if x>=0.5 else 0) 

#성능평가
accuracy_score(y_val, y_pred_val)
>>>0.7868852459016393

 

성능은 LGBMClassifier보다 조금 더 낫다.

 

 

 

보다 더 자세한 내용은 lgbm 공식 사이트에서 확인!

https://lightgbm.readthedocs.io/en/latest/index.html