앙상블 학습 - 부스팅 (Boosting)
앙상블 학습 - 부스팅 (Boosting)¶
개요¶
부스팅(Boosting)은 여러 개의 약한 학습기를 순차적으로 학습하여 강한 학습기를 만드는 앙상블 기법입니다. 각 학습기는 이전 학습기의 오류를 보완하도록 학습됩니다.
1. 부스팅의 기본 개념¶
1.1 배깅 vs 부스팅¶
"""
배깅 (Bagging):
- 병렬 학습: 각 모델 독립적으로 학습
- 분산 감소: 과적합 방지
- 결합 방법: 평균 또는 다수결
부스팅 (Boosting):
- 순차 학습: 이전 모델의 오류 보완
- 편향 감소: 과소적합 해결
- 결합 방법: 가중 투표
비유:
- 배깅: 여러 전문가가 독립적으로 의견 제시 후 종합
- 부스팅: 한 전문가가 실수한 부분을 다음 전문가가 집중 보완
"""
1.2 부스팅 알고리즘 종류¶
"""
주요 부스팅 알고리즘:
1. AdaBoost (Adaptive Boosting):
- 잘못 분류된 샘플에 가중치 증가
- 분류 문제에 주로 사용
2. Gradient Boosting:
- 잔차(residual)를 예측하는 방식
- 분류와 회귀 모두 가능
3. XGBoost (eXtreme Gradient Boosting):
- Gradient Boosting 최적화 버전
- 정규화, 병렬처리 지원
4. LightGBM:
- 리프 중심 분할 방식
- 대용량 데이터에 효율적
5. CatBoost:
- 범주형 특성 자동 처리
- Ordered Boosting
"""
2. AdaBoost¶
2.1 AdaBoost 원리¶
import numpy as np
import matplotlib.pyplot as plt
from sklearn.ensemble import AdaBoostClassifier
from sklearn.tree import DecisionTreeClassifier
from sklearn.datasets import make_classification
from sklearn.model_selection import train_test_split
from sklearn.metrics import accuracy_score
"""
AdaBoost 알고리즘:
1. 초기화: 모든 샘플에 동일한 가중치 (1/n)
2. 반복 (t = 1, 2, ..., T):
a. 가중치 기반으로 약한 학습기 학습
b. 가중 오류율 계산: ε_t = Σ w_i * I(y_i ≠ h_t(x_i))
c. 학습기 가중치 계산: α_t = 0.5 * log((1-ε_t)/ε_t)
d. 샘플 가중치 업데이트:
- 틀린 샘플: w_i *= exp(α_t)
- 맞은 샘플: w_i *= exp(-α_t)
e. 가중치 정규화
3. 최종 예측: sign(Σ α_t * h_t(x))
"""
2.2 AdaBoost 기본 사용법¶
# 데이터 생성
X, y = make_classification(
n_samples=1000, n_features=20,
n_informative=15, n_redundant=5,
random_state=42
)
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.2, random_state=42)
# AdaBoost 분류기
ada_clf = AdaBoostClassifier(
estimator=DecisionTreeClassifier(max_depth=1), # 약한 학습기 (stump)
n_estimators=50,
learning_rate=1.0,
algorithm='SAMME', # 'SAMME' or 'SAMME.R'
random_state=42
)
ada_clf.fit(X_train, y_train)
y_pred = ada_clf.predict(X_test)
print("AdaBoost 결과:")
print(f" 훈련 정확도: {ada_clf.score(X_train, y_train):.4f}")
print(f" 테스트 정확도: {accuracy_score(y_test, y_pred):.4f}")
2.3 학습기 수에 따른 성능¶
# 학습기 수 증가에 따른 성능 변화
n_estimators_range = [1, 5, 10, 20, 50, 100, 200]
train_scores = []
test_scores = []
for n_est in n_estimators_range:
ada = AdaBoostClassifier(
estimator=DecisionTreeClassifier(max_depth=1),
n_estimators=n_est,
random_state=42
)
ada.fit(X_train, y_train)
train_scores.append(ada.score(X_train, y_train))
test_scores.append(ada.score(X_test, y_test))
# 시각화
plt.figure(figsize=(10, 6))
plt.plot(n_estimators_range, train_scores, 'o-', label='Train')
plt.plot(n_estimators_range, test_scores, 's-', label='Test')
plt.xlabel('Number of Estimators')
plt.ylabel('Accuracy')
plt.title('AdaBoost: Performance vs Number of Estimators')
plt.legend()
plt.grid(True, alpha=0.3)
plt.show()
2.4 스테이지별 에러 분석¶
# 스테이지별 에러
ada = AdaBoostClassifier(
estimator=DecisionTreeClassifier(max_depth=1),
n_estimators=100,
random_state=42
)
ada.fit(X_train, y_train)
# 스테이지별 예측
staged_train_scores = list(ada.staged_score(X_train, y_train))
staged_test_scores = list(ada.staged_score(X_test, y_test))
# 시각화
plt.figure(figsize=(10, 6))
plt.plot(range(1, len(staged_train_scores)+1), staged_train_scores, label='Train')
plt.plot(range(1, len(staged_test_scores)+1), staged_test_scores, label='Test')
plt.xlabel('Number of Estimators')
plt.ylabel('Accuracy')
plt.title('AdaBoost: Staged Performance')
plt.legend()
plt.grid(True, alpha=0.3)
plt.show()
3. Gradient Boosting¶
3.1 Gradient Boosting 원리¶
"""
Gradient Boosting 알고리즘:
목표: 손실 함수 L(y, F(x))를 최소화하는 F(x) 찾기
1. 초기화: F_0(x) = argmin_γ Σ L(y_i, γ)
2. 반복 (m = 1, 2, ..., M):
a. 의사 잔차(pseudo-residual) 계산:
r_im = -[∂L(y_i, F(x_i))/∂F(x_i)]_{F=F_{m-1}}
b. 잔차에 대해 약한 학습기 h_m(x) 학습
c. 최적 스텝 크기 계산:
γ_m = argmin_γ Σ L(y_i, F_{m-1}(x_i) + γ * h_m(x_i))
d. 모델 업데이트:
F_m(x) = F_{m-1}(x) + learning_rate * γ_m * h_m(x)
손실 함수 예:
- 회귀: MSE → 잔차 = y - F(x)
- 분류: Logloss → 잔차 = y - sigmoid(F(x))
"""
3.2 sklearn Gradient Boosting¶
from sklearn.ensemble import GradientBoostingClassifier, GradientBoostingRegressor
# Gradient Boosting 분류기
gb_clf = GradientBoostingClassifier(
n_estimators=100,
learning_rate=0.1,
max_depth=3,
min_samples_split=2,
min_samples_leaf=1,
subsample=1.0, # 각 트리에 사용할 샘플 비율
max_features=None, # 분할에 사용할 특성 수
random_state=42
)
gb_clf.fit(X_train, y_train)
print("Gradient Boosting 결과:")
print(f" 훈련 정확도: {gb_clf.score(X_train, y_train):.4f}")
print(f" 테스트 정확도: {gb_clf.score(X_test, y_test):.4f}")
# 특성 중요도
print("\n상위 5개 특성 중요도:")
indices = np.argsort(gb_clf.feature_importances_)[::-1][:5]
for i, idx in enumerate(indices):
print(f" {i+1}. Feature {idx}: {gb_clf.feature_importances_[idx]:.4f}")
3.3 학습률과 학습기 수의 균형¶
# learning_rate vs n_estimators 트레이드오프
learning_rates = [0.01, 0.1, 0.5, 1.0]
n_estimators_list = [200, 100, 50, 20]
plt.figure(figsize=(12, 4))
for i, (lr, n_est) in enumerate(zip(learning_rates, n_estimators_list)):
gb = GradientBoostingClassifier(
n_estimators=n_est,
learning_rate=lr,
max_depth=3,
random_state=42
)
gb.fit(X_train, y_train)
staged_scores = list(gb.staged_score(X_test, y_test))
plt.subplot(1, 4, i+1)
plt.plot(range(1, len(staged_scores)+1), staged_scores)
plt.xlabel('Estimators')
plt.ylabel('Accuracy')
plt.title(f'LR={lr}, n={n_est}\nFinal={staged_scores[-1]:.4f}')
plt.ylim(0.7, 1.0)
plt.grid(True, alpha=0.3)
plt.tight_layout()
plt.show()
3.4 Gradient Boosting 회귀¶
from sklearn.datasets import load_diabetes
# 데이터 로드
diabetes = load_diabetes()
X_train_r, X_test_r, y_train_r, y_test_r = train_test_split(
diabetes.data, diabetes.target, test_size=0.2, random_state=42
)
# Gradient Boosting 회귀
gb_reg = GradientBoostingRegressor(
n_estimators=100,
learning_rate=0.1,
max_depth=3,
loss='squared_error', # 'squared_error', 'absolute_error', 'huber'
random_state=42
)
gb_reg.fit(X_train_r, y_train_r)
from sklearn.metrics import mean_squared_error, r2_score
y_pred_r = gb_reg.predict(X_test_r)
print("Gradient Boosting 회귀 결과:")
print(f" MSE: {mean_squared_error(y_test_r, y_pred_r):.4f}")
print(f" RMSE: {np.sqrt(mean_squared_error(y_test_r, y_pred_r)):.4f}")
print(f" R²: {r2_score(y_test_r, y_pred_r):.4f}")
4. XGBoost¶
4.1 XGBoost 소개¶
"""
XGBoost 특징:
1. 정규화:
- L1, L2 정규화로 과적합 방지
- 목표 함수: Σ L(y_i, ŷ_i) + Σ Ω(f_k)
- Ω(f) = γT + 0.5λ||w||²
2. 효율적인 계산:
- 2차 테일러 전개 사용
- 히스토그램 기반 분할
- 캐시 최적화
3. 결측치 처리:
- 자동으로 최적 방향 학습
4. 병렬 처리:
- 특성별 병렬 분할점 탐색
"""
# pip install xgboost
import xgboost as xgb
4.2 XGBoost 기본 사용법¶
from xgboost import XGBClassifier, XGBRegressor
# XGBoost 분류기
xgb_clf = XGBClassifier(
n_estimators=100,
learning_rate=0.1,
max_depth=6,
min_child_weight=1, # 리프 노드 최소 가중치
gamma=0, # 분할에 필요한 최소 손실 감소
subsample=1.0, # 행 샘플링 비율
colsample_bytree=1.0, # 트리별 열 샘플링 비율
reg_alpha=0, # L1 정규화
reg_lambda=1, # L2 정규화
random_state=42,
use_label_encoder=False,
eval_metric='logloss'
)
xgb_clf.fit(X_train, y_train)
print("XGBoost 결과:")
print(f" 훈련 정확도: {xgb_clf.score(X_train, y_train):.4f}")
print(f" 테스트 정확도: {xgb_clf.score(X_test, y_test):.4f}")
4.3 조기 종료 (Early Stopping)¶
# 조기 종료 사용
xgb_clf_early = XGBClassifier(
n_estimators=1000,
learning_rate=0.1,
max_depth=6,
random_state=42,
early_stopping_rounds=10, # 10 라운드 동안 개선 없으면 중지
eval_metric='logloss'
)
# 검증 데이터 분리
X_train_sub, X_val, y_train_sub, y_val = train_test_split(
X_train, y_train, test_size=0.2, random_state=42
)
xgb_clf_early.fit(
X_train_sub, y_train_sub,
eval_set=[(X_val, y_val)],
verbose=False
)
print("조기 종료 결과:")
print(f" 최적 반복 횟수: {xgb_clf_early.best_iteration}")
print(f" 최적 점수: {xgb_clf_early.best_score:.4f}")
print(f" 테스트 정확도: {xgb_clf_early.score(X_test, y_test):.4f}")
4.4 XGBoost 특성 중요도¶
# 특성 중요도 타입
importance_types = ['weight', 'gain', 'cover']
fig, axes = plt.subplots(1, 3, figsize=(15, 4))
for ax, imp_type in zip(axes, importance_types):
importance = xgb_clf.get_booster().get_score(importance_type=imp_type)
if importance:
features = list(importance.keys())[:10]
values = [importance[f] for f in features]
ax.barh(range(len(features)), values)
ax.set_yticks(range(len(features)))
ax.set_yticklabels(features)
ax.set_title(f'Feature Importance ({imp_type})')
plt.tight_layout()
plt.show()
"""
중요도 타입:
- weight: 특성이 분할에 사용된 횟수
- gain: 특성 사용 시 평균 이득
- cover: 특성이 커버하는 평균 샘플 수
"""
5. LightGBM¶
5.1 LightGBM 소개¶
"""
LightGBM 특징:
1. Leaf-wise 성장:
- 기존: Level-wise (수평 분할)
- LightGBM: Leaf-wise (손실 최대 감소 리프 분할)
- 더 빠르고 정확하지만 과적합 위험
2. 히스토그램 기반 분할:
- 연속형 값을 이산화
- 메모리 효율적, 빠른 학습
3. GOSS (Gradient-based One-Side Sampling):
- 그래디언트가 큰 샘플 위주로 샘플링
4. EFB (Exclusive Feature Bundling):
- 상호 배타적 특성들을 묶음
- 희소 특성에 효과적
"""
# pip install lightgbm
import lightgbm as lgb
5.2 LightGBM 기본 사용법¶
from lightgbm import LGBMClassifier, LGBMRegressor
# LightGBM 분류기
lgb_clf = LGBMClassifier(
n_estimators=100,
learning_rate=0.1,
max_depth=-1, # -1: 제한 없음
num_leaves=31, # 리프 노드 최대 수
min_child_samples=20, # 리프 노드 최소 샘플 수
subsample=1.0, # 행 샘플링 (bagging_fraction)
colsample_bytree=1.0, # 열 샘플링
reg_alpha=0, # L1 정규화
reg_lambda=0, # L2 정규화
random_state=42,
verbose=-1
)
lgb_clf.fit(X_train, y_train)
print("LightGBM 결과:")
print(f" 훈련 정확도: {lgb_clf.score(X_train, y_train):.4f}")
print(f" 테스트 정확도: {lgb_clf.score(X_test, y_test):.4f}")
5.3 num_leaves vs max_depth¶
"""
num_leaves와 max_depth의 관계:
- max_depth = d일 때, 최대 리프 수 = 2^d
- num_leaves = 31이면 대략 max_depth = 5 수준
- 과적합 방지: num_leaves < 2^max_depth
권장 설정:
- 대용량 데이터: num_leaves = 2^max_depth - 1 이하
- 소규모 데이터: num_leaves를 작게 (15~31)
"""
# num_leaves에 따른 성능
num_leaves_range = [15, 31, 63, 127, 255]
train_scores = []
test_scores = []
for num_leaves in num_leaves_range:
lgb_temp = LGBMClassifier(
n_estimators=100,
num_leaves=num_leaves,
random_state=42,
verbose=-1
)
lgb_temp.fit(X_train, y_train)
train_scores.append(lgb_temp.score(X_train, y_train))
test_scores.append(lgb_temp.score(X_test, y_test))
plt.figure(figsize=(10, 6))
plt.plot(num_leaves_range, train_scores, 'o-', label='Train')
plt.plot(num_leaves_range, test_scores, 's-', label='Test')
plt.xlabel('num_leaves')
plt.ylabel('Accuracy')
plt.title('LightGBM: num_leaves Effect')
plt.legend()
plt.grid(True, alpha=0.3)
plt.show()
5.4 범주형 특성 처리¶
# LightGBM은 범주형 특성을 직접 처리 가능
import pandas as pd
# 예시 데이터
df = pd.DataFrame({
'num_feature': np.random.randn(1000),
'cat_feature': np.random.choice(['A', 'B', 'C', 'D'], 1000),
'target': np.random.randint(0, 2, 1000)
})
# 범주형으로 변환
df['cat_feature'] = df['cat_feature'].astype('category')
X_cat = df[['num_feature', 'cat_feature']]
y_cat = df['target']
X_train_cat, X_test_cat, y_train_cat, y_test_cat = train_test_split(
X_cat, y_cat, test_size=0.2, random_state=42
)
# LightGBM은 자동으로 범주형 처리
lgb_cat = LGBMClassifier(random_state=42, verbose=-1)
lgb_cat.fit(
X_train_cat, y_train_cat,
categorical_feature=['cat_feature']
)
print("범주형 특성 처리 결과:")
print(f" 테스트 정확도: {lgb_cat.score(X_test_cat, y_test_cat):.4f}")
6. CatBoost¶
"""
CatBoost 특징:
1. 범주형 특성 자동 처리:
- Target Encoding 자동 적용
- Ordered Target Statistics로 데이터 누수 방지
2. Ordered Boosting:
- 학습 순서를 랜덤화하여 편향 감소
- 과적합 방지
3. 대칭 트리:
- 같은 수준의 모든 노드가 동일한 분할 조건 사용
- 예측 속도 향상
"""
# pip install catboost
from catboost import CatBoostClassifier, CatBoostRegressor
# CatBoost 분류기
cat_clf = CatBoostClassifier(
iterations=100,
learning_rate=0.1,
depth=6,
l2_leaf_reg=3, # L2 정규화
random_state=42,
verbose=False
)
cat_clf.fit(X_train, y_train)
print("CatBoost 결과:")
print(f" 훈련 정확도: {cat_clf.score(X_train, y_train):.4f}")
print(f" 테스트 정확도: {cat_clf.score(X_test, y_test):.4f}")
7. 부스팅 알고리즘 비교¶
from sklearn.ensemble import AdaBoostClassifier, GradientBoostingClassifier
from xgboost import XGBClassifier
from lightgbm import LGBMClassifier
from catboost import CatBoostClassifier
import time
# 모델 정의
models = {
'AdaBoost': AdaBoostClassifier(n_estimators=100, random_state=42),
'Gradient Boosting': GradientBoostingClassifier(n_estimators=100, random_state=42),
'XGBoost': XGBClassifier(n_estimators=100, random_state=42, eval_metric='logloss'),
'LightGBM': LGBMClassifier(n_estimators=100, random_state=42, verbose=-1),
'CatBoost': CatBoostClassifier(iterations=100, random_state=42, verbose=False)
}
# 비교
print("부스팅 알고리즘 비교:")
print("-" * 60)
print(f"{'모델':<20} {'정확도':>10} {'학습시간(초)':>15}")
print("-" * 60)
results = {}
for name, model in models.items():
start_time = time.time()
model.fit(X_train, y_train)
train_time = time.time() - start_time
accuracy = model.score(X_test, y_test)
results[name] = {'accuracy': accuracy, 'time': train_time}
print(f"{name:<20} {accuracy:>10.4f} {train_time:>15.4f}")
# 시각화
fig, axes = plt.subplots(1, 2, figsize=(12, 5))
# 정확도 비교
names = list(results.keys())
accuracies = [results[n]['accuracy'] for n in names]
axes[0].barh(names, accuracies)
axes[0].set_xlabel('Accuracy')
axes[0].set_title('Accuracy Comparison')
# 학습 시간 비교
times = [results[n]['time'] for n in names]
axes[1].barh(names, times)
axes[1].set_xlabel('Training Time (seconds)')
axes[1].set_title('Training Time Comparison')
plt.tight_layout()
plt.show()
8. 하이퍼파라미터 튜닝¶
8.1 XGBoost 튜닝¶
from sklearn.model_selection import GridSearchCV, RandomizedSearchCV
from scipy.stats import uniform, randint
# XGBoost 파라미터 그리드
xgb_param_grid = {
'max_depth': [3, 5, 7],
'learning_rate': [0.01, 0.1, 0.3],
'n_estimators': [100, 200],
'min_child_weight': [1, 3, 5],
'subsample': [0.8, 1.0],
'colsample_bytree': [0.8, 1.0]
}
# Grid Search
xgb_grid = GridSearchCV(
XGBClassifier(random_state=42, eval_metric='logloss'),
xgb_param_grid,
cv=3,
scoring='accuracy',
n_jobs=-1,
verbose=1
)
xgb_grid.fit(X_train, y_train)
print("\nXGBoost Grid Search 결과:")
print(f" 최적 파라미터: {xgb_grid.best_params_}")
print(f" 최적 CV 점수: {xgb_grid.best_score_:.4f}")
print(f" 테스트 점수: {xgb_grid.score(X_test, y_test):.4f}")
8.2 LightGBM 튜닝¶
# LightGBM 파라미터 분포 (Randomized Search)
lgb_param_dist = {
'num_leaves': randint(20, 100),
'learning_rate': uniform(0.01, 0.3),
'n_estimators': randint(100, 500),
'min_child_samples': randint(10, 50),
'subsample': uniform(0.6, 0.4),
'colsample_bytree': uniform(0.6, 0.4),
'reg_alpha': uniform(0, 1),
'reg_lambda': uniform(0, 1)
}
lgb_random = RandomizedSearchCV(
LGBMClassifier(random_state=42, verbose=-1),
lgb_param_dist,
n_iter=30,
cv=3,
scoring='accuracy',
random_state=42,
n_jobs=-1
)
lgb_random.fit(X_train, y_train)
print("\nLightGBM Randomized Search 결과:")
print(f" 최적 파라미터: {lgb_random.best_params_}")
print(f" 최적 CV 점수: {lgb_random.best_score_:.4f}")
print(f" 테스트 점수: {lgb_random.score(X_test, y_test):.4f}")
8.3 Optuna를 이용한 튜닝¶
# pip install optuna
import optuna
from sklearn.model_selection import cross_val_score
def objective(trial):
params = {
'n_estimators': trial.suggest_int('n_estimators', 100, 500),
'max_depth': trial.suggest_int('max_depth', 3, 10),
'learning_rate': trial.suggest_float('learning_rate', 0.01, 0.3, log=True),
'num_leaves': trial.suggest_int('num_leaves', 20, 100),
'min_child_samples': trial.suggest_int('min_child_samples', 5, 50),
'subsample': trial.suggest_float('subsample', 0.6, 1.0),
'colsample_bytree': trial.suggest_float('colsample_bytree', 0.6, 1.0),
'reg_alpha': trial.suggest_float('reg_alpha', 0, 1),
'reg_lambda': trial.suggest_float('reg_lambda', 0, 1),
'random_state': 42,
'verbose': -1
}
model = LGBMClassifier(**params)
scores = cross_val_score(model, X_train, y_train, cv=3, scoring='accuracy')
return scores.mean()
# 최적화 실행
# study = optuna.create_study(direction='maximize')
# study.optimize(objective, n_trials=50, show_progress_bar=True)
# print(f"최적 파라미터: {study.best_params}")
# print(f"최적 점수: {study.best_value:.4f}")
9. 과적합 방지 전략¶
"""
부스팅 과적합 방지 전략:
1. 조기 종료:
- early_stopping_rounds 사용
- 검증 손실이 개선되지 않으면 중지
2. 정규화:
- L1 (reg_alpha, lambda_l1)
- L2 (reg_lambda, lambda_l2)
3. 샘플링:
- subsample (행 샘플링)
- colsample_bytree (열 샘플링)
4. 트리 제한:
- max_depth (깊이 제한)
- min_samples_leaf / min_child_weight
5. 학습률 조절:
- learning_rate 낮추기
- n_estimators 늘리기
"""
# 정규화 효과 비교
reg_params = [
{'reg_alpha': 0, 'reg_lambda': 0},
{'reg_alpha': 0.1, 'reg_lambda': 0},
{'reg_alpha': 0, 'reg_lambda': 1},
{'reg_alpha': 0.1, 'reg_lambda': 1}
]
print("정규화 효과:")
for params in reg_params:
xgb_temp = XGBClassifier(
n_estimators=100,
max_depth=10, # 깊은 트리
random_state=42,
eval_metric='logloss',
**params
)
xgb_temp.fit(X_train, y_train)
train_acc = xgb_temp.score(X_train, y_train)
test_acc = xgb_temp.score(X_test, y_test)
print(f" alpha={params['reg_alpha']}, lambda={params['reg_lambda']}: "
f"Train={train_acc:.4f}, Test={test_acc:.4f}")
10. HistGradientBoosting (sklearn)¶
from sklearn.ensemble import HistGradientBoostingClassifier, HistGradientBoostingRegressor
"""
sklearn의 HistGradientBoosting:
- sklearn 1.0부터 정식 지원
- LightGBM과 유사한 히스토그램 기반 알고리즘
- 대용량 데이터에 효율적
- 결측치 자동 처리
"""
hgb_clf = HistGradientBoostingClassifier(
max_iter=100,
learning_rate=0.1,
max_depth=None,
max_leaf_nodes=31,
min_samples_leaf=20,
l2_regularization=0,
early_stopping='auto', # 자동 조기 종료
random_state=42
)
hgb_clf.fit(X_train, y_train)
print("HistGradientBoosting 결과:")
print(f" 훈련 정확도: {hgb_clf.score(X_train, y_train):.4f}")
print(f" 테스트 정확도: {hgb_clf.score(X_test, y_test):.4f}")
연습 문제¶
문제 1: XGBoost 분류¶
유방암 데이터로 XGBoost를 학습하고 조기 종료를 적용하세요.
from sklearn.datasets import load_breast_cancer
from xgboost import XGBClassifier
cancer = load_breast_cancer()
X_train, X_test, y_train, y_test = train_test_split(
cancer.data, cancer.target, test_size=0.2, random_state=42
)
# 풀이
X_tr, X_val, y_tr, y_val = train_test_split(
X_train, y_train, test_size=0.2, random_state=42
)
xgb = XGBClassifier(
n_estimators=500,
learning_rate=0.05,
early_stopping_rounds=20,
eval_metric='logloss',
random_state=42
)
xgb.fit(X_tr, y_tr, eval_set=[(X_val, y_val)], verbose=False)
print(f"최적 반복 횟수: {xgb.best_iteration}")
print(f"테스트 정확도: {xgb.score(X_test, y_test):.4f}")
문제 2: LightGBM 하이퍼파라미터 튜닝¶
Grid Search로 LightGBM 최적 파라미터를 찾으세요.
from lightgbm import LGBMClassifier
from sklearn.model_selection import GridSearchCV
param_grid = {
'num_leaves': [15, 31, 63],
'learning_rate': [0.05, 0.1],
'n_estimators': [100, 200]
}
# 풀이
grid = GridSearchCV(
LGBMClassifier(random_state=42, verbose=-1),
param_grid,
cv=3,
scoring='accuracy',
n_jobs=-1
)
grid.fit(X_train, y_train)
print(f"최적 파라미터: {grid.best_params_}")
print(f"최적 점수: {grid.best_score_:.4f}")
print(f"테스트 점수: {grid.score(X_test, y_test):.4f}")
문제 3: 앙상블 비교¶
여러 부스팅 알고리즘을 비교하세요.
from sklearn.ensemble import GradientBoostingClassifier
from xgboost import XGBClassifier
from lightgbm import LGBMClassifier
models = {
'GB': GradientBoostingClassifier(n_estimators=100, random_state=42),
'XGB': XGBClassifier(n_estimators=100, random_state=42, eval_metric='logloss'),
'LGB': LGBMClassifier(n_estimators=100, random_state=42, verbose=-1)
}
# 풀이
for name, model in models.items():
model.fit(X_train, y_train)
print(f"{name}: {model.score(X_test, y_test):.4f}")
요약¶
| 알고리즘 | 특징 | 장점 | 단점 |
|---|---|---|---|
| AdaBoost | 가중치 기반 | 간단, 해석 용이 | 노이즈에 민감 |
| Gradient Boosting | 잔차 학습 | 높은 정확도 | 느린 학습 |
| XGBoost | 정규화 + 병렬화 | 빠름, 정확함 | 메모리 사용 |
| LightGBM | Leaf-wise | 매우 빠름, 대용량 | 과적합 위험 |
| CatBoost | 범주형 처리 | 튜닝 적게 필요 | 느린 시작 |
하이퍼파라미터 가이드¶
| 파라미터 | XGBoost | LightGBM | 효과 |
|---|---|---|---|
| 학습률 | learning_rate | learning_rate | 낮으면 안정적 |
| 트리 수 | n_estimators | n_estimators | 많으면 정확 |
| 깊이 | max_depth | max_depth | 깊으면 복잡 |
| 리프 수 | - | num_leaves | 많으면 복잡 |
| L1 정규화 | reg_alpha | reg_alpha | 과적합 방지 |
| L2 정규화 | reg_lambda | reg_lambda | 과적합 방지 |
| 행 샘플링 | subsample | subsample | 분산 감소 |
| 열 샘플링 | colsample_bytree | colsample_bytree | 다양성 증가 |