Условие
Какие самые частые источники утечки данных (data leakage) при построении ML-модели и как их избежать?
Решение
Подход
Утечка = в train или val попала информация, недоступная в production на момент предсказания. Симптом — нереально хорошая val метрика.
Типичные источники.
-
Препроцессинг до split.
- Подогнать
StandardScaler.fitна всех данных, потом split. Скейлер «знал» val-распределение. SelectKBestпо корреляции с таргетом по всему датасету — отбор фичей подсматривает val-таргеты.- Решение: всё, что fit-ится — внутри
Pipeline, и fit только на train фолде.
- Подогнать
-
Target encoding.
- Закодировать категорию средним таргетом по всему датасету — мощная утечка. Особенно ярко проявляется на редких категориях.
- Решение: out-of-fold encoding (для каждой train-строки таргет считается по другим фолдам).
-
Информация из будущего.
- Признак
last_login_in_30_daysна дату предсказания, посчитанный с использованием логов, которых в момент предсказания ещё не было. - Решение: «point-in-time correctness» — для каждой строки train считать признаки только из данных до её timestamp.
- Признак
-
Identity leak.
- В CV пользователь оказался и в train, и в val (если объект = транзакция, а строки независимы по user). Модель учится узнавать пользователя, а не задачу.
- Решение:
GroupKFoldпо user_id.
-
Дубликаты между train и test.
- Например, два почти одинаковых текста.
- Решение: дедупликация и near-duplicate detection до split.
-
Метка-следствие.
- В фичах есть переменная, которая физически появляется после таргета (например, «сумма страховой выплаты» в задаче «будет ли страховой случай»).
- Решение: ревью списка фичей с доменным экспертом.
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")Подводные камни
- «AUC 0.99 — мы гениальны» — почти всегда утечка.
- Target encoding без OOF даёт огромный буст оффлайн и плоский результат в проде.
- Случайный split на временных данных — гарантированная утечка через будущее.
- Leak через ID-токены: даже хэш пользователя может выдать таргет, если он не равномерно распределён.
Эталонный ответ
Утечка — это любая информация в train/val, недоступная на проде. Чаще всего: препроцессинг до split, target encoding без OOF, временные сплиты в случайном порядке, перекрытие пользователей между train и val. Лекарство: всё fit-ить только на train-фолде через Pipeline, временные сплиты делать по дате, использовать GroupKFold для зависимых наблюдений.