← Маршрут ML-инженерии

Урок · 2 мин чтения · упражнения и самопроверка

Разделение данных и утечки

После урока: объяснить train и holdout и выполнить упражнение «Отделить финальный тест и проверить отсутствие пересечения», обосновав выбранный подход..

Перед началом

Примеры выполняются локально: скачайте лабораторию и установите зависимости по README. Онлайн-редактор алгоритмических задач не содержит ML-библиотеки.

Симуляция будущих объектов

Обучение подбирает параметры по данным. Если измерить качество на тех же наблюдениях, получится оценка запоминания, а не работы на новых объектах. Поэтому до обучения отделите holdout — финальную часть, которую не используют для выбора признаков, параметров или модели.

Train нужен для обучения. Validation или folds внутри train помогают выбирать настройки. Test используют для финального измерения после выбора. Повторное принятие решений по test постепенно превращает его в ещё одну validation-выборку. Если это произошло, для честной оценки нужен новый holdout.

Как делить

В Wine используем случайное разделение 80/20 со stratify=y: доли классов примерно сохраняются. Random_state фиксирует конкретное разбиение для повторения эксперимента. Само значение seed не улучшает модель; нельзя выбирать его по лучшей test-оценке.

Для временных рядов обучайтесь на прошлом и проверяйте на будущем. Для повторных объектов одного пользователя, пациента или устройства разделяйте группы целиком. Иначе в train и test окажутся зависимые наблюдения и оценка станет слишком оптимистичной. Стратификация по классу не устраняет пересечение групп.

Утечка данных

Утечка возникает, если в обучение попадает информация, недоступная на момент реального предсказания. Примеры: признак «результат лечения» до лечения, один объект в обеих выборках, среднее масштабирования по всей таблице. Даже операция без y может сообщить модели свойства будущего test.

Сохраняйте индексы разбиения в отчёте и проверяйте отсутствие пересечения. Но это только одна проверка: разные строки могут принадлежать одному объекту. Для продукта также нужны устойчивый ключ и правило времени появления признаков.

Пошаговый пример

python
from sklearn.datasets import load_wine
from sklearn.model_selection import train_test_split
data = load_wine(as_frame=True)
train_x, test_x, train_y, test_y = train_test_split(data.data, data.target, test_size=0.2, stratify=data.target, random_state=42)
print(len(train_x), len(test_x))
print(len(set(train_x.index) & set(test_x.index)))

Ожидаемый вывод

text
142 36
0

142 наблюдения идут в train, 36 — в holdout. Индексы не пересекаются; стратификация сохраняет классы.

Сделайте самостоятельно

В таблице несколько строк каждого клиента. Вы планируете предсказывать для новых клиентов. Почему случайное деление строк опасно и как изменить схему?

Ответ и критерии проверки

Один клиент может оказаться в обеих частях, и модель воспользуется его узнаваемыми признаками. Делите по client_id, оставляя все строки клиента в одной части; дополнительно проверьте время появления признаков.

Проверьте понимание

1. Можно ли выбирать C по лучшему результату test?
2. Для чего stratify=y?