Собесов

alexeygrigorev: где обычно зарыто переобучение через утечку фичей

ML / Data ScienceПодготовка данныхСредняяMiddle

Условие

Какие самые частые источники утечки данных (data leakage) при построении ML-модели и как их избежать?

Решение

Подход

Утечка = в train или val попала информация, недоступная в production на момент предсказания. Симптом — нереально хорошая val метрика.

Типичные источники.

  1. Препроцессинг до split.

    • Подогнать StandardScaler.fit на всех данных, потом split. Скейлер «знал» val-распределение.
    • SelectKBest по корреляции с таргетом по всему датасету — отбор фичей подсматривает val-таргеты.
    • Решение: всё, что fit-ится — внутри Pipeline, и fit только на train фолде.
  2. Target encoding.

    • Закодировать категорию средним таргетом по всему датасету — мощная утечка. Особенно ярко проявляется на редких категориях.
    • Решение: out-of-fold encoding (для каждой train-строки таргет считается по другим фолдам).
  3. Информация из будущего.

    • Признак last_login_in_30_days на дату предсказания, посчитанный с использованием логов, которых в момент предсказания ещё не было.
    • Решение: «point-in-time correctness» — для каждой строки train считать признаки только из данных до её timestamp.
  4. Identity leak.

    • В CV пользователь оказался и в train, и в val (если объект = транзакция, а строки независимы по user). Модель учится узнавать пользователя, а не задачу.
    • Решение: GroupKFold по user_id.
  5. Дубликаты между train и test.

    • Например, два почти одинаковых текста.
    • Решение: дедупликация и near-duplicate detection до split.
  6. Метка-следствие.

    • В фичах есть переменная, которая физически появляется после таргета (например, «сумма страховой выплаты» в задаче «будет ли страховой случай»).
    • Решение: ревью списка фичей с доменным экспертом.
from sklearn.pipeline import Pipeline
from sklearn.preprocessing import StandardScaler
from sklearn.linear_model import LogisticRegression
from sklearn.model_selection import GroupKFold, cross_val_score
 
pipe = Pipeline([
    ("scaler", StandardScaler()),  # fit только на train-фолде
    ("clf",    LogisticRegression()),
])
 
scores = cross_val_score(pipe, X, y, groups=user_ids, cv=GroupKFold(5), scoring="roc_auc")

Подводные камни

  1. «AUC 0.99 — мы гениальны» — почти всегда утечка.
  2. Target encoding без OOF даёт огромный буст оффлайн и плоский результат в проде.
  3. Случайный split на временных данных — гарантированная утечка через будущее.
  4. Leak через ID-токены: даже хэш пользователя может выдать таргет, если он не равномерно распределён.

Эталонный ответ

Утечка — это любая информация в train/val, недоступная на проде. Чаще всего: препроцессинг до split, target encoding без OOF, временные сплиты в случайном порядке, перекрытие пользователей между train и val. Лекарство: всё fit-ить только на train-фолде через Pipeline, временные сплиты делать по дате, использовать GroupKFold для зависимых наблюдений.

Хочешь увидеть разбор?

Зарегистрируйся бесплатно — откроется развёрнутое решение этой задачи и ещё 4 на выбор.

Зарегистрироваться и увидеть разбор
Уже есть аккаунт? Войти