Sobes.tech
Назад к вопросам
Middle — Senior
11

Чем CatBoost отличается от XGBoost при работе с категориальными признаками?

Компании, где спрашивали
Hybrid

Ответ от нейросети

sobes.tech AI

Что хотят услышать интервьюеры:

CatBoost из коробки умеет работать с категориальными признаками и делает это через специальные схемы кодирования, снижая риск утечки таргета. XGBoost исторически ожидает числовые признаки, поэтому категориальные обычно приходится предварительно кодировать вручную. На практике CatBoost часто проще и безопаснее для табличных данных с большим числом категорий, а XGBoost требует больше подготовки данных и контроля за encoding.

Определение:

CatBoost и XGBoost — это алгоритмы градиентного бустинга по деревьям, но они по-разному обрабатывают категориальные признаки.

CatBoost нативно поддерживает категориальные фичи: ему можно передать их как категории, и он сам использует внутренние методы преобразования. Это удобно и уменьшает вероятность переобучения на целевой переменной при кодировании.

XGBoost работает в первую очередь с числовыми признаками. Категориальные данные обычно нужно перевести в числовой вид заранее, например one-hot encoding, target encoding или ordinal encoding. Это дает больше контроля, но и больше ответственности за качество преобразования.

Пример использования:

Допустим, есть данные о покупке товара: city, device_type, product_category, price, target.

Для CatBoost можно передать city, device_type, product_category как категориальные признаки почти без ручного кодирования.

Для XGBoost обычно сначала делают преобразование:

import pandas as pd
from sklearn.model_selection import train_test_split
from sklearn.preprocessing import OneHotEncoder
from sklearn.compose import ColumnTransformer
from sklearn.pipeline import Pipeline
from xgboost import XGBClassifier
from sklearn.metrics import roc_auc_score

df = pd.DataFrame({
    "city": ["Moscow", "SPb", "Moscow", "Kazan"],
    "device_type": ["mobile", "desktop", "mobile", "tablet"],
    "price": [100, 200, 150, 120],
    "target": [1, 0, 1, 0]
})

X = df[["city", "device_type", "price"]]
y = df["target"]

cat_cols = ["city", "device_type"]
num_cols = ["price"]

preprocessor = ColumnTransformer([
    ("cat", OneHotEncoder(handle_unknown="ignore"), cat_cols),
    ("num", "passthrough", num_cols)
])

model = Pipeline([
    ("prep", preprocessor),
    ("clf", XGBClassifier(use_label_encoder=False, eval_metric="logloss"))
])

model.fit(X, y)

Пояснение кода:

Код показывает типичный путь для XGBoost: категориальные признаки сначала преобразуются в one-hot, затем модель обучается на уже числовой матрице.

Шаги такие:

  1. Данные разбиваются на признаки X и целевую переменную y.
  2. Категориальные колонки перечисляются отдельно.
  3. OneHotEncoder превращает каждую категорию в набор бинарных столбцов.
  4. ColumnTransformer объединяет обработку категориальных и числовых признаков.
  5. Pipeline связывает препроцессинг и модель в один объект.
  6. XGBClassifier получает только числовые данные.

Для CatBoost код выглядел бы проще: категориальные колонки можно передать напрямую, указав их индексы или имена, а сам CatBoost выполнит внутреннюю обработку.

Ключевые моменты:

  • CatBoost нативно поддерживает категориальные признаки, XGBoost — обычно нет.
  • CatBoost снижает риск leakage за счет специальных схем кодирования категорий.
  • С XGBoost чаще нужен ручной preprocessing: one-hot, target encoding или другие методы.
  • CatBoost обычно удобнее и сильнее на табличных данных с большим числом категорий.
  • XGBoost дает гибкость, но качество сильно зависит от выбранного encoding.
  • В реальных задачах выбор часто сводится к компромиссу между удобством, скоростью и качеством на конкретном датасете.