Типичные ошибки прогнозиста

Собираем в одном месте грабли, на которые наступают чаще всего, и учимся их обходить.

Утечка из будущего — использование при прогнозе информации, которая на момент прогноза ещё не была доступна; главный источник ложно-хороших метрик.

Зачем отдельный урок про ошибки

Большинство провальных прогнозов гибнут не от слабой модели, а от методологических ошибок. Можно взять идеальный алгоритм и всё равно получить бесполезный результат, если нарушить валидацию или забыть про интервалы. Этот урок — чеклист, который стоит пробегать перед сдачей любого прогноза.

Опытные практики знают парадокс: чем красивее метрики на бумаге, тем выше шанс, что где-то спрятана ошибка. Прогноз с MAPE в полтора процента на тесте чаще означает не гениальную модель, а утечку из будущего, которую автор не заметил. Реальный прогноз спроса или цен почти никогда не бывает таким точным, потому что будущее по своей природе шумно. Поэтому здоровая реакция на подозрительно хороший результат — не радость, а недоверие и проверка: где модель могла подсмотреть ответ. Этот урок собирает типовые места, где такое подсматривание происходит.

Ошибка 1: утечка из будущего

Самая частая и коварная. Возникает при случайном train/test-разбиении, нормализации по всему ряду, заполнении пропусков будущими значениями, целевом кодировании на всей выборке. Признак беды — подозрительно хорошие метрики на тесте, рушащиеся на проде. Лечение: backtesting с расширяющимся окном (раздел 7) и правило «на момент t — только данные до t».

Особенно коварна утечка тем, что она прячется в рутинных шагах препроцессинга, которые кажутся безобидными. Посчитали среднее и стандартное отклонение для нормализации по всему датасету — и статистики из тестового периода уже просочились в обучающие признаки. Сделали случайное перемешивание перед train/test split, как привыкли в обычном ML, — и модель учится на завтрашних точках, чтобы предсказать вчерашние. В табличных задачах перемешивание законно, во временных рядах оно ломает причинность времени и обесценивает всю валидацию. Универсальное правило-оберег: любой расчёт, любая статистика и любое заполнение в точке t должны опираться строго на данные до момента t, и ни на что позже.

Ошибка 2: переобучение на сезонности и шуме

Соблазн добавить много лагов, гармоник и параметров, чтобы идеально описать историю. Модель запоминает шум и конкретные сезонные всплески прошлого, а на новых данных промахивается. Простой эксперимент: сложная модель почти всегда лучше на train и хуже на честном бэктесте.

# демонстрация: чем больше параметров, тем меньше ошибка на train,
# но это не значит лучший прогноз
train_err = {1: 8.0, 3: 4.5, 6: 2.1, 12: 0.4}   # падает с числом параметров
test_err  = {1: 8.5, 3: 5.0, 6: 5.8, 12: 9.2}   # сначала падает, потом РАСТЁТ

print("параметры | train | test")
best_k, best_v = None, 1e9
for k in (1, 3, 6, 12):
    print(f"   {k:2d}     | {train_err[k]:4.1f}  | {test_err[k]:4.1f}")
    if test_err[k] < best_v:
        best_v, best_k = test_err[k], k
print("Лучший выбор по тесту: k =", best_k)

Вывод:

параметры | train | test
    1     |  8.0  |  8.5
    3     |  4.5  |  5.0
    6     |  2.1  |  5.8
   12     |  0.4  |  9.2
Лучший выбор по тесту: k = 3

На train ошибка падает до 0.4 с ростом параметров, а на честном тесте — растёт после k=3. Минимум тестовой ошибки (k=3) и есть оптимальная сложность. Гнаться за train-ошибкой — прямая дорога к переобучению.

Эта U-образная кривая тестовой ошибки — фундаментальный факт, известный как компромисс смещения и разброса. Слишком простая модель (k=1) недообучена: она не улавливает реальную структуру и ошибается и на train, и на тесте. Слишком сложная (k=12) переобучена: она идеально пересказывает историю, включая случайный шум, но шум в будущем будет другим, и на тесте точность рушится. Золотая середина (k=3) ловит настоящий сигнал, не цепляясь за шум. Практический вывод жёсткий: train-ошибку для выбора сложности использовать нельзя в принципе, потому что она всегда монотонно падает с числом параметров и потому всегда советует самую сложную модель. Решение принимают исключительно по честному бэктесту.

