сеньорчикОткрыть в Telegram
← вся теориятеория к собесу · Временные ряды

Валидация моделей на временных рядах

Зачем это спрашивают

Валидация рядов - минное поле утечек: одна ошибка сплита, и метрика фантастическая, а прод мёртвый. «Как валидируешь прогноз» - вопрос, где интервьюер ждёт слов «только вперёд по времени».

// shuffle=True в сплите ряда - утечка номер один всей темы.

Только вперёд: rolling origin

Главное правило: train - до момента T, test - после. Случайный k-fold утекает будущее в прошлое, потому что соседние точки ряда почти дубли друг друга.

Rolling/expanding origin: несколько последовательных сплитов «обучились до T, предсказали T+h» - оценка стабильности по периодам вместо одной удачной точки. Тюнить гиперпараметры по одному последнему периоду - переобучение на конкретный сезон.

// Если в проде данные приходят с задержкой (вчера доступно послезавтра) - между train и test нужен gap той же величины, иначе оценка оптимистична.

rolling origin
серия сплитов вперёд по времени - бэктест
gap
зазор train/test под реальную задержку данных

Горизонт и честные фичи

Горизонт валидации равен горизонту прода: модель, хорошая на день вперёд, не обязана быть хорошей на месяц - ошибки растут с горизонтом нелинейно.

Фичи - только из прошлого относительно момента прогноза: агрегат «за 7 дней» - назад от точки предсказания. Внешние регрессоры обязаны быть реально известны заранее: погода на завтра это прогноз погоды, а не факт.

// Центрированное скользящее среднее - окно, наполовину смотрящее в будущее. В фичах - только окна, заканчивающиеся «вчера».

Метрики и срезы

MAE (mean absolute error)/RMSE (root mean squared error) - в единицах таргета; WAPE (weighted absolute percentage error) - для агрегатов «процент ошибки в деньгах»; MASE (mean absolute scaled error) - ошибка относительно наивного прогноза, честный ответ на «а лучше ли мы бейзлайна». MAPE (mean absolute percentage error) - осторожно: нули и асимметрия.

Средняя метрика прячет провалы: оценивай по сегментам (товар, регион, канал) и по горизонтам - день вперёд и месяц вперёд это разные модели с разной ошибкой.

// Репорт бизнесу: WAPE по ключевым сегментам + сравнение с наивным. «RMSE 42» без контекста не значит ничего.

MASE
ошибка относительно наивного прогноза; >1 - хуже наивного

Как отвечать: «Как будешь валидировать модель прогноза?»

Только вперёд по времени: rolling origin - серия сплитов «обучился до T, предсказал горизонт прода», смотрю стабильность метрики по периодам, а не одну точку. Горизонт валидации совпадает с продовым, между train и test - gap под реальную задержку данных. Фичи проверяю на честность: все окна заканчиваются вчера, регрессоры известны на момент прогноза. Метрики - WAPE по сегментам плюс MASE против наивного: если MASE выше единицы, модель не нужна. Случайный сплит для ряда - автоматическая утечка, соседние точки почти дубли.

Все четыре защиты от утечки плюс метрика относительно бейзлайна - полный чек-лист честного бэктеста.

На чём валят

  • shuffle=True в сплите ряда - утечка номер один.
  • Центрированное скользящее среднее - окно смотрит в будущее.
  • Тюнинг по одному последнему периоду - переобучение на конкретный сезон.
  • Валидировать на горизонте 1 шаг, прогнозировать 30 - ошибка растёт нелинейно.

Проверьте себя

