train_test_split в scikit-learn: выборки без утечки данных
Автор: Казачкин Даниил Михайлович · Обновлено
Функция train_test_split из scikit-learn делит данные на обучающую и тестовую части, но сама команда не гарантирует честную оценку модели. Способ разделения должен имитировать встречу с действительно новыми объектами и не пропускать информацию из проверки в обучение.
Роли трёх выборок
На обучающей части алгоритм подбирает параметры модели. Валидационная часть помогает выбрать признаки, алгоритм и гиперпараметры. Тестовую часть используют в самом конце для независимой оценки выбранного процесса.
Если многократно смотреть на тестовую метрику и после каждого результата менять решение, тест превращается в валидацию. Для итоговой честной проверки тогда понадобится новый набор данных.
Как работает train_test_split
from sklearn.datasets import load_breast_cancer
from sklearn.model_selection import train_test_split
X, y = load_breast_cancer(return_X_y=True)
# stratify используется для классификационной цели; для непрерывной
# регрессионной цели этот аргумент обычно опускают.
X_train, X_test, y_train, y_test = train_test_split(
X,
y,
test_size=0.2,
random_state=42,
stratify=y,
)random_state делает эксперимент воспроизводимым, а stratify=y сохраняет доли классов. Но случайное разделение подходит только тогда, когда строки достаточно независимы и будущие данные похожи на случайную выборку из той же совокупности.
Когда случайное перемешивание обманывает
Для прогноза будущего обучайтесь на прошлом и проверяйтесь на более позднем периоде. Для медицинских снимков разделяйте по пациентам, для событий приложения — по пользователям, для товаров — иногда по карточкам товара. Иначе связанные записи попадут в обе части, а модель узнает объект по косвенным деталям.
Граница должна соответствовать реальному запуску. Если сервис будет прогнозировать для новых магазинов, проверка на новых чеках старых магазинов измеряет другую способность.
Что такое утечка данных
Утечка возникает, когда при обучении используется информация, недоступная в момент реального прогноза, либо статистика проверочной части. Типичные примеры:
- заполнение пропусков средним, рассчитанным по всей таблице;
- масштабирование до разделения;
- признак «дата закрытия заявки» для прогноза её успешности;
- выбор признаков по корреляции с целью на полном наборе;
- дубликаты одного объекта в train и test.
Преобразования, которые обучаются на данных, нужно настраивать только внутри обучающей части. Pipeline в scikit-learn помогает соблюдать эту границу при кросс-валидации.
Проверка здравого смысла
Сравните модель с простым baseline и исследуйте подозрительно высокий результат. Почти идеальная метрика на шумной прикладной задаче чаще требует аудита данных, чем празднования. Проверьте время появления полей, уникальные идентификаторы и связь объектов между частями.
Практика: спроектируйте разделение
Для истории доставок с полями courier_id, order_created_at, delivered_at, район и погода опишите прогноз времени доставки в момент создания заказа. Уберите недоступные признаки, выберите временную границу и решите, нужно ли дополнительно группировать строки по курьеру. Объясните, что будет считаться новым объектом.
Что важно запомнить
- Train настраивает параметры, validation выбирает решение, test проверяет его один раз.
- Разделение должно воспроизводить реальную границу новых данных.
- Временные и групповые зависимости важнее случайной пропорции.
- Любая статистика тестовой части, попавшая в обучение, создаёт утечку.
Частые вопросы
Всегда ли достаточно соотношения 80/20?
Нет. Размер теста зависит от объёма данных и требуемой точности оценки. Важнее сохранить достаточно примеров редких случаев и выбрать способ разделения, соответствующий будущему использованию.
Зачем нужна валидация, если есть кросс-валидация?
Кросс-валидация многократно создаёт обучающие и проверочные фолды внутри доступного для разработки набора. Отдельный тест всё равно нужен для финальной оценки процесса, который уже был выбран по этим фолдам.
Можно ли масштабировать данные до train-test split?
Нельзя обучать scaler на всей таблице: средние и масштабы теста попадут в обучение. Сначала разделите данные, затем поместите преобразование в Pipeline или обучите его только на X_train.
Связанные исследования
- Утечка данных в машинном обучении: как честно провести train/test-оценку — Разбираем data leakage, границы train/test, preprocessing внутри Pipeline, групповые и временные разбиения и nested cross-validation без завышения выводов.
- Как читать научные статьи по ML: метод трёх проходов — Практический метод чтения ML-статей в три прохода: от быстрой карты до проверки данных, baseline, метрик и воспроизводимости.
- arXiv и препринты: отличие от рецензируемых статей — Разбираемся, что означает публикация на arXiv, чем модерация отличается от peer review и как проверить версию, DOI, статус и обновления работы.