051 LightGBM 회귀 상세
키워드: LightGBM, 회귀
개요
LightGBM(Light Gradient Boosting Machine)은 Microsoft에서 개발한 고성능 그래디언트 부스팅 프레임워크입니다. 대용량 데이터에서 빠른 학습 속도와 낮은 메모리 사용량을 제공합니다.
실습 환경
- Python 버전: 3.11 권장
- 필요 패키지:
pycaret[full]>=3.0
LightGBM의 핵심 특징
Leaf-wise (Best-first) 성장
일반적인 Level-wise 방식과 달리 Leaf-wise로 트리를 성장시킵니다:
Level-wise (XGBoost): Leaf-wise (LightGBM):
[1] [1]
/ \ / \
[2] [3] [2] [3]
/ \ / \ / \
[4] [5][6] [7] [4] [5]
/ \
모든 노드를 동일 깊이로 [6] [7]
손실 감소가 큰 리프만 분할
장점: 더 빠른 수렴, 높은 정확도 단점: 과적합 위험 (num_leaves로 제어)
PyCaret에서 LightGBM 회귀
from pycaret.regression import *
from pycaret.datasets import get_data
data = get_data('boston')
reg = setup(data, target='medv', session_id=42, verbose=False)
# 051 LightGBM 회귀
lgbm = create_model('lightgbm')
주요 하이퍼파라미터
# 051 num_leaves: 리프 노드 수 (가장 중요한 파라미터)
lgbm = create_model('lightgbm', num_leaves=31)
# 051 n_estimators: 부스팅 라운드 수
lgbm = create_model('lightgbm', n_estimators=100)
# 051 learning_rate: 학습률
lgbm = create_model('lightgbm', learning_rate=0.1)
# 051 max_depth: 최대 깊이 (-1은 제한 없음)
lgbm = create_model('lightgbm', max_depth=-1)
# 051 min_child_samples: 리프 최소 샘플 수
lgbm = create_model('lightgbm', min_child_samples=20)
# 051 subsample: 샘플 비율 (배깅)
lgbm = create_model('lightgbm', subsample=0.8)
# 051 colsample_bytree: 특성 비율
lgbm = create_model('lightgbm', colsample_bytree=0.8)
# 051 reg_alpha (L1), reg_lambda (L2): 정규화
lgbm = create_model('lightgbm', reg_alpha=0, reg_lambda=1)
num_leaves 설정 가이드
from pycaret.regression import *
from pycaret.datasets import get_data
import pandas as pd
data = get_data('boston')
reg = setup(data, target='medv', session_id=42, verbose=False)
# 051 num_leaves에 따른 성능 변화
results = []
for leaves in [15, 31, 63, 127, 255]:
lgbm = create_model('lightgbm', num_leaves=leaves, verbose=False)
metrics = pull()
results.append({
'num_leaves': leaves,
'RMSE': metrics['RMSE'].mean(),
'R2': metrics['R2'].mean()
})
df = pd.DataFrame(results)
print(df)
# 051 num_leaves = 2^max_depth - 1 관계
# 051 max_depth=5 → num_leaves <= 31 권장
Boosting Type
# 051 boosting_type: 부스팅 방식
# 051 gbdt: Gradient Boosting Decision Tree (기본값)
lgbm_gbdt = create_model('lightgbm', boosting_type='gbdt')
# 051 dart: Dropouts meet Multiple Additive Regression Trees
lgbm_dart = create_model('lightgbm', boosting_type='dart')
# 051 goss: Gradient-based One-Side Sampling (대용량 데이터용)
lgbm_goss = create_model('lightgbm', boosting_type='goss')
# 051 rf: Random Forest 모드
lgbm_rf = create_model('lightgbm', boosting_type='rf', bagging_fraction=0.8, bagging_freq=1)
GOSS (Gradient-based One-Side Sampling)
대용량 데이터에서 학습 속도 향상:
import lightgbm as lgb
from pycaret.regression import *
from pycaret.datasets import get_data
data = get_data('boston')
reg = setup(data, target='medv', session_id=42, verbose=False)
# 051 GOSS 파라미터
# 051 top_rate: 큰 gradient를 가진 데이터 비율
# 051 other_rate: 작은 gradient 데이터 중 샘플링 비율
lgbm_goss = create_model(
'lightgbm',
boosting_type='goss',
top_rate=0.2,
other_rate=0.1
)
Early Stopping
import lightgbm as lgb
from sklearn.model_selection import train_test_split
from pycaret.regression import *
from pycaret.datasets import get_data
data = get_data('boston')
reg = setup(data, target='medv', 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
)
# 051 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': 'regression',
'metric': 'rmse',
'num_leaves': 31,
'learning_rate': 0.05,
'feature_fraction': 0.8,
'bagging_fraction': 0.8,
'bagging_freq': 5,
'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(100)
]
)
print(f"Best iteration: {model.best_iteration}")
print(f"Best RMSE: {model.best_score['val']['rmse']:.4f}")
튜닝
from pycaret.regression import *
from pycaret.datasets import get_data
data = get_data('boston')
reg = setup(data, target='medv', session_id=42, verbose=False)
lgbm = create_model('lightgbm', verbose=False)
# 051 자동 튜닝
tuned_lgbm = tune_model(lgbm, optimize='RMSE')
# 051 커스텀 그리드
custom_grid = {
'num_leaves': [15, 31, 63],
'n_estimators': [100, 200, 300],
'learning_rate': [0.01, 0.05, 0.1],
'max_depth': [5, 7, -1],
'min_child_samples': [10, 20, 30],
'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_lgbm = tune_model(lgbm, custom_grid=custom_grid, optimize='RMSE')
특성 중요도
from pycaret.regression import *
from pycaret.datasets import get_data
import pandas as pd
data = get_data('boston')
reg = setup(data, target='medv', session_id=42, verbose=False)
lgbm = create_model('lightgbm', verbose=False)
# 051 특성 중요도
feature_names = get_config('X_train').columns
importances = lgbm.feature_importances_
importance_df = pd.DataFrame({
'Feature': feature_names,
'Importance': importances
}).sort_values('Importance', ascending=False)
print(importance_df)
# 051 시각화
plot_model(lgbm, plot='feature')
LightGBM 중요도 유형
import lightgbm as lgb
from pycaret.regression import *
from pycaret.datasets import get_data
data = get_data('boston')
reg = setup(data, target='medv', session_id=42, verbose=False)
lgbm = create_model('lightgbm', verbose=False)
# 051 split: 분할 횟수 기반
split_importance = lgbm.booster_.feature_importance(importance_type='split')
# 051 gain: 정보 이득 기반
gain_importance = lgbm.booster_.feature_importance(importance_type='gain')
feature_names = get_config('X_train').columns
import pandas as pd
importance_df = pd.DataFrame({
'Feature': feature_names,
'Split': split_importance,
'Gain': gain_importance
}).sort_values('Gain', ascending=False)
print(importance_df)
범주형 특성 처리
LightGBM의 강점 중 하나:
import lightgbm as lgb
import pandas as pd
import numpy as np
# 051 범주형 특성이 있는 데이터
np.random.seed(42)
data = pd.DataFrame({
'category_a': np.random.choice(['A', 'B', 'C'], 500),
'category_b': np.random.choice(['X', 'Y', 'Z'], 500),
'numeric': np.random.randn(500),
'target': np.random.randn(500) * 10 + 50
})
from pycaret.regression import *
# 051 PyCaret이 자동으로 범주형 처리
reg = setup(data, target='target', session_id=42, verbose=False)
# 051 LightGBM은 범주형을 효율적으로 처리
lgbm = create_model('lightgbm', verbose=False)
GPU 가속
# 051 GPU 사용 (CUDA 필요)
lgbm_gpu = create_model(
'lightgbm',
device='gpu',
gpu_platform_id=0,
gpu_device_id=0
)
XGBoost vs LightGBM
from pycaret.regression import *
from pycaret.datasets import get_data
import time
data = get_data('boston')
reg = setup(data, target='medv', session_id=42, verbose=False)
# 051 XGBoost
start = time.time()
xgb = create_model('xgboost', verbose=False)
xgb_time = time.time() - start
xgb_metrics = pull()
# 051 LightGBM
start = time.time()
lgbm = create_model('lightgbm', verbose=False)
lgbm_time = time.time() - start
lgbm_metrics = pull()
print(f"XGBoost - RMSE: {xgb_metrics['RMSE'].mean():.4f}, Time: {xgb_time:.2f}s")
print(f"LightGBM - RMSE: {lgbm_metrics['RMSE'].mean():.4f}, Time: {lgbm_time:.2f}s")
| 항목 | XGBoost | LightGBM |
|---|---|---|
| 트리 성장 | Level-wise | Leaf-wise |
| 속도 | 보통 | 빠름 |
| 메모리 | 많음 | 적음 |
| 범주형 처리 | 인코딩 필요 | 네이티브 지원 |
| 과적합 | 안정적 | num_leaves 조절 필요 |
| 소규모 데이터 | 좋음 | 과적합 위험 |
장단점
장점:
- 매우 빠른 학습 속도
- 낮은 메모리 사용량
- 높은 정확도
- 범주형 특성 네이티브 지원
- 대용량 데이터에 적합
- GOSS, EFB 등 최적화 기법
단점:
- 소규모 데이터에서 과적합 위험
- num_leaves 튜닝 필요
- 노이즈에 민감할 수 있음
정리
- LightGBM은 Leaf-wise 성장으로 빠른 학습
- num_leaves가 가장 중요한 파라미터
- 대용량 데이터에서 XGBoost보다 효율적
- 범주형 특성을 네이티브로 처리
- Early Stopping으로 과적합 방지
다음 글 예고
다음 글에서는 회귀 알고리즘 선택 가이드를 다룹니다.
PyCaret 머신러닝 마스터 시리즈 #051