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

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

Кросс-валидация и подбор параметров

После урока: объяснить folds и выполнить упражнение «Выбрать C по train-CV без просмотра test», обосновав выбранный подход..

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

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

Оценка решения внутри train

Кросс-валидация делит train на folds. Для каждого запуска одна часть становится validation, остальные — обучением. Среднее validation-оценок помогает выбирать гиперпараметры с меньшей зависимостью от одного разбиения. Оценки folds не являются полностью независимыми наблюдениями: их train-части пересекаются.

В Wine используем StratifiedKFold из пяти частей с перемешиванием и фиксированным seed. Каждый класс должен иметь достаточно объектов для выбранного числа частей. Для временных или групповых данных нужны соответствующие splitters; StratifiedKFold не исправляет зависимость между строками одного объекта.

Поиск параметров

GridSearchCV перебирает заранее заданные варианты, оценивает весь Pipeline на folds и с refit=True обучает лучший вариант на всём train. Параметр шага задаётся через два подчёркивания: model__C. В лаборатории рассматриваем C = 0.1, 1, 10 и scoring="f1_macro".

Цена поиска растёт с числом комбинаций, folds и стоимостью обучения. Не запускайте огромную сетку без гипотезы. Зафиксируйте бюджет, кандидатов и метрику до измерения. Если сравниваете много семейств, отбор тоже является частью процесса и способен переобучиться на validation.

Финальная проверка

После выбора один раз измерьте качество на holdout. В отчёте раздельно запишите CV-оценку и test-оценку. Они получены на разных данных и не обязаны совпадать. Низкая test-метрика — информация о процедуре или распределении, а не повод перебирать seed до удачи.

В небольшом примере считаем только число folds и пересечение индексов, чтобы проверить механику. Полный поиск реализован в ml_lab.train; откройте его и найдите, что test передаётся только финальному predict, а не search.fit.

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

python
from sklearn.datasets import load_wine
from sklearn.model_selection import StratifiedKFold
data = load_wine()
folds = list(StratifiedKFold(n_splits=5, shuffle=True, random_state=42).split(data.data, data.target))
print(len(folds))
print(all(not set(train) & set(valid) for train, valid in folds))

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

text
5
True

В каждом из пяти запусков обучающие и validation-индексы не пересекаются.

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

Сетка содержит 3 значения C и 5 folds. Сколько обучений нужно для оценки, не считая финального refit?

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

3 × 5 = 15. При refit=True добавится обучение выбранного варианта на всём train. Полный pipeline обучается заново в каждом fold.

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

1. Как обратиться к C шага model внутри Pipeline?
2. Входит ли holdout в search.fit?