본문으로 건너뛰기

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")
항목XGBoostLightGBM
트리 성장Level-wiseLeaf-wise
속도보통빠름
메모리많음적음
범주형 처리인코딩 필요네이티브 지원
과적합안정적num_leaves 조절 필요
소규모 데이터좋음과적합 위험

장단점

장점:

  • 매우 빠른 학습 속도
  • 낮은 메모리 사용량
  • 높은 정확도
  • 범주형 특성 네이티브 지원
  • 대용량 데이터에 적합
  • GOSS, EFB 등 최적화 기법

단점:

  • 소규모 데이터에서 과적합 위험
  • num_leaves 튜닝 필요
  • 노이즈에 민감할 수 있음

정리

  • LightGBM은 Leaf-wise 성장으로 빠른 학습
  • num_leaves가 가장 중요한 파라미터
  • 대용량 데이터에서 XGBoost보다 효율적
  • 범주형 특성을 네이티브로 처리
  • Early Stopping으로 과적합 방지

다음 글 예고

다음 글에서는 회귀 알고리즘 선택 가이드를 다룹니다.


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