Как делить данные на страты для валидации
Что проверяют
Понимаете ли вы, зачем стратифицируют: чтобы каждая часть разбиения повторяла распределение важного признака, и оценка качества не прыгала от фолда к фолду. Следом обычно спрашивают, как стратифицировать регрессию и что делать, если в данных есть группы, например несколько записей одного клиента.
Как отвечать
Базовый случай это классификация с дисбалансом. При 2% положительного класса случайное разбиение легко даёт тест с 1% и фолд с 3%, и метрики между ними несравнимы.
train_test_split(..., stratify=y): доли классов в обучении и тесте совпадают с исходными;StratifiedKFold: то же для кросс-валидации.cross_val_scoreс целымcvу классификатора и так использует его по умолчанию.shuffleпо умолчаниюFalse, приTrueзадайтеrandom_state;- регрессия: целевую переменную режут на квантильные корзины через
pd.qcut(y, 10, labels=False)и стратифицируют по номеру корзины; - несколько признаков: склеивают составной ключ, например класс плюс регион, и следят, чтобы в каждой страте хватало объектов;
- группы:
StratifiedGroupKFoldдержит все записи одного клиента в одном фолде и при этом старается сохранить доли классов; - мультилейбл: обычная стратификация не подходит, используют итеративную, например
IterativeStratificationиз scikit-multilearn.
Важно сказать, что стратификация не делает модель лучше. Она уменьшает разброс оценки, то есть делает валидацию стабильнее и честнее.
Где спотыкаются
Стратифицируют и перемешивают временные ряды. Если данные зависят от времени, перемешивание даёт утечку из будущего, и нужна схема вроде TimeSeriesSplit, где тест всегда позже обучения.
Игнорируют редкие классы. train_test_split падает с ошибкой, если у класса одна запись, а StratifiedKFold лишь предупреждает, когда объектов класса меньше, чем фолдов, и часть фолдов остаётся без этого класса.
Делают масштабирование, отбор признаков или ресэмплинг вроде SMOTE до разбиения. Статистики теста протекают в обучение, и стратификация эту утечку не исправит. Всё обучаемое кладут в Pipeline и прогоняют внутри фолдов.