Data leakage простыми словами
Карьерник — квиз-тренажёр в Telegram с 1500+ вопросами для собесов аналитика. SQL, Python, A/B, метрики. Бесплатно.
Зачем это знать
Data leakage — главный враг ML-модели в production. Симптом: на train accuracy 99%, на prod 60%. Обидно, непонятно, и причина почти всегда — утечка данных. Вы случайно добавили в features информацию, которой не будет в момент реального предсказания.
Собеседования на middle+ DS роли — data leakage топ-3 тема. «Расскажите о реальном случае», «как обнаружили», «как избежали». Умение распознавать leakage — отличительная черта senior от middle.
В статье:
- Что такое data leakage
- Классические примеры (target leakage, train/test leakage)
- Как обнаружить (слишком хорошие метрики → подозрение)
- Как избежать (proper split, pipeline, time-aware CV)
- Кейсы из реального мира
Короткое объяснение
Data leakage — модель видит в train информацию, которой в реальном production не будет. Результат: идеальные метрики на train, provал в prod.
Классический пример
Предсказываем churn (ушёл ли клиент). В feature попадает last_login_date.
Leakage: клиенты, которые churn-нулись, имеют last_login за несколько недель до churn-date. Модель выучит: «давний last_login → churn». На train работает идеально.
В production применяем: сегодня — last_login_date = вчера. Модель говорит: «не churn». Но мы не знаем, что будет через месяц. Модель бесполезна.
Два типа leakage
1. Target leakage
Feature содержит информацию о target.
Примеры:
- В churn prediction: колонка
churn_dateили её производные - В loan default prediction:
insurance_paid— но insurance paid только если default наступил - В fraud detection:
account_closed(закрываем после детекции)
2. Train/test contamination
Информация из test просочилась в train.
Примеры:
StandardScaler.fit()на всём dataset (включая test) перед split- Feature engineering использует global statistics (mean, max) из всего dataset
- Duplicated rows в train и test одновременно
Признаки leakage
1. Слишком хорошие метрики
Accuracy 99%, AUC 0.99 — для сложной задачи. Подозрительно.
2. Performance не переносится в prod
Train AUC 0.95, production AUC 0.6 — гигантский gap.
3. Top-feature неожиданно важный
Feature importance показывает 90% веса на одну колонку, которая «не должна быть так важна».
4. Timeline inconsistency
В features есть информация из будущего относительно target.
Как избежать
1. Правильный split перед preprocessing
# неправильно: global normalization перед split
scaler = StandardScaler()
X_scaled = scaler.fit_transform(X)
X_train, X_test = train_test_split(X_scaled)
# правильно: scaler только на train
X_train, X_test = train_test_split(X)
scaler = StandardScaler()
scaler.fit(X_train)
X_train_s = scaler.transform(X_train)
X_test_s = scaler.transform(X_test) # только transform, не fit!2. Pipeline
from sklearn.pipeline import Pipeline
from sklearn.preprocessing import StandardScaler
from sklearn.ensemble import RandomForestClassifier
pipe = Pipeline([
('scaler', StandardScaler()),
('model', RandomForestClassifier())
])
pipe.fit(X_train, y_train) # всё в pipeline, без leakageВ cross_val_score(pipe, X, y) scaler обучится только на train fold.
3. Time-aware split
Для time series — обучаться на прошлом, тестировать на будущем:
# правильно
X_train = X[X['date'] < '2026-01-01']
X_test = X[X['date'] >= '2026-01-01']Не random split!
4. Feature audit
Для каждой feature спросите: «в момент предсказания эта информация будет доступна?». Если нет → leakage.
5. Sanity check
Train model. Посмотреть feature importances. Есть ли там что-то «слишком важное»?
Примеры из реальной жизни
Kaggle: предсказание отмены бронирования
Feature booking_cancel_reason — заполнено только для отменённых. Target — «отменили / нет». 100% accuracy. Все участники хлопали в ладоши, пока не поняли leakage.
Medical: предсказание заболевания
В features — номер страховой компании. Оказалось, одна компания обслуживает только диабетиков. Модель выучила «эта компания = диабет». В другом регионе — мусор.
Ecom: prediction покупки
Feature days_since_last_purchase. Для покупателей ≥ 1 — посчитано. Для никогда не покупавших — NaN (заполнено 0). Модель выучила: «0 days → новый user → не купит» (но с другими причинами).
Time series leakage
Особенно коварный. Типичные ошибки:
- Rolling mean, включающее будущее
- Forward fill NaN после target-event
- Label с «будущим знанием» в features
На собесе
«Что такое data leakage?» Модель видит в train то, что не будет доступно в prod.
«Пример из вашей практики?» Приготовьте один свой реальный или из книжки (Andrew Ng).
«Как бы проверили модель на leakage?» Audit features, check для «too good» metrics, test on holdout от другого периода.
«Почему StandardScaler перед split плохо?» Mean и std считаются с учётом test → инфа из test утекла в train.
Частые ошибки
1. Global feature engineering
df['mean_price_per_user'] = df.groupby('user_id')['price'].transform('mean') — включает future rows.
2. Leaky imputation
df.fillna(df.mean()) перед split — global mean включает test.
3. Window без time awareness
# неправильно
df['7d_avg'] = df['value'].rolling(7).mean() # может включать future
# правильно (time-aware)
df = df.sort_values('date')
df['7d_avg'] = df['value'].rolling(7).mean().shift(1) # сдвиг на 14. Duplicated data
Пользователь попал в train и в test — модель «вспоминает».
Связанные темы
FAQ
Target leakage всегда очевиден?
Нет. Может быть subtle (например, feature эффект сильно связан с тем, как label создаётся).
Как найти leakage в готовой модели?
Audit features → test на holdout из совершенно нового периода → feature importances check.
Pipeline спасает от всех leakage?
От preprocessing leakage — да. От target leakage — нет.
DVC / MLflow помогают?
Они track эксперименты, но leakage — code-level issue. Только careful review.
Тренируйте ML — откройте тренажёр с 1500+ вопросами для собесов.