Ответ
В зависимости от структуры данных и задачи я выбираю разные стратегии кросс-валидации (CV), чтобы получить надежную оценку обобщающей способности модели.
Основные стратегии и их применение:
-
K-Fold Cross-Validation Стандартный выбор для большинства задач с независимыми и одинаково распределенными (IID) данными. Данные случайно перемешиваются и разбиваются на K равных частей (фолдов).
from sklearn.model_selection import KFold import numpy as np X = np.array([[1, 2], [3, 4], [5, 6], [7, 8], [9, 10]]) y = np.array([1, 2, 3, 4, 5]) kf = KFold(n_splits=5, shuffle=True, random_state=42) for train_index, val_index in kf.split(X): X_train, X_val = X[train_index], X[val_index] y_train, y_val = y[train_index], y[val_index] # Обучение и оценка модели -
Stratified K-Fold Когда применяю: Для задач классификации с несбалансированными классами. Эта стратегия сохраняет процентное соотношение классов в каждом фолде, что дает более стабильную оценку метрик (например, F1-score для миноритарного класса).
from sklearn.model_selection import StratifiedKFold skf = StratifiedKFold(n_splits=5, shuffle=True, random_state=42) # Используется аналогично KFold, но передается и y для стратификации for train_index, val_index in skf.split(X, y): ... -
Time Series Split (или TimeSeriesCV) Когда применяю: Для данных, имеющих временную зависимость (финансовые котировки, сенсорные данные). Важно не допустить "утечки будущего в прошлое". Каждый последующий тренировочный набор является надмножеством предыдущего.
from sklearn.model_selection import TimeSeriesSplit tscv = TimeSeriesSplit(n_splits=5) for train_index, val_index in tscv.split(X): # train_index всегда предшествует val_index по времени -
Leave-One-Out (LOO) Частный случай K-Fold, где
K = N(число объектов). Каждый объект по очереди становится валидационным. Применяю очень редко из-за высокой вычислительной стоимости, только для очень маленьких датасетов (десятки образцов). -
Group K-Fold Когда применяю: Когда в данных есть группы, и нужно убедиться, что объекты из одной группы не попадут одновременно в train и test. Например, данные от нескольких пациентов в медицинском датасете или несколько снимков одного объекта.
from sklearn.model_selection import GroupKFold groups = [1, 1, 2, 2, 3, 3, 4, 4, 5, 5] # ID группы для каждого образца gkf = GroupKFold(n_splits=5) for train_index, val_index in gkf.split(X, y, groups=groups): # Объекты с одинаковым group_id не будут разбиты между фолдами
В 90% случаев для табличных данных я начинаю с Stratified K-Fold (shuffle=True) для классификации и обычного K-Fold для регрессии, если нет явной временной или групповой структуры.