Модель нельзя оценивать на тех же данных, на которых она училась
Поэтому train/test split — это не техническая привычка, а способ смоделировать будущее. Мы как будто говорим модели: вот на этой части мира ты можешь учиться, а вот эта часть будет для тебя новой. Именно такой режим и ждет ее в реальной эксплуатации. В продакшене модель всегда сталкивается не с прошлым, а с новыми объектами. Если при разработке мы не воспроизводим этот сценарий, то вся оценка качества становится сомнительной.
Именно поэтому train/test split стоит воспринимать не как служебную операцию библиотеки, а как первый и самый важный барьер между реальной проверкой модели и самообманом.
Почему одной хорошей метрики на обучающей выборке недостаточно
Представим, что модель обучилась на таблице и показала почти идеальную точность. Без отдельного тестового набора это может выглядеть как сильный результат. Но на самом деле мы пока измерили только одно: насколько хорошо модель умеет воспроизводить уже увиденное. Для линейной модели, дерева решений, градиентного бустинга и тем более нейросети это слишком слабая проверка. Любой достаточно гибкий алгоритм умеет подстраиваться под обучающую выборку. Вопрос не в том, может ли он уменьшить ошибку на train, а в том, умеет ли он переносить закономерность на unseen data.
Именно здесь и появляется понятие валидации. Мы перестаем спрашивать: насколько модель хорошо помнит. И начинаем спрашивать: насколько она умеет обобщать. В машинном обучении это и есть центральная задача. Хорошая модель не обязана идеально описывать прошлое. Она должна надежно работать на новых наблюдениях.
Поэтому рядом полезно держать и материал про baseline-модель. Без базовой отправной точки даже честный split не даст полного ответа: мы увидим оценку, но не поймем, лучше ли модель простой и понятной альтернативы.
Как устроено разбиение и почему у него есть логика, а не только пропорции
Чаще всего начинают с простого деления: одну часть данных отдают на обучение, вторую оставляют на тест. Популярные пропорции вроде 80/20 или 70/30 полезны, но сами по себе не являются магией. Важен не конкретный процент, а баланс между двумя задачами. С одной стороны, модели нужно достаточно данных, чтобы учиться. С другой стороны, тестовая часть должна быть достаточно большой, чтобы оценка качества была стабильной.
Если тест слишком мал, результат становится шумным: одна неудачная группа наблюдений может сильно исказить итоговую метрику. Если тест слишком велик, модели может не хватить информации для обучения. Поэтому выбор пропорции — это не ритуал, а инженерный компромисс. Он зависит от размера датасета, сложности задачи, редкости целевого события и типа модели.
(N = N_{train} + N_{test})
Раздел математики: базовая статистика и теория выборок.
Что означает каждый символ:(N) — общее число объектов в исходном датасете;(N_{train}) — число объектов, на которых модель учится;(N_{test}) — число объектов, которые полностью отложены для финальной проверки.
Численный пример: если в наборе данных (N = 1000) объектов и мы выбрали разбиение 80/20, то получаем (N_{train} = 800) и (N_{test} = 200). Это не просто арифметика. Это решение о том, сколько информации мы отдаем на построение модели и сколько сохраняем для честной оценки.
Где появляется validation set и почему одного test уже бывает мало
Как только модель перестает быть совсем простой, одного train/test split часто недостаточно. Причина в том, что в процессе разработки мы обычно перебираем гиперпараметры, сравниваем алгоритмы, меняем признаки, пробуем разные способы обработки пропусков и категорий. Если в этот момент постоянно смотреть на test, он перестает быть честным. По сути, мы начинаем подстраивать решение под тестовую выборку так же, как раньше подстраивали модель под train.
Именно для этого выделяют validation set. Он нужен как рабочая площадка для выбора модели, настройки гиперпараметров и проверки промежуточных решений. Тогда логика становится такой: train используется для обучения, validation — для выбора лучшей конфигурации, test — для финальной независимой оценки. Это особенно важно в Data Science проектах, где итераций много и соблазн постоянно смотреть на итоговый скор очень велик.
Почему валидация связана с переобучением сильнее, чем кажется
Переобучение обычно объясняют через разницу между train и test quality. Это верно, но неполно. На практике переобучение может происходить и на уровне выбора модели. Если команда слишком долго оптимизирует решение под один validation set, этот набор тоже начинает терять независимость. Поэтому профессиональная работа с качеством почти всегда строится как иерархия проверок. Сначала базовое разделение данных, потом честная настройка на validation, потом один финальный взгляд на test.
Именно здесь тема train/test split естественно продолжается разговором о том, как бороться с overfitting. Потому что само разбиение данных ещё не решает проблему, а только создаёт условия, в которых переобучение вообще можно заметить честно.
Здесь train/test split превращается из простой операции в дисциплину эксперимента. Он задает правила, при которых метрика действительно что-то означает. Без этих правил accuracy, ROC AUC, F1 или RMSE могут быть математически посчитаны верно, но интерпретационно бесполезны.
Когда обычного split недостаточно и нужна кросс-валидация
Если данных мало, единичное разбиение может быть слишком нестабильным. Одно неудачное распределение объектов между train и validation даст завышенную или заниженную оценку. В таких случаях используют кросс-валидацию. Ее идея интуитивно проста: мы несколько раз меняем роль частей выборки и усредняем результат. Тогда качество меньше зависит от случайного конкретного split.
Если хочется глубже понять именно этот следующий уровень оценки, полезно отдельно открыть и кросс-валидацию в Machine Learning. Она хорошо показывает, в какой момент одного честного split уже недостаточно и нужна более устойчивая проверка.
(\bar{M} = \frac{1}{K}\sum_{k=1}^{K} M_k)
Раздел математики: математическая статистика.
Что означает каждый символ:(\bar{M}) — средняя оценка качества по всем фолдам;(K) — число разбиений, или фолдов;(M_k) — значение метрики на (k)-м фолде.
Численный пример: если при пяти фолдах модель получила значения (0.81, 0.79, 0.83, 0.80, 0.82), то средняя метрика равна (\bar{M} = \frac{0.81 + 0.79 + 0.83 + 0.80 + 0.82}{5} = 0.81). Такая оценка обычно надежнее, чем результат на одном произвольном split.
Геометрического смысла здесь почти нет, но есть очень важный статистический смысл
Не каждая тема Machine Learning обязана иметь яркую геометрическую интерпретацию. В train/test split главное не геометрия, а логика выборочного контроля. Мы фактически создаем две разные выборки из одного распределения: одна помогает оценить параметры модели, другая — проверить, насколько эти параметры работают за пределами обучающего примера. Это ближе к статистическому эксперименту, чем к геометрии пространства признаков.
Тем не менее связь с машинным обучением здесь прямая. Любой алгоритм — от линейной регрессии до градиентного бустинга — нуждается в честной внешней проверке. Разделение данных не зависит от конкретной модели, но определяет, можно ли вообще доверять ее метрике.
Самые частые ошибки при разбиении данных
Первая ошибка — случайно допустить утечку. Например, сначала масштабировать весь датасет, а уже потом делить на train и test. В таком случае статистика test выборки попадает в preprocessing, и оценка качества становится слишком оптимистичной. Вторая ошибка — несколько раз смотреть на test во время настройки модели. Третья — делать случайный split там, где данные имеют временную структуру. Для временных рядов такой подход особенно опасен, потому что модель получает информацию из будущего.
Поэтому здесь особенно важно отдельно понимать и data leakage. Она часто выглядит как мелкая техническая оплошность, но на деле полностью ломает смысл train/test split, превращая тест в ещё одну замаскированную часть train.
Четвертая ошибка — игнорировать дисбаланс классов при классификации. Если положительный класс редок, случайное разбиение без стратификации может привести к тому, что train и test окажутся слишком разными по доле целевого события. Тогда метрика начнет отражать не качество модели, а неудачное разбиение.
Как это выглядит в Python
from sklearn.model_selection import train_test_split # Импортируем функцию для разбиения данных.
from sklearn.linear_model import LogisticRegression # Импортируем простую модель классификации.
from sklearn.metrics import accuracy_score # Импортируем метрику accuracy.
import pandas as pd # Подключаем pandas для работы с таблицей.
# Загружаем данные в DataFrame.
df = pd.read_csv("customers.csv")
# Отделяем признаки от целевой переменной churn.
X = df.drop(columns=["churn"])
y = df["churn"]
# Делим данные на обучающую и тестовую части.
X_train, X_test, y_train, y_test = train_test_split(
X, y,
test_size=0.2, # Оставляем 20 процентов данных под тест.
random_state=42, # Фиксируем разбиение для воспроизводимости.
stratify=y # Сохраняем долю классов в обеих частях.
)
# Создаем модель.
model = LogisticRegression(max_iter=1000)
# Обучаем модель только на train-части.
model.fit(X_train, y_train)
# Строим предсказания только на test-части.
y_pred = model.predict(X_test)
# Считаем accuracy на полностью отложенных данных.
print(accuracy_score(y_test, y_pred))Построчно здесь происходит следующее. Мы загружаем данные и разделяем признаки и целевую переменную. Затем вызываем (train_test_split), который случайно разбивает выборку. Параметр (test_size = 0.2) означает, что 20 процентов объектов будут отложены под честную проверку. (random_state = 42) нужен для воспроизводимости, чтобы разбиение можно было повторить. (stratify = y) особенно важен при дисбалансе классов. После этого модель обучается только на train, а качество считается только на test. Это и есть минимальная честная схема оценки.
Но и на этом шаге полезно помнить, что честный split начинается ещё до обучения модели — с проверки самих данных. Поэтому рядом логично держать и материал про data validation, чтобы сначала убедиться в корректности входа, а уже потом обсуждать качество на train и test.
Что важно запомнить начинающему специалисту
Train/test split — это не шаг ради библиотеки, а правило интеллектуальной честности. Он нужен не для красоты кода и не потому, что так написано в учебниках. Он нужен потому, что модель всегда должна проверяться на данных, которых она не видела. Валидация продолжает эту логику и защищает нас от переобучения уже на уровне выбора решений. А кросс-валидация делает оценку устойчивее, когда данных мало.
Если смотреть на тему именно так, то разбиение данных перестает быть скучной вводной темой. Оно становится одним из центральных принципов Data Science. Через него проходит граница между моделью, которая кажется хорошей, и моделью, которой действительно можно доверять.
Kaggle Notebook по теме статьи: https://www.kaggle.com/code/bohdanzaika/part-1-data-cleaning-and-train-test-split/code