Пять вопросов из банка по этой подтеме. Всего их 12, остальные разбираются в тренажёре.

  1. #ts_validation1 / 5
    Прогнозная модель дала отличные метрики на бэктесте, но в проде провалилась. Частая причина именно во временных рядах?
    A)Модель обучали на слишком мощном сервере, и на более слабом продакшене её прогнозы закономерно ухудшились
    B)В проде меньше оперативной памяти, поэтому модель временного ряда там работает заметно хуже
    C)Дело в том, что в проде поменяли язык программирования, на котором крутится модель
    D)Утечка будущего в фичи: нормализация по всему ряду или значения, недоступные на момент прогноза
    показать ответ и разбор
    +D)Утечка будущего в фичи: нормализация по всему ряду или значения, недоступные на момент прогноза

    // разбор: Классика провала прогноза — утечка будущего в признаки, незаметная на бэктесте: скейлинг/нормализация, посчитанные по всему ряду включая тест; агрегаты, задевающие будущее; фичи, которых на момент реального прогноза ещё не существует. На истории они «работают», а в проде их нет или они другие. Лечится: все статистики — только по прошлому (expanding), фичи — доступные на момент t.

  2. #ts_validation2 / 5
    StandardScaler обучили (fit) на всём ряду, потом сделали сплит по времени. Почему это утечка, хотя сплит корректный?
    A)Потому что StandardScaler не получится применять к данным временного ряда в этом случае обстоятельствах
    B)Никакой утечки нет: раз сплит по времени сделан правильно, предварительный масштаб данных уже не важен
    C)Статистики среднего и дисперсии посчитаны с учётом тестового периода — будущее просочилось в препроцессинг
    D)Потому что после масштабирования ряд обязательно перестаёт быть стационарным и модель ломается из-за этого
    показать ответ и разбор
    +C)Статистики среднего и дисперсии посчитаны с учётом тестового периода — будущее просочилось в препроцессинг

    // разбор: Даже при корректном сплите fit скейлера на всём ряду считает среднее и дисперсию по данным, включающим тестовый (будущий) период — эти статистики протекают в трейн через нормализацию. Метрика на бэктесте оказывается оптимистичной. Правильно: fit скейлера только на обучающей части (или на расширяющемся окне) и transform теста этими же параметрами. Любой fit — только по прошлому.

  3. #ts_validation3 / 5
    Признаки используют лаги и окна. Зачем между train и валидацией оставляют временной зазор (gap/embargo)?
    A)Зазор нужен лишь для ускорения обучения — так в обучающей выборке остаётся заметно меньше строк
    B)Это устаревшая практика; современные модели требуют, наоборот, максимально плотного стыка train и теста
    C)Зазор выбирают случайно ради разнообразия сплитов, и на возможную утечку он совершенно никак не влияет
    D)Окна и лаги приграничных точек теста залезают в train-период — зазор рвёт эту утечку через фичи
    показать ответ и разбор
    +D)Окна и лаги приграничных точек теста залезают в train-период — зазор рвёт эту утечку через фичи

    // разбор: Если фичи считаются по окну назад, то у точек теста сразу за границей окно частично попадает в train-период, таргеты которого модель уже видела, — утечка через перекрытие окон. Зазор (embargo) шириной с максимальное окно/горизонт выбрасывает приграничные точки, разрывая перекрытие, и делает оценку честной (особенно важно в финансах). Это про чистоту оценки, а не скорость или разнообразие.

  4. #ts_validation4 / 5
    Прогноз в проде — на 30 дней вперёд. Как это должно отражаться в схеме бэктеста?
    A)Валидировать на том же горизонте: между концом train и оцениваемой точкой держать те же 30 дней
    B)Горизонт валидации не важен: достаточно проверить прогноз на один день вперёд и потом экстраполировать
    C)Валидировать на один шаг вперёд — это даёт самую честную оценку для горизонта прогноза
    D)Горизонт вообще не влияет на бэктест: главное — взять как можно больше последовательных фолдов подряд
    показать ответ и разбор
    +A)Валидировать на том же горизонте: между концом train и оцениваемой точкой держать те же 30 дней

    // разбор: Ошибка растёт с горизонтом, и оценка на один шаг вперёд систематически оптимистична для прогноза на 30 дней. Бэктест должен воспроизводить реальную задачу: предсказывать на тот же горизонт h, оставляя между концом обучения и оцениваемой точкой те же h шагов (и не давая данные внутри окна). Иначе метрика не про ваш прод. Число фолдов вторично по сравнению с соответствием горизонта.

  5. #ts_validation5 / 5
    Гоняете десятки конфигураций по одному и тому же бэктесту и берёте лучшую. Чем это опасно?
    A)Ничем: бэктест на истории объективен, и чем больше конфигураций перебрать, тем надёжнее итоговый выбор
    B)Опасно лишь тем, что перебор занимает много времени, но на качество самого выбора это никак не влияет
    C)Переобучение под бэктест: лучшая на истории конфигурация могла выиграть случайно; на новом периоде эффект тает
    D)Это верный способ подбора, и отложенный свежий период для проверки при нём не нужен
    показать ответ и разбор
    +C)Переобучение под бэктест: лучшая на истории конфигурация могла выиграть случайно; на новом периоде эффект тает

    // разбор: Многократный подбор по одной истории — оптимизация под конкретный шум: с ростом числа проб растёт шанс, что «победитель» выиграл случайно (multiple comparisons на ряде). На новом периоде его преимущество регрессирует к среднему. Защита — отложенный поздний период (out-of-time), которого тюнинг не касался, честная кросс-валидация по времени и скромное число гипотез. Объективность истории иллюзорна, если по ней же и выбирать.

дальше

Теорию прочитали. Навык ставится повторением

В Сеньорчике эта подтема идёт в ежедневных сессиях: движок возвращает её, пока ответы не станут уверенными, и ведёт прогресс отдельно по каждой подтеме. Теория внутри тоже бесплатна, лимит только на количество вопросов в день.