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
| 항목 | LightGBM | XGBoost |
|---|---|---|
| 트리 성장 | Leaf-wise | Level-wise |
| 속도 | 더 빠름 | 빠름 |
| 메모리 | 더 적음 | 보통 |
| 범주형 | 직접 지원 | 인코딩 필요 |
| 작은 데이터 | 과적합 위험 | 더 안정적 |
장단점
장점:
- 매우 빠른 학습
- 낮은 메모리 사용
- 범주형 변수 직접 지원
- 대용량 데이터에 적합
- GPU 지원
단점:
- 작은 데이터에서 과적합 경향
- num_leaves 튜닝 필요
- 노이즈에 민감할 수 있음
정리
- LightGBM은 빠르고 효율적인 Gradient Boosting
- num_leaves가 핵심 파라미터 (max_depth보다 중요)
- 범주형 변수 직접 처리 가능
- 대용량 데이터에서 XGBoost보다 유리
- 작은 데이터에서는 과적합 주의
다음 글 예고
다음 글에서는 CatBoost 분류 상세를 다룹니다.
PyCaret 머신러닝 마스터 시리즈 #031