본문으로 건너뛰기

031 LightGBM 분류 상세

키워드: LightGBM, lightgbm

개요

LightGBM(Light Gradient Boosting Machine)은 Microsoft에서 개발한 Gradient Boosting 프레임워크입니다. XGBoost보다 빠른 학습 속도와 낮은 메모리 사용이 특징입니다.

실습 환경

  • Python 버전: 3.11 권장
  • 필요 패키지: pycaret[full]>=3.0

LightGBM 특징

  • Leaf-wise 성장: Level-wise보다 효율적
  • 히스토그램 기반: 연속형 변수를 bin으로 이산화
  • 범주형 직접 지원: One-hot 인코딩 불필요
  • 빠른 속도: XGBoost 대비 10배 이상 빠를 수 있음
  • 낮은 메모리: 효율적인 메모리 사용

PyCaret에서 LightGBM

from pycaret.classification import *
from pycaret.datasets import get_data

# 031 데이터 로드
data = get_data('diabetes')
clf = setup(data, target='Class variable', session_id=42, verbose=False)

# 031 LightGBM 모델 생성
lgb = create_model('lightgbm')

주요 하이퍼파라미터

부스팅 파라미터

# 031 n_estimators: 부스팅 라운드 수
lgb = create_model('lightgbm', n_estimators=100)

# 031 learning_rate: 학습률
lgb = create_model('lightgbm', learning_rate=0.1)

# 031 boosting_type: 부스팅 방식
lgb = create_model('lightgbm', boosting_type='gbdt') # 기본값
# 031 lgb = create_model('lightgbm', boosting_type='dart')
# 031 lgb = create_model('lightgbm', boosting_type='goss')

트리 파라미터

# 031 num_leaves: 리프 노드 최대 수 (중요!)
lgb = create_model('lightgbm', num_leaves=31) # 기본값

# 031 max_depth: 최대 깊이 (-1 = 제한 없음)
lgb = create_model('lightgbm', max_depth=-1)

# 031 min_child_samples: 리프 노드 최소 샘플 수
lgb = create_model('lightgbm', min_child_samples=20)

# 031 subsample (bagging_fraction): 샘플 샘플링 비율
lgb = create_model('lightgbm', subsample=0.8)

# 031 colsample_bytree (feature_fraction): 특성 샘플링 비율
lgb = create_model('lightgbm', colsample_bytree=0.8)

정규화 파라미터

# 031 reg_alpha (lambda_l1): L1 정규화
lgb = create_model('lightgbm', reg_alpha=0)

# 031 reg_lambda (lambda_l2): L2 정규화
lgb = create_model('lightgbm', reg_lambda=0)

# 031 min_gain_to_split: 분할에 필요한 최소 gain
lgb = create_model('lightgbm', min_gain_to_split=0)

num_leaves vs max_depth

LightGBM은 Leaf-wise 방식이므로 num_leaves가 더 중요:

from pycaret.classification import *
from pycaret.datasets import get_data
import pandas as pd

data = get_data('credit')
clf = setup(data, target='default', session_id=42, verbose=False)

# 031 num_leaves 영향 분석
results = []

for leaves in [15, 31, 63, 127, 255]:
lgb = create_model('lightgbm', num_leaves=leaves, verbose=False)
metrics = pull()

results.append({
'num_leaves': leaves,
'accuracy': metrics['Accuracy'].mean(),
'auc': metrics['AUC'].mean()
})

df = pd.DataFrame(results)
print(df)

# 031 num_leaves가 크면 복잡한 모델 → 과적합 위험
# 031 일반적으로 2^max_depth - 1 이하로 설정

범주형 변수 처리

from pycaret.classification import *
from pycaret.datasets import get_data
import lightgbm as lgb

data = get_data('titanic')

# 031 PyCaret은 자동으로 범주형 처리
clf = setup(
data,
target='Survived',
ignore_features=['PassengerId', 'Name', 'Ticket', 'Cabin'],
categorical_features=['Pclass', 'Sex', 'Embarked'],
session_id=42,
verbose=False
)

lgb_model = create_model('lightgbm', verbose=False)

# 031 LightGBM 네이티브 API에서는 직접 지정
# 031 cat_features = ['Pclass', 'Sex', 'Embarked']

