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

Как делить датасет на тестовую и обучающую часть?

1.8 Middle🔥 291 комментариев
#Машинное обучение

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

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

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

Разделение датасета на обучающую и тестовую части — критический этап, определяющий валидность оценки модели. Существует несколько подходов в зависимости от природы данных.

Стандартная случайная разбивка

Самый распространённый подход — случайное разделение на train/test с помощью train_test_split:

from sklearn.model_selection import train_test_split

X_train, X_test, y_train, y_test = train_test_split(
    X, y, test_size=0.2, random_state=42
)
test_size=0.2 означает 80/20 разбивку. Для больших датасетов часто используют 70/30. random_state=42 обеспечивает воспроизводимость.

Стратифицированная разбивка

Для дисбалансированных классов критична стратификация — она гарантирует одинаковое распределение классов в train и test:

X_train, X_test, y_train, y_test = train_test_split(
    X, y, test_size=0.2, random_state=42, stratify=y
)

Это обязательно при работе с классификацией с дисбалансом.

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

Для более надёжной оценки используется k-fold cross-validation. Данные делятся на k частей, модель обучается k раз, каждый раз оставляя одну часть для теста:

from sklearn.model_selection import cross_val_score, KFold

kfold = KFold(n_splits=5, shuffle=True, random_state=42)
scores = cross_val_score(model, X, y, cv=kfold, scoring="accuracy")

Вместо простого train/test, кросс-валидация использует весь датасет для обучения и даёт более стабильную оценку.

TimeSeriesSplit для временных рядов

Для временных рядов обычная случайная разбивка неуместна. Нужна временная разбивка:

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]

Модель обучается на прошлых данных, тестируется на будущих.

Тройная разбивка: train/val/test

Для гиперпараметров нужен валидационный набор:

X_temp, X_test, y_temp, y_test = train_test_split(
    X, y, test_size=0.2, random_state=42
)
X_train, X_val, y_train, y_val = train_test_split(
    X_temp, y_temp, test_size=0.25, random_state=42
)

Результат: 60% train, 20% val, 20% test.

GroupKFold для данных с зависимостями

Если данные содержат группы (пациенты, пользователи), нельзя делить случайно — утечка информации:

from sklearn.model_selection import GroupKFold

gkf = GroupKFold(n_splits=5)
for train_idx, test_idx in gkf.split(X, y, groups=patient_ids):
    pass

Практические советы

  1. Всегда используй random_state для воспроизводимости
  2. Для классификации — обязательна стратификация
  3. Для временных рядов — никогда не смешивай train и test случайно
  4. Для дисбалансированных данных — рассмотри стратифицированную кросс-валидацию
  5. Для надёжности — используй кросс-валидацию, а не простой train/test split

Правильная разбивка — основа валидной оценки модели.

Как делить датасет на тестовую и обучающую часть? | PrepBro