# Кросс-валидация

> Метод оценки качества модели, при котором данные многократно делятся на обучающую и проверочную части; даёт устойчивую оценку и помогает подбирать гиперпараметры.

Источник: https://llmdocs.ru/wiki/cross-validation/ · обновлено 2026-11-09 · лицензия CC BY-SA 4.0

- **Назначение**: оценка обобщающей способности модели
- **Основной вариант**: k-fold (обычно k = 5 или 10)
- **Варианты**: stratified, group, time series, leave-one-out, nested
- **Реализация**: scikit-learn (sklearn.model_selection)
- **Связанное**: подбор гиперпараметров, переобучение, утечка данных
**Кросс-валидация** (перекрёстная проверка, англ. *cross-validation*) — способ оценить, насколько хорошо модель [машинного обучения](https://llmdocs.ru/wiki/machine-learning.md) будет работать на новых данных. Данные несколько раз делят на обучающую и проверочную части, модель обучают и проверяют на каждом разбиении, а результаты усредняют. В отличие от единственного разбиения на train/test, кросс-валидация использует все данные и для обучения, и для проверки и показывает не только среднее качество, но и его разброс.

## Зачем

Качество модели на обучающих данных ничего не говорит о качестве на новых: сложная модель может просто запомнить примеры (см. [Переобучение и регуляризация](https://llmdocs.ru/wiki/overfitting-regularization.md)). Поэтому часть данных откладывают. Но одно случайное разбиение ненадёжно: на маленьком наборе оценка сильно зависит от того, какие примеры попали в тест. Кросс-валидация уменьшает эту случайность и позволяет честно сравнивать модели и гиперпараметры.[4]

## k-fold

Самый распространённый вариант — **k-кратная кросс-валидация**:

1. перемешать данные и разбить на *k* равных частей (фолдов);
2. для каждого *i* от 1 до *k* обучить модель на всех фолдах, кроме *i*-го, и измерить качество на *i*-м;
3. усреднить *k* оценок и посчитать стандартное отклонение.

Обычно берут *k* = 5 или 10: модель обучается на 80–90% данных, а вычислений в 5–10 раз больше, чем при одном разбиении. Крайний случай — **leave-one-out** (*k* равно числу примеров): почти несмещённая, но дорогая и шумная оценка.

```python
from sklearn.model_selection import cross_val_score
from sklearn.ensemble import RandomForestClassifier

scores = cross_val_score(RandomForestClassifier(), X, y, cv=5, scoring="f1")
print(f"F1 = {scores.mean():.3f} ± {scores.std():.3f}")
```

Метрику выбирают по задаче (см. [Метрики качества классификации](https://llmdocs.ru/wiki/classification-metrics.md)).[1]

## Варианты разбиения

| Вариант | Когда использовать |
|---|---|
| **StratifiedKFold** | классификация с несбалансированными классами — доля классов в каждом фолде одинакова |
| **GroupKFold** | у примеров есть группы (пациент, пользователь, документ), которые нельзя разрывать между train и test |
| **TimeSeriesSplit** | временные ряды — обучение только на прошлом, проверка на будущем |
| **RepeatedKFold** | маленький набор — несколько повторов с разными перемешиваниями |
| **ShuffleSplit** | большой набор — несколько случайных разбиений произвольного размера |

Для временных данных обычное перемешивание недопустимо: модель «подглядит» в будущее, и оценка окажется оптимистичной. TimeSeriesSplit расширяет обучающее окно шаг за шагом, как в реальной эксплуатации.

## Подбор гиперпараметров

Кросс-валидация — основа подбора гиперпараметров: для каждой комбинации считается средняя оценка по фолдам, и выбирается лучшая.[2]

```python
from sklearn.model_selection import GridSearchCV

search = GridSearchCV(
    estimator=model,
    param_grid={"max_depth": [3, 5, 8], "n_estimators": [200, 500]},
    cv=5, scoring="roc_auc", n_jobs=-1,
)
search.fit(X_train, y_train)
print(search.best_params_, search.best_score_)
```

Есть тонкость: если много раз выбирать лучшую конфигурацию по одной и той же кросс-валидации, её оценка становится смещённой вверх — модель «переобучается на валидацию».[5] Честная оценка требует отложенного тестового набора, который не участвует в подборе, или **вложенной кросс-валидации** (nested CV): внутренний цикл подбирает параметры, внешний оценивает весь процесс.

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

Самая частая ошибка — выполнить предобработку (масштабирование, отбор признаков, заполнение пропусков, балансировку классов) на всём наборе до разбиения. Тогда статистики тестовых фолдов влияют на обучение, и оценка завышена.[3] Решение — объединить предобработку и модель в `Pipeline`, чтобы на каждом фолде всё обучалось только на обучающей части:

```python
from sklearn.pipeline import make_pipeline
from sklearn.preprocessing import StandardScaler
from sklearn.linear_model import LogisticRegression

pipe = make_pipeline(StandardScaler(), LogisticRegression(max_iter=1000))
cross_val_score(pipe, X, y, cv=StratifiedKFold(5, shuffle=True, random_state=0))
```

Другие источники утечки — дубликаты между фолдами, признаки, вычисленные с использованием целевой переменной, и данные одного объекта по разные стороны разбиения (решается GroupKFold).

## Кросс-валидация в бустинге и глубоком обучении

Для [градиентного бустинга](https://llmdocs.ru/wiki/gradient-boosting.md) кросс-валидация, помимо оценки, помогает выбрать число деревьев через раннюю остановку на каждом фолде; предсказания моделей разных фолдов часто усредняют (out-of-fold ансамбль), что популярно на соревнованиях Kaggle. В глубоком обучении, где одна модель обучается часами, обычно ограничиваются одним валидационным набором — данных достаточно, а k-кратное обучение слишком дорого.

## См. также

- [Переобучение и регуляризация](https://llmdocs.ru/wiki/overfitting-regularization.md)
- [scikit-learn](https://llmdocs.ru/wiki/scikit-learn.md)
- [Метрики качества классификации](https://llmdocs.ru/wiki/classification-metrics.md)
- [Машинное обучение](https://llmdocs.ru/wiki/machine-learning.md)

## Источники

1. [scikit-learn — Cross-validation: evaluating estimator performance](https://scikit-learn.org/stable/modules/cross_validation.html)
2. [scikit-learn — Tuning the hyper-parameters of an estimator](https://scikit-learn.org/stable/modules/grid_search.html)
3. [scikit-learn — Common pitfalls and recommended practices](https://scikit-learn.org/stable/common_pitfalls.html)
4. [Hastie, Tibshirani, Friedman — The Elements of Statistical Learning, ch. 7](https://hastie.su.domains/ElemStatLearn/)
5. [Cawley, Talbot — On Over-fitting in Model Selection (JMLR, 2010)](https://jmlr.org/papers/v11/cawley10a.html)
