Валидация моделей на временных рядах
Валидация рядов - минное поле утечек: одна ошибка сплита, и метрика фантастическая, а прод мёртвый. «Как валидируешь прогноз» - вопрос, где интервьюер ждёт слов «только вперёд по времени».
// 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, остальные разбираются в тренажёре.
- Прогнозная модель дала отличные метрики на бэктесте, но в проде провалилась. Частая причина именно во временных рядах?A)Модель обучали на слишком мощном сервере, и на более слабом продакшене её прогнозы закономерно ухудшилисьB)В проде меньше оперативной памяти, поэтому модель временного ряда там работает заметно хужеC)Дело в том, что в проде поменяли язык программирования, на котором крутится модельD)Утечка будущего в фичи: нормализация по всему ряду или значения, недоступные на момент прогноза
показать ответ и разбор
+D)Утечка будущего в фичи: нормализация по всему ряду или значения, недоступные на момент прогноза// разбор: Классика провала прогноза — утечка будущего в признаки, незаметная на бэктесте: скейлинг/нормализация, посчитанные по всему ряду включая тест; агрегаты, задевающие будущее; фичи, которых на момент реального прогноза ещё не существует. На истории они «работают», а в проде их нет или они другие. Лечится: все статистики — только по прошлому (expanding), фичи — доступные на момент t.
- StandardScaler обучили (fit) на всём ряду, потом сделали сплит по времени. Почему это утечка, хотя сплит корректный?A)Потому что StandardScaler не получится применять к данным временного ряда в этом случае обстоятельствахB)Никакой утечки нет: раз сплит по времени сделан правильно, предварительный масштаб данных уже не важенC)Статистики среднего и дисперсии посчитаны с учётом тестового периода — будущее просочилось в препроцессингD)Потому что после масштабирования ряд обязательно перестаёт быть стационарным и модель ломается из-за этого
показать ответ и разбор
+C)Статистики среднего и дисперсии посчитаны с учётом тестового периода — будущее просочилось в препроцессинг// разбор: Даже при корректном сплите fit скейлера на всём ряду считает среднее и дисперсию по данным, включающим тестовый (будущий) период — эти статистики протекают в трейн через нормализацию. Метрика на бэктесте оказывается оптимистичной. Правильно: fit скейлера только на обучающей части (или на расширяющемся окне) и transform теста этими же параметрами. Любой fit — только по прошлому.
- Признаки используют лаги и окна. Зачем между train и валидацией оставляют временной зазор (gap/embargo)?A)Зазор нужен лишь для ускорения обучения — так в обучающей выборке остаётся заметно меньше строкB)Это устаревшая практика; современные модели требуют, наоборот, максимально плотного стыка train и тестаC)Зазор выбирают случайно ради разнообразия сплитов, и на возможную утечку он совершенно никак не влияетD)Окна и лаги приграничных точек теста залезают в train-период — зазор рвёт эту утечку через фичи
показать ответ и разбор
+D)Окна и лаги приграничных точек теста залезают в train-период — зазор рвёт эту утечку через фичи// разбор: Если фичи считаются по окну назад, то у точек теста сразу за границей окно частично попадает в train-период, таргеты которого модель уже видела, — утечка через перекрытие окон. Зазор (embargo) шириной с максимальное окно/горизонт выбрасывает приграничные точки, разрывая перекрытие, и делает оценку честной (особенно важно в финансах). Это про чистоту оценки, а не скорость или разнообразие.
- Прогноз в проде — на 30 дней вперёд. Как это должно отражаться в схеме бэктеста?A)Валидировать на том же горизонте: между концом train и оцениваемой точкой держать те же 30 днейB)Горизонт валидации не важен: достаточно проверить прогноз на один день вперёд и потом экстраполироватьC)Валидировать на один шаг вперёд — это даёт самую честную оценку для горизонта прогнозаD)Горизонт вообще не влияет на бэктест: главное — взять как можно больше последовательных фолдов подряд
показать ответ и разбор
+A)Валидировать на том же горизонте: между концом train и оцениваемой точкой держать те же 30 дней// разбор: Ошибка растёт с горизонтом, и оценка на один шаг вперёд систематически оптимистична для прогноза на 30 дней. Бэктест должен воспроизводить реальную задачу: предсказывать на тот же горизонт h, оставляя между концом обучения и оцениваемой точкой те же h шагов (и не давая данные внутри окна). Иначе метрика не про ваш прод. Число фолдов вторично по сравнению с соответствием горизонта.
- Гоняете десятки конфигураций по одному и тому же бэктесту и берёте лучшую. Чем это опасно?A)Ничем: бэктест на истории объективен, и чем больше конфигураций перебрать, тем надёжнее итоговый выборB)Опасно лишь тем, что перебор занимает много времени, но на качество самого выбора это никак не влияетC)Переобучение под бэктест: лучшая на истории конфигурация могла выиграть случайно; на новом периоде эффект таетD)Это верный способ подбора, и отложенный свежий период для проверки при нём не нужен
показать ответ и разбор
+C)Переобучение под бэктест: лучшая на истории конфигурация могла выиграть случайно; на новом периоде эффект тает// разбор: Многократный подбор по одной истории — оптимизация под конкретный шум: с ростом числа проб растёт шанс, что «победитель» выиграл случайно (multiple comparisons на ряде). На новом периоде его преимущество регрессирует к среднему. Защита — отложенный поздний период (out-of-time), которого тюнинг не касался, честная кросс-валидация по времени и скромное число гипотез. Объективность истории иллюзорна, если по ней же и выбирать.
дальше
Теорию прочитали. Навык ставится повторением
В Сеньорчике эта подтема идёт в ежедневных сессиях: движок возвращает её, пока ответы не станут уверенными, и ведёт прогресс отдельно по каждой подтеме. Теория внутри тоже бесплатна, лимит только на количество вопросов в день.