Какие способы кодирования категориальных признаков вы знаете и как выбрать подходящий?
Короткий ответ
- One-hot: просто и честно, но раздувает размерность
- Label/ordinal encoding — только для порядковых категорий
- Target encoding мощен, но опасен утечкой
- Частотное кодирование — счётчики встречаемости категории
- Высококардинальные признаки: хэширование или эмбеддинги
- CatBoost кодирует категории сам, упорядоченно
- Новые категории в проде нужно обрабатывать явно
Выбор кодирования зависит от кардинальности, типа модели и риска утечки: one-hot для малых словарей, target encoding с регуляризацией или встроенные механизмы бустингов для больших.
Как сказать вслух
пример ответаДля небольшого числа категорий я обычно беру one-hot — он честный и понятный. Порядковое кодирование использую только там, где у категорий есть естественный порядок. Для признаков с тысячами значений хорошо работает target encoding — заменяем категорию средним таргетом, но его обязательно считать аккуратно, на кросс-валидации, иначе утечём. А если работаю с CatBoost, часто отдаю категории ему как есть.
Подробный ответ
Основной ответ
Основные приёмы: one-hot encoding — бинарный столбец на категорию, хорош для линейных моделей и малой кардинальности, но взрывает размерность; ordinal/label encoding — подходит только для упорядоченных категорий (размер, грейд), иначе навязывает модели ложный порядок (хотя деревья к этому терпимее); frequency encoding — замена категории её частотой; target encoding — замена средним значением таргета по категории, мощен для высокой кардинальности, но требует защиты от утечки: сглаживание к глобальному среднему и вычисление по out-of-fold схеме. Для очень больших словарей — feature hashing или обучаемые эмбеддинги в нейросетях. CatBoost применяет ordered target statistics из коробки. Отдельно продумывают обработку редких и новых категорий: группа «other» и дефолтное значение в проде.
Ключевые моменты
- Модель диктует выбор. Линейным моделям нужен one-hot, деревья переваривают ordinal, бустинги умеют свои счётчики.
- Target encoding без утечки. Считать только по train-части фолда, сглаживать по размеру категории; наивная версия по всей выборке — классическая утечка.
- Высокая кардинальность. Тысячи значений: target/frequency encoding, хэширование или эмбеддинги вместо one-hot.
- Прод-устойчивость. Новые и редкие категории должны иметь явный fallback, иначе пайплайн упадёт или выдаст мусор.
Практический контекст
Практический вопрос: интервьюер проверяет не словарь терминов, а понимание последствий — что будет с one-hot на признаке «город» с десятью тысячами значений, как не утечь с target encoding. Это ежедневная рутина табличного ML; грамотная обработка категорий часто даёт больше прироста качества, чем смена модели. Хорошо прозвучит опыт сравнения кодировок на конкретной задаче.
Пример кода
import pandas as pd
from sklearn.model_selection import KFold
# Target encoding без утечки: out-of-fold среднее со сглаживанием
def target_encode(df, col, target, n_splits=5, alpha=10):
global_mean = df[target].mean()
encoded = pd.Series(index=df.index, dtype=float)
for tr_idx, val_idx in KFold(n_splits, shuffle=True, random_state=42).split(df):
tr = df.iloc[tr_idx]
stats = tr.groupby(col)[target].agg(["mean", "count"])
smooth = (stats["mean"] * stats["count"] + global_mean * alpha) / (
stats["count"] + alpha
)
encoded.iloc[val_idx] = df.iloc[val_idx][col].map(smooth).fillna(global_mean)
return encoded
df["city_te"] = target_encode(df, "city", "churn")Частые ошибки
- Применяют label encoding к неупорядоченным категориям для линейной модели
- Считают target encoding по всей выборке и получают утечку
- Забывают про обработку новых категорий, появляющихся после обучения