Аналитика25 октября 2026 г.

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

Автор
Ненашев А.
На чтение
6 мин
Дата обновления
25.10.2026
Старт:С 2 сентября
Срок обучения:4 месяца
Методы анализа и прогнозирования временных рядов
Целью курса является формирование умений по применению научно-обоснованной комплексной методологии анализа и прогнозирования временных рядов на основе методов статистического анализа, моделирования и прогнозирования информации, с учетом отечественного и зарубежного опыта по использованию подобных подходов на практике. В курсе также описываются новые методы и подходы к обработке информации, являющиеся адаптивными, как по характеру их применения, так и по способу установления характеристик компонент временных рядов.
Подробнее
3 600 ₽3 600 ₽
#COURSE##INNER#

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

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

Ниже разберем узкий и проверяемый сценарий: есть 12 последовательных недель, и нужно оценить прогноз без перемешивания. Мы построим три expanding-window окна: обучающая часть растет от окна к окну, а тест всегда идет только после нее. Заодно проверим, где проходят границы, и почему даже правильный TimeSeriesSplit не спасает от всех утечек сам по себе.

Сначала зафиксируйте горизонт прогноза и доступную информацию

Горизонт прогноза отвечает на вопрос, насколько далеко вперед вы смотрите. В этом разборе возьмем такой смысл: в конце недели W6, W8 и W10 вы хотите получить прогноз на следующие две недели. Тогда естественная проверка — тестовые блоки по две недели. Если же ваша реальная задача — предсказать только следующую неделю, а test_size=2, то один фолд проверяет двухшаговый блок от одной и той же границы обучения. Это полезно, когда в работе вы тоже строите прогноз сразу на две недели вперед. Но это не равно двум отдельным одношаговым проверкам с дообучением после первой недели теста. Для такого сценария обычно нужен пошаговый backtest с тестом по одной неделе или явное обновление модели внутри тестового блока.

Не менее важен второй вопрос: какие признаки доступны в момент прогноза. Для границы после W6 можно использовать факты W1–W6, календарные признаки для W7–W8 и любые планы, которые действительно известны заранее. Нельзя использовать фактические значения W7–W8, показатели, которые публикуются с задержкой после этих недель, или признаки, посчитанные так, будто W7–W8 уже наблюдались. Именно здесь часто появляется утечка, даже если разбиение по времени сделано формально правильно.

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

Три expanding-window окна на 12 неделях

Expanding-window означает, что каждое следующее обучающее окно включает все предыдущие недели и добавляет новые. Такой способ хорош, когда вы хотите имитировать реальную работу: по мере накопления истории модель переобучается на большем объеме данных. В отличие от случайного деления, здесь тест всегда расположен строго правее train на временной оси.

Для 12 недель и трех окон с test_size=2 получаем такую схему:

ОкноTrainTestМомент прогноза
1W1–W6W7–W8конец W6
2W1–W8W9–W10конец W8
3W1–W10W11–W12конец W10

Это удобно по двум причинам. Во-первых, все три теста имеют одинаковую длину — по две недели, значит, ошибки можно сравнивать между окнами. Во-вторых, обучающая выборка растет: сначала 6 недель, потом 8, потом 10. Если ваша модель чувствительна к объему истории, вы увидите, как меняется качество по мере накопления наблюдений.

Учебный вывод из этой схемы: если вы видите в первом окне хотя бы один объект из W7–W8 внутри train, разбиение неверно. Если в test попали недели раньше train, разбиение неверно. Если признаки для W7–W8 были рассчитаны с использованием фактов самих W7–W8, разбиение индексов верное, но проверка прогноза все равно нечестная.

Учебный пример: индексы и проверка в Python

Учебный пример. Возьмем 12 условных недель с метками W1–W12 и построим три окна через TimeSeriesSplit в Python со средой scikit-learn. Числа здесь условные; цель примера — проверить границы разбиения, а не обучить конкретную модель.

import pandas as pd
from sklearn.model_selection import TimeSeriesSplit

weeks = pd.Index([f"W{i}" for i in range(1, 13)], name="week")
ts = TimeSeriesSplit(n_splits=3, test_size=2)

for fold, (train_idx, test_idx) in enumerate(ts.split(weeks), start=1):
    train_weeks = list(weeks[train_idx])
    test_weeks = list(weeks[test_idx])
    no_leak_by_index = max(train_idx) < min(test_idx)
    print(f"Fold {fold}")
    print(" train:", train_weeks)
    print(" test :", test_weeks)
    print(" boundary_ok:", no_leak_by_index)
    print()

Ожидаемый результат: первое окно даст train W1–W6 и test W7–W8, второе — train W1–W8 и test W9–W10, третье — train W1–W10 и test W11–W12. Проверка boundary_ok должна быть истинной во всех трех случаях, потому что максимальный индекс train меньше минимального индекса test.

Практическая польза такого мини-кода в том, что он снимает спор на уровне слов. Вместо фразы «мы вроде бы не подглядываем» вы получаете воспроизводимую схему. Ее можно приложить к ноутбуку или пайплайну и перед запуском убедиться, что окна именно такие, как вы задумали. Для учебной задачи на 12 неделях это уже достаточный, проверяемый результат.

Как проверить границы train/test и поймать утечку до обучения

Правильные индексы — только первый слой защиты. Дальше нужно проверить, что все преобразования данных подчиняются тем же границам. Самая частая ошибка — сначала посчитать признаки на всем ряде целиком, а потом делить на окна. Тогда train формально не содержит будущих недель, но признаки внутри него уже могли вобрать информацию справа от границы.

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

  • Граница времени: последний объект train раньше первого объекта test.
  • Длина теста: соответствует реальному горизонту проверки, а не выбрана случайно.
  • Доступность признаков: каждый признак можно получить на момент прогноза, не дожидаясь будущих фактов.
  • Преобразования внутри окна: масштабирование, заполнение пропусков и отбор признаков настраиваются на train каждого окна, а не на всем наборе сразу.
  • Минимальный размер train: первого окна хватает для вашей модели и признаков. Если нужны, например, длинные лаги, первых 6 недель может не хватить.

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

Когда нужен зазор между train и test

Иногда даже соседние периоды разделять вплотную опасно, и между ними нужен gap — зазор. Он полезен, когда последние наблюдения train еще не были бы доступны в момент реального прогноза или когда ваши признаки используют недавнее окно, которое пересекается с тестовым периодом по смыслу. Типичный пример — показатель, который окончательно подтверждается только через неделю после события.

Если для тех же 12 недель задать test_size=2 и gap=1, схема станет такой: train W1–W5, пропуск W6, test W7–W8; затем train W1–W7, пропуск W8, test W9–W10; затем train W1–W9, пропуск W10, test W11–W12. Зазор уменьшает объем доступного обучения, но делает эксперимент ближе к реальным условиям, когда часть самых свежих данных еще недоступна или ненадежна.

Здесь полезно помнить и обратную сторону: gap не нужен «на всякий случай». Если все признаки действительно доступны на границе прогноза и не используют данные из будущего периода, лишний зазор только сокращает train и делает оценку шумнее. Сначала опишите поток появления данных, потом решайте, нужен ли пропуск между окнами.

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

Курсы

103000
0,0
0 отзывов
Методы анализа и прогнозирования временных рядов
  • С 2 сентября
  • 4 месяца
  • самостоятельно
  • сертификат
3 600 ₽3 600 ₽
Перейти на сайт