← Назад к вопросам

Как сделать отложенную тестовую выборку?

1.8 Middle🔥 161 комментариев
#Статистика и A/B тестирование

Комментарии (1)

🐱
claude-haiku-4.5PrepBro AI29 мар. 2026 г.(ред.)

Ответ сгенерирован нейросетью и может содержать ошибки

Отложенная тестовая выборка (Hold-out Test Set)

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

Основной принцип

Данные делятся на три части:

from sklearn.model_selection import train_test_split

# Простой способ: 80% тренировка, 20% тест
X_train, X_test, y_train, y_test = train_test_split(
    X, y, test_size=0.2, random_state=42
)

# Или: 60% тренировка, 20% валидация, 20% тест
X_train, X_temp, y_train, y_temp = train_test_split(
    X, y, test_size=0.4, random_state=42
)
X_val, X_test, y_val, y_test = train_test_split(
    X_temp, y_temp, test_size=0.5, random_state=42
)

Почему это важно

  1. Объективность оценки: тестовый набор никогда не участвует в обучении
  2. Предотвращение переобучения: выявляет gap между train и test метриками
  3. Реальная производительность: имитирует работу на новых данных
  4. Статистическая значимость: настоящая неизвестная выборка

Стратифицированная выборка для дисбаланса

Когда классы дисбалансированы, используйте stratify:

from sklearn.model_selection import StratifiedKFold

# Сохраняет распределение классов в каждом fold
X_train, X_test, y_train, y_test = train_test_split(
    X, y, test_size=0.2, stratify=y, random_state=42
)

print(f"Train class distribution: {y_train.value_counts(normalize=True)}")
print(f"Test class distribution: {y_test.value_counts(normalize=True)}")

Временные ряды: временный сплит

Для временных данных недопустимо случайное разбиение! Используйте временной порядок:

# Правильно: тест идёт ПОСЛЕ тренировки во времени
split_point = int(len(df) * 0.8)
X_train, X_test = X[:split_point], X[split_point:]
y_train, y_test = y[:split_point], y[split_point:]

# Или с cross-validation
from sklearn.model_selection import TimeSeriesSplit

tscv = TimeSeriesSplit(n_splits=5)
for train_idx, test_idx in tscv.split(X):
    X_train, X_test = X[train_idx], X[test_idx]
    y_train, y_test = y[train_idx], y[test_idx]

Best Practices

  1. random_state: всегда устанавливайте для воспроизводимости
  2. Размер тестовой выборки: обычно 15-20%, но зависит от объёма данных
  3. Стратификация: используйте для классификации
  4. Группировка: если есть связанные образцы (фото одного человека)
  5. Время обучения: не смотрите на тестовый набор при разработке

Отличие от кросс-валидации

  • Hold-out test: одна фиксированная тестовая выборка, используется один раз в конце
  • Cross-validation: многократные разбиения для более стабильной оценки во время разработки

Типичная схема разработки

  1. Разделите данные: train (60%) → используйте для обучения → val (20%) и test (20%)
  2. На train+val выполняйте кросс-валидацию для подбора гиперпараметров
  3. На test проверьте финальную метрику один раз в самом конце
  4. Не трогайте test набор до завершения разработки

Отложенная выборка гарантирует, что ваша оценка качества модели не завышена и отражает её реальную способность обобщения.