Что такое кросс-валидация?

«Что такое кросс-валидация?» — вопрос из категории Классическое ML, который задают на 30% собеседований Data Scientist / ML Инженер. Ниже — развёрнутый ответ с разбором ключевых моментов.

Ответ

Кросс-валидация (CV) — это метод перекрестной проверки, используемый для более надежной оценки обобщающей способности модели и для настройки гиперпараметров. Вместо разового разбиения на train/test, данные циклически разбиваются на несколько частей (фолдов), что позволяет эффективнее использовать все данные для оценки.

Основная идея K-Fold CV:

  1. Данные случайно перемешиваются и разбиваются на K равных частей (фолдов).
  2. Модель обучается K раз. Каждый раз одна из K частей используется как валидационная (test) выборка, а остальные (K-1) части — как обучающая (train) выборка.
  3. Итоговая оценка качества (например, средняя точность) вычисляется как среднее по K валидационным прогонам.

Преимущества:

  • Меньшая зависимость от случайного разбиения на train/test.
  • Эффективное использование данных (каждое наблюдение побывает и в train, и в test).
  • Позволяет оценить стабильность модели (по разбросу оценок на фолдах).

Пример с scikit-learn (оценка модели):

from sklearn.model_selection import cross_val_score, KFold
from sklearn.ensemble import RandomForestClassifier
from sklearn.datasets import load_iris

# Загрузка данных
iris = load_iris()
X, y = iris.data, iris.target

# Создание модели и стратегии CV
model = RandomForestClassifier(n_estimators=100, random_state=42)
kfold = KFold(n_splits=5, shuffle=True, random_state=42)  # 5 фолдов

# Кросс-валидация
scores = cross_val_score(model, X, y, cv=kfold, scoring='accuracy')

print(f"Оценки accuracy на каждом фолде: {scores}")
print(f"Средняя accuracy: {scores.mean():.3f} (+/- {scores.std() * 2:.3f})")  # 95% интервал

Основные типы в sklearn:

  • KFold — стандартная K-блочная CV.
  • StratifiedKFold — сохраняет процентное соотношение классов в каждом фолде (важно для несбалансированных данных).
  • LeaveOneOut — частный случай, где K = n (каждый объект — отдельный тестовый фолд). Вычислительно дорого.
  • TimeSeriesSplit — для временных рядов, где важно не "заглядывать в будущее" при валидации.