TATECHATLAS
◎ Русский
Математика и модели

Как проверить прогноз временного ряда без утечки будущего

Хронологические выборки и обучение преобразований только на прошлом.

В этом материале

Обучайте модель на ранних наблюдениях, а проверяйте на более поздних. Случайное разбиение может дать ей информацию, недоступную при реальном прогнозе.

Начните с момента, когда нужен прогноз

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

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

Зафиксировать горизонт

Размер тестового периода должен соответствовать нужному горизонту прогноза. Масштабирование и другие обучаемые преобразования настраивайте только на тренировочной части. Скользящие признаки используют лишь доступное на момент прогноза.

from sklearn.model_selection import TimeSeriesSplit

observations = list(range(12))
splitter = TimeSeriesSplit(n_splits=3, test_size=2, gap=1)
for train, test in splitter.split(observations):
    print(train.tolist(), test.tolist())

Как выглядит разбиение на конкретных позициях

В небольшом примере выше 12 упорядоченных наблюдений, три проверочных окна по два наблюдения и зазор в одну строку. Первое обучение использует позиции 0–4, проверка — 6–7. Затем обучение — 0–6, проверка — 8–9. Последняя пара — 0–8 и 10–11.

Зазор задаёт выбранный интервал исключения, а не универсально устраняет утечки. Его длина зависит от задержек публикации и перекрытия целевых окон. TimeSeriesSplit считает строки: две строки не обязательно означают два дня. До интерпретации окон проверьте порядок дат, дубликаты, пропуски и равномерность шага.

Проверить временные предпосылки

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

Ищите утечки не только в разбиении

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

Для дневных продаж скользящее среднее при прогнозе на день t должно использовать предыдущие наблюдения, например shift(1).rolling(7).mean(). Центрированное окно может захватить будущие дни. При прогнозе всей недели сразу даже реальные продажи её первых дней ещё неизвестны: нельзя подставлять их в прогноз следующих дней как доступные данные.

Сравните с простым прогнозом до настройки модели

Возьмите базовый вариант под задачу: последнее известное значение или соответствующий период предыдущего сезонного цикла. Считайте ошибки на тех же точках построения и горизонте, что и у модели. В условном расчёте ниже фактические 100, 110 и 90 при прогнозах 100 дают MAE ≈ 6,67 в единицах целевого показателя.

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

actual = [100, 110, 90]
predicted = [100, 100, 100]
mae = sum(abs(a - p) for a, p in zip(actual, predicted)) / len(actual)
print(round(mae, 2))

Что проверить

  • Разбивайте по времени.
  • Обучайте преобразования внутри каждой выборки.
  • Проверяйте доступность признаков на момент прогноза.

Наблюдения должны идти хронологически. TimeSeriesSplit оперирует позициями строк: для сопоставимых временных окон проверьте равномерность интервалов.

Источники

  1. scikit-learn: TimeSeriesSplit ↗
  2. scikit-learn: common pitfalls ↗
  3. pandas: time series ↗
  4. pandas: rolling windows ↗
Наверх ↑