Условие
Выберите стратегию валидации для каждого случая:
- Прогноз дневной выручки на 7 дней вперёд.
- Классификация фотографий собак по породе (10000 фото, 50 пород).
- Антифрод: 0.5% положительных, 50 млн строк, дрейф паттернов мошенничества.
- Recommender system: предсказать клики на следующей неделе.
- Группы данных: 1000 пациентов с 10 МРТ каждый — предсказать диагноз.
Решение
Стратегии
| Стратегия | Когда |
|---|---|
| K-Fold | iid данные, классическая задача |
| Stratified K-Fold | классификация, дисбаланс |
| Group K-Fold | есть «группы» (пациент, пользователь), данные внутри группы коррелированы |
| Time-Series Split (rolling/expanding) | временная зависимость, нельзя «подсмотреть будущее» |
| Stratified Group K-Fold | группы + дисбаланс |
| Leave-One-Group-Out | мало групп, важно протестировать на каждой |
| Nested CV | гиперпараметры + честная оценка ошибки |
По кейсам
1. Прогноз выручки (7 дней): Time-Series Split с expanding window. Никогда не shuffle — обучение на прошлом, оценка на будущем. Обязательно gap = горизонт прогноза, чтобы не смотреть в фичи из будущего.
from sklearn.model_selection import TimeSeriesSplit
tscv = TimeSeriesSplit(n_splits=5, test_size=7, gap=0)2. Породы собак (10К фото, 50 классов): Stratified K-Fold (k=5) — балансировать классы в фолдах (некоторые породы редкие, выпадут в один фолд). Если фото взяты с одного источника (Instagram пользователя) — добавить Group K-Fold.
3. Антифрод (50M строк, 0.5%, дрейф): Time-Series Split + Stratified. Мошенничество меняется во времени — нельзя валидироваться на «прошлом». 5 фолдов с rolling-окном (train: 60 дней, val: 7 дней). Дополнительно out-of-time test на последних 30 днях (никогда не участвуют в обучении).
4. Рекоммендер: Time-Based split + leave-future-out. Train: до недели N. Val: неделя N. Test: неделя N+1. Внутри пользователя — без shuffle. Метрики: NDCG@k, Recall@k на последней неделе. Доп. вариант — leave-one-out per user (последний клик в test), но дороже.
5. МРТ пациентов:
Group K-Fold по patient_id — никогда не должно быть так, что МРТ одного пациента в train и в val. Иначе модель «запомнит» пациента, а не научится диагностировать.
from sklearn.model_selection import GroupKFold
gkf = GroupKFold(n_splits=5)
for tr, va in gkf.split(X, y, groups=patient_ids):
...Nested CV
Если делать grid-search и репортить честный score:
from sklearn.model_selection import GridSearchCV, cross_val_score
outer_cv = StratifiedKFold(5, shuffle=True, random_state=0)
inner_cv = StratifiedKFold(3, shuffle=True, random_state=0)
gs = GridSearchCV(estimator, param_grid, cv=inner_cv)
scores = cross_val_score(gs, X, y, cv=outer_cv)
print("Unbiased CV:", scores.mean(), "±", scores.std())Leakage-чеклист
- Target leakage: фича вычислена с использованием target.
- Train-test contamination: фичи, посчитанные на полном датасете до сплита (
StandardScaler.fit(X)до сплита). - Group leakage: разные строки одного пациента/пользователя в train и val.
- Temporal leakage: окно агрегации фичи захватывает будущее относительно target.
Подводные камни
shuffle=Trueдля временных рядов — катастрофа: модель «подсматривает» в будущее.- Stratified без
random_state— фолды непрозрачно меняются между запусками. - Scaler / encoder fit на all data — leakage.
Pipelineрешает это. - K=5 vs K=10: K=10 даёт меньше bias оценки, но дороже. На больших данных K=5 ок.
- CV-score падает на test — обычно leakage в фичах или нарушение группировки.
- Out-of-time для антифрода обязателен: CV-AUC может быть 0.95, OOT-AUC = 0.70 из-за дрейфа.
- Stratify в Time-Series Split — нет нативного, но можно делать stratified внутри окна вручную.
Эталонный ответ
- Выручка — Time-Series Split, expanding/rolling, без shuffle.
- Собаки — Stratified K-Fold; если есть «источник» — Group K-Fold поверх.
- Антифрод — Time-Series + Stratified + Out-of-Time test (учитывать дрейф).
- Рекоммендер — Time-Based split, метрики на следующей неделе.
- МРТ пациентов — Group K-Fold по
patient_id.
Общие правила: никогда не shuffle временные данные; всегда уважать группировку; fit препроцессинга — только на train (через Pipeline); для честной оценки гиперов — nested CV.