Переобучение и недообучение модели: как увидеть и исправить

Хорошая модель должна переносить найденную закономерность на новые данные. Переобученная модель запоминает детали и шум train-выборки, а недообученная не описывает даже основные…

Хорошая модель должна переносить найденную закономерность на новые данные. Переобученная модель запоминает детали и шум train-выборки, а недообученная не описывает даже основные зависимости. Эти состояния различают по ошибкам на обучении и независимой проверке.

Два характерных профиля

При недообучении качество низкое и на train, и на validation. Возможные причины — слишком простая модель, слабые признаки, неверная цель или чрезмерная регуляризация. Простое добавление данных не всегда поможет, если алгоритм принципиально не способен представить связь.

При переобучении train-метрика заметно лучше validation. Модель использует случайные особенности обучающей части, которые не повторяются. Риск растёт при высокой гибкости, малой выборке, утечках, долгом подборе по одной проверочной части и большом числе слабых признаков.

Кривые обучения

Learning curve показывает качество при увеличении объёма train. Если валидационный результат продолжает улучшаться, дополнительные данные могут быть полезны. Если обе кривые сходятся на плохом уровне, сначала стоит пересмотреть признаки или класс модели.

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

from sklearn.datasets import load_diabetes
from sklearn.linear_model import Ridge
from sklearn.model_selection import learning_curve, train_test_split

X, y = load_diabetes(return_X_y=True)
X_train, _, y_train, _ = train_test_split(
    X, y, test_size=0.2, random_state=42
)
model = Ridge(alpha=1.0)

sizes, train_scores, validation_scores = learning_curve(
    estimator=model,
    X=X_train,
    y=y_train,
    cv=5,
    scoring='neg_mean_absolute_error',
    train_sizes=[0.2, 0.4, 0.6, 0.8, 1.0],
)

train_mae = -train_scores.mean(axis=1)
validation_mae = -validation_scores.mean(axis=1)

Отрицательное имя scoring — соглашение scikit-learn: библиотека максимизирует score, поэтому метрики потерь инвертируются. Для отчёта знак возвращают обратно.

Способы борьбы с переобучением

Не выбирайте меру только по тому, насколько она улучшила один тест. Каждое решение должно приниматься на валидации, а финальная оценка оставаться независимой.

Ошибка может быть не в сложности

Разрыв между выборками возникает и при сдвиге данных. Если train содержит зиму, а validation — лето, ухудшение не обязательно исправляется регуляризацией. Нужно понять, соответствует ли обучающая история будущему периоду и доступны ли нужные сезонные признаки.

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

Практика: диагноз по двум числам

Для трёх моделей запишите train/validation accuracy: 0,61/0,60; 0,99/0,72; 0,88/0,86. Предложите основной диагноз и следующий эксперимент для каждой пары. Затем придумайте пример с временным сдвигом, где разрыв похож на переобучение, но уменьшение глубины не устраняет причину.

Что важно запомнить

Источники