CatBoost
(Categorical Boosting)
범주형 데이터의 왕 — 목표 누수 없는 인코딩, 대칭 트리, 순서형 부스팅으로 완전 정복
목차
CatBoost의 탄생 — 범주형 문제의 해결사
XGBoost와 LightGBM은 강력하지만 범주형 특성을 처리하려면 원-핫 인코딩이나 레이블 인코딩 등 별도 전처리가 필요합니다. 고유값이 많은 범주형 특성(high-cardinality categorical features)에서는 이 과정이 매우 번거롭고, 잘못되면 목표 누수(Target Leakage)가 발생합니다.
Yandex가 2018년 공개한 CatBoost(Categorical Boosting)는 이 문제를 알고리즘 수준에서 해결합니다. 범주형 특성을 수치로 인코딩하는 과정에서 발생하는 편향을 원천 차단하는 새로운 방법론을 제안했습니다.
범주형 전처리 불필요
범주형 특성을 문자열로 직접 입력할 수 있습니다. 인코딩을 알고리즘이 자동 처리합니다.
목표 누수 방지
순서형 인코딩으로 학습 시 목표값 정보가 인코딩에 누수되는 것을 원천 방지합니다.
대칭 트리
대칭 구조 트리로 예측이 빠르고 과적합 방지에 유리합니다.
하이퍼파라미터 기본값 우수
기본 파라미터만으로도 경쟁력 있는 성능을 보입니다. 튜닝 부담이 적습니다.
목표 통계량 인코딩과 목표 누수 문제
범주형 특성을 수치로 변환하는 가장 효과적인 방법 중 하나는 목표 통계량(Target Statistics, TS)을 사용하는 것입니다. 각 범주에 해당하는 샘플들의 타겟값 평균을 사용합니다:
그런데 이 방식에는 치명적 문제가 있습니다. 샘플 xᵢ의 인코딩에 yᵢ 자신의 값이 포함됩니다. 이것이 목표 누수(Target Leakage)입니다. 모델이 훈련 데이터에서 타겟 정보를 직접 "들여다보게" 되어 과적합이 발생하고, 테스트 데이터에서 성능이 급락합니다.
순서형 목표 통계량 (Ordered TS)
CatBoost의 핵심 혁신은 순서형 원칙(Ordering Principle)을 적용한 목표 통계량입니다. 데이터를 무작위로 순열(permutation)하고, 샘플 xᵢ를 인코딩할 때 순열에서 자신보다 앞에 오는 샘플들만을 사용합니다:
a는 평활 파라미터, p는 전체 타겟 평균입니다. 자기 자신(yᵢ)은 절대 포함되지 않으므로 목표 누수가 원천 차단됩니다.
순서형 부스팅 (Ordered Boosting)
CatBoost는 목표 통계량뿐만 아니라 부스팅 과정 자체에도 순서형 원칙을 적용합니다. 기존 그래디언트 부스팅의 예측 편향 문제를 해결합니다.
기존 GBM에서는 m번째 트리를 학습할 때 1~(m-1)번 트리의 예측 잔차를 사용하는데, 이 잔차를 계산할 때 사용된 모델이 해당 샘플을 학습에 사용했으므로 잔차가 편향됩니다. CatBoost는 각 샘플의 잔차를 해당 샘플 없이 학습된 모델로 계산해 이 편향을 제거합니다.
대칭 트리 (Oblivious Trees)
CatBoost는 대칭 트리(Oblivious Trees) 구조를 사용합니다. 일반 결정 트리와 달리, 각 깊이(레벨)에서 모든 노드가 동일한 분기 조건을 사용합니다.
일반 트리 vs 대칭 트리 구조 비교
특성 조합 자동 생성
CatBoost는 학습 과정에서 범주형 특성들의 조합(combination)을 자동으로 생성합니다. 예를 들어 '도시'와 '직업' 두 범주형 특성이 있으면, '서울+개발자', '부산+디자이너' 같은 조합 특성을 자동으로 만들어 모델에 추가합니다.
이 조합 특성도 Ordered TS로 인코딩되며, max_ctr_complexity 파라미터로 최대 조합 길이를 제어합니다.
XGBoost vs LightGBM vs CatBoost
| 항목 | XGBoost | LightGBM | CatBoost |
|---|---|---|---|
| 트리 구조 | Level-wise | Leaf-wise | 대칭 트리 |
| 범주형 처리 | 수동 필요 | 정수 후 직접 | 문자열 직접 입력 |
| 목표 누수 | 인코딩 따라 다름 | 인코딩 따라 다름 | 원천 방지 |
| 학습 속도 | 보통 | 가장 빠름 | 보통~빠름 |
| 예측 속도 | 빠름 | 빠름 | 가장 빠름 (대칭 트리) |
| 소규모 데이터 | 안정 | 과적합 주의 | 안정 |
| GPU 지원 | 지원 | 지원 | 빠름 |
| 기본값 성능 | 좋음 | 좋음 | 매우 좋음 |
| 특성 조합 | 수동 | 수동 | 자동 생성 |
주요 하이퍼파라미터
| 파라미터 | 설명 | 기본값 / 권장 |
|---|---|---|
iterations | 트리 수 (n_estimators와 동일) | 1000 |
learning_rate | 학습률. 작을수록 안정적 | 0.03 |
depth | 대칭 트리의 깊이 | 6 (4~10) |
l2_leaf_reg | L2 정규화 (XGBoost의 lambda) | 3.0 |
cat_features | 범주형 특성 인덱스/이름 목록 | 자동 탐지 가능 |
max_ctr_complexity | 최대 특성 조합 길이 | 4 |
border_count | 수치 특성 히스토그램 빈 수 | 254 |
od_type | 조기 종료 타입 ('Iter'/'IncToDec') | 'Iter' |
task_type | 'CPU' 또는 'GPU' | 'CPU' |
Python 구현 예제
from sklearn.model_selection import train_test_split
from sklearn.metrics import roc_auc_score
import pandas as pd
# 1. 데이터 (범주형 특성 포함 예시)
df = pd.read_csv('data.csv')
cat_cols = ['city', 'job', 'product_type']
X = df.drop('target', axis=1)
y = df['target']
X_train, X_test, y_train, y_test = train_test_split(X, y, 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.15)
# 2. Pool 객체 생성 — 범주형 특성 명시
train_pool = Pool(X_tr, y_tr, cat_features=cat_cols)
val_pool = Pool(X_val, y_val, cat_features=cat_cols)
test_pool = Pool(X_test, cat_features=cat_cols)
# 3. 모델 학습
model = CatBoostClassifier(
iterations=500,
learning_rate=0.05,
depth=6,
l2_leaf_reg=3.0,
eval_metric='AUC',
random_seed=42,
verbose=50
)
model.fit(
train_pool,
eval_set=val_pool,
early_stopping_rounds=30
)
# 4. 평가
y_proba = model.predict_proba(test_pool)[:, 1]
print(f"AUC-ROC: {roc_auc_score(y_test, y_proba):.4f}")
수치형 데이터에서 sklearn API 사용
X, y = load_breast_cancer(return_X_y=True)
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.2)
clf = CatBoostClassifier(
iterations=300, learning_rate=0.05,
depth=6, verbose=0
)
clf.fit(X_train, y_train)
print(f"정확도: {clf.score(X_test, y_test):.4f}")
# 특성 중요도
imp = clf.get_feature_importance()
print(f"상위 3개 특성: {imp.argsort()[::-1][:3]}")
댓글