Early Stopping

import lightgbm as lgb
from sklearn.model_selection import train_test_split
from pycaret.classification import *
from pycaret.datasets import get_data

data = get_data('credit')
clf = setup(data, target='default', session_id=42, verbose=False)

X_train = get_config('X_train')
y_train = get_config('y_train')

X_tr, X_val, y_tr, y_val = train_test_split(
X_train, y_train, test_size=0.2, random_state=42
)

# 031 LightGBM 네이티브 API
train_data = lgb.Dataset(X_tr, label=y_tr)
val_data = lgb.Dataset(X_val, label=y_val, reference=train_data)

params = {
'objective': 'binary',
'metric': 'auc',
'num_leaves': 31,
'learning_rate': 0.05,
'verbose': -1
}

model = lgb.train(
params,
train_data,
num_boost_round=1000,
valid_sets=[train_data, val_data],
valid_names=['train', 'val'],
callbacks=[
lgb.early_stopping(stopping_rounds=50),
lgb.log_evaluation(period=100)
]
)

print(f"Best iteration: {model.best_iteration}")

특성 중요도

from pycaret.classification import *
from pycaret.datasets import get_data
import pandas as pd

data = get_data('diabetes')
clf = setup(data, target='Class variable', session_id=42, verbose=False)

lgb_model = create_model('lightgbm', verbose=False)

# 031 시각화
plot_model(lgb_model, plot='feature')

# 031 상세 중요도
feature_names = get_config('X_train').columns
importances = lgb_model.feature_importances_

importance_df = pd.DataFrame({
'feature': feature_names,
'importance': importances
}).sort_values('importance', ascending=False)

print(importance_df)

튜닝

from pycaret.classification import *
from pycaret.datasets import get_data

data = get_data('credit')
clf = setup(data, target='default', session_id=42, verbose=False)

# 031 기본 모델
lgb = create_model('lightgbm', verbose=False)

# 031 자동 튜닝
tuned_lgb = tune_model(lgb, optimize='AUC')

# 031 커스텀 그리드
custom_grid = {
'n_estimators': [100, 200, 300],
'num_leaves': [15, 31, 63],
'learning_rate': [0.01, 0.05, 0.1],
'subsample': [0.7, 0.8, 0.9],
'colsample_bytree': [0.7, 0.8, 0.9],
'reg_alpha': [0, 0.1, 1],
'reg_lambda': [0, 0.1, 1]
}

tuned_lgb = tune_model(lgb, custom_grid=custom_grid, optimize='AUC')

불균형 데이터

from pycaret.classification import *
from pycaret.datasets import get_data

data = get_data('credit')
clf = setup(data, target='default', session_id=42, verbose=False)

# 031 is_unbalance 또는 scale_pos_weight
lgb = create_model('lightgbm', is_unbalance=True, verbose=False)

# 031 또는 수동 계산
neg_count = (data['default'] == 0).sum()
pos_count = (data['default'] == 1).sum()
scale = neg_count / pos_count

lgb = create_model('lightgbm', scale_pos_weight=scale, verbose=False)

LightGBM vs XGBoost

항목LightGBMXGBoost
트리 성장Leaf-wiseLevel-wise
속도더 빠름빠름
메모리더 적음보통
범주형직접 지원인코딩 필요
작은 데이터과적합 위험더 안정적

장단점

장점:

  • 매우 빠른 학습
  • 낮은 메모리 사용
  • 범주형 변수 직접 지원
  • 대용량 데이터에 적합
  • GPU 지원

단점:

  • 작은 데이터에서 과적합 경향
  • num_leaves 튜닝 필요
  • 노이즈에 민감할 수 있음

정리

  • LightGBM은 빠르고 효율적인 Gradient Boosting
  • num_leaves가 핵심 파라미터 (max_depth보다 중요)
  • 범주형 변수 직접 처리 가능
  • 대용량 데이터에서 XGBoost보다 유리
  • 작은 데이터에서는 과적합 주의

다음 글 예고

다음 글에서는 CatBoost 분류 상세를 다룹니다.


PyCaret 머신러닝 마스터 시리즈 #031