Ошибка 3: прогноз без интервалов

Отдавать бизнесу одну точку — значит скрывать неопределённость. Решение по складу или мощностям нужно принимать с учётом риска: интервал [130, 175] говорит больше, чем «150». Прогноз без интервала создаёт ложное чувство контроля и приводит к недозаказу или перезаказу.

Разберём, как интервал меняет решение. Допустим, точечный прогноз спроса — 150 единиц. По нему логично заказать 150. Но если интервал широкий, скажем [130, 175], а дефицит товара стоит куда дороже, чем хранение излишка, разумно заказать ближе к верхней границе — 175, чтобы застраховаться от всплеска. А при узком интервале [148, 152] переплачивать за запас незачем. Сама ширина интервала несёт управленческий сигнал: она говорит, насколько модель уверена, и позволяет осознанно выбрать страховой запас под цену ошибки каждого типа. Точка без интервала всю эту информацию выбрасывает, оставляя менеджера принимать решение вслепую.

Ещё ловушки коротко

  • Сравнение с наивным базлайном пропущено. Если модель не бьёт «завтра как сегодня» или «как в прошлом сезоне» — она бесполезна. Всегда считайте базлайн.
  • Метрика не та. R² на трендовом ряде врёт; MAPE взрывается на нулях. Выбирайте метрику под задачу (раздел 7).
  • Игнор смены режима. Пандемия, новый продукт, смена цен ломают историю; модель на старых данных перестаёт работать.

Из этих трёх ловушек чаще всего недооценивают первую — наивный базлайн. Без него вообще непонятно, есть ли в модели смысл: возможно, тривиальное «завтра как сегодня» даёт ту же или лучшую точность, и весь сложный пайплайн не стоил усилий. Базлайн — это бесплатная планка качества, мимо которой нельзя проходить. Смена режима опаснее тем, что бьёт исподтишка уже в проде: модель работала отлично, пока структура данных не изменилась, и тогда исторические закономерности перестают действовать. Лекарство — мониторинг качества прогноза в реальном времени и готовность переобучить или отключить модель, когда мир под ней поменялся.

Как работает под капотом

Все три главные ошибки — об одном: модель оценивают не так, как она будет работать в реальности. Утечка нарушает причинность времени, переобучение путает запоминание с обобщением, отсутствие интервала скрывает реальную дисперсию ошибки. Противоядие универсально: честный backtest с расширяющимся окном, штраф за сложность (AIC/валидация) и обязательная оценка неопределённости.

Объединяющий принцип звучит так: процедура оценки должна максимально точно имитировать боевое применение модели. Если в проде прогноз делается каждое утро на данных до сегодняшнего дня — ровно так должен быть устроен и бэктест: расширяющееся окно, никаких будущих точек, никаких глобальных статистик. Тогда метрика на бэктесте становится честной оценкой того, что вы увидите в реальной работе, а не оптимистичной фантазией. Все три ошибки — это разные способы нарушить эту имитацию: утечка подсовывает недоступные данные, переобучение проверяет на тех же точках, на которых училась, отсутствие интервала прячет разброс. Держите процедуру оценки верной реальности — и большинство граблей обойдёте стороной.

Частые ошибки

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

Итоги

  • Три главные ошибки: утечка из будущего, переобучение, прогноз без интервалов.
  • Честный backtest, штраф за сложность и интервалы лечат большинство проблем.
  • Всегда сравнивайте модель с наивным базлайном — иначе непонятно, есть ли польза.
  • Главный принцип: процедура оценки должна имитировать боевое применение модели.
Проверьте себя
1. Что такое утечка из будущего (data leakage) в прогнозе рядов?
AПотеря данных при выгрузке
BИспользование при прогнозе информации, недоступной на момент прогноза
CСлишком большой горизонт
DОшибка округления
2. Как распознать переобучение модели прогноза?
AОшибка растёт и на train, и на тесте
BОшибка на train мала, а на честном бэктесте велика и растёт со сложностью
CМетрики одинаковы везде
DМодель не обучается
3. Почему важно сравнивать модель с наивным базлайном?
AБазлайн быстрее считается
BЕсли модель не бьёт «завтра как сегодня», она бесполезна
CЭто требование Prophet
DБазлайн не нужен