Временные ряды и прогнозирование
Временные ряды (time series): декомпозиция на тренд и сезонность, наивные бейзлайны, лаговые фичи, walk-forward валидация и почему random split для рядов — утечка данных.
Интуиция
Временной ряд — это наблюдения, упорядоченные во времени: продажи по дням, нагрузка на сервер по минутам, курс валюты. От обычной табличной задачи он отличается двумя вещами: порядок важен (перемешать строки нельзя — время потечёт вспять) и наблюдения зависимы (продажи сегодня похожи на вчерашние). Обе особенности ломают привычные привычки: и подготовку фичей, и валидацию.
Классический способ думать о ряде — декомпозиция (decomposition) на три компоненты:
Тренд — медленное движение уровня (бизнес растёт), сезонность — повторяющийся узор (по субботам продажи выше), остаток — шум, который не объясняется ни тем, ни другим. Хорошая модель ловит первые две компоненты и не пытается выучить третью.
Бейзлайны, которые стыдно проигрывать
Прежде чем строить что-то умное, обязательны наивные прогнозы:
- Naive: завтра = сегодня. Последнее известное значение тянется на весь горизонт.
- Seasonal naive: завтра = неделю назад (для недельной сезонности). Часто на удивление силён.
- Скользящее среднее (moving average): среднее последних k точек — сглаживает шум, но игнорирует тренд и сезонность.
Если ваша нейросеть проигрывает seasonal naive — у вас нет модели, у вас есть дорогой генератор случайных чисел. На собеседовании фраза «сначала я построю naive-бейзлайн» звучит как признак зрелости.
Фичи и валидация: только из прошлого
ML-подход к рядам — превратить прогноз в обычную табличную задачу. Фичи для точки t:
- Лаги (lags): y(t−1), y(t−7), y(t−28) — значения ряда в прошлом;
- Скользящие агрегаты: среднее/минимум/максимум за последние 7 или 30 дней;
- Календарные признаки: день недели, месяц, праздники, промо-акции.
Железное правило: каждая фича вычисляется только из данных до момента t. Скользящее среднее, центрированное на t (окно захватывает будущее), — уже утечка данных. Тот же вопрос задаём внешним признакам: фактическая погода в день прогноза известна не будет — можно брать только прогноз погоды, каким он был в момент предсказания.
Валидация — та же логика. Random split перемешивает будущее в train, и модель получает нечестно низкую ошибку: она интерполирует между известными соседями вместо экстраполяции. Правильно — сплит по времени: обучение на прошлом, проверка на будущем. Ещё честнее — walk-forward (расширяющееся окно): обучаемся на данных до точки k, прогнозируем следующий отрезок, сдвигаем границу, повторяем и усредняем ошибку по всем отрезкам.
Чем прогнозируют на практике
- Экспоненциальное сглаживание (exponential smoothing): прогноз — взвешенное среднее прошлого, свежие точки весят больше; версии с трендом и сезонностью (Holt-Winters).
- ARIMA: следующая точка — линейная комбинация прошлых значений (авторегрессия) и прошлых ошибок, после устранения тренда разностями. Идея важнее формул: ряд объясняется собственным прошлым.
- Prophet: декомпозиция «тренд + сезонности + праздники» с удобным API — быстрый сильный бейзлайн для бизнес-рядов.
- Градиентный бустинг на лаговых фичах — рабочая лошадка индустрии: легко добавлять внешние признаки (цены, промо, погоду), одна модель на тысячи рядов.
- Нейросети и трансформеры для рядов — оправданы, когда рядов и данных очень много; на одном коротком ряде почти всегда проигрывают классике и бустингу.
Качество меряют MAE (средняя абсолютная ошибка, в единицах ряда) и MAPE (в процентах — удобно сравнивать ряды разного масштаба). И помните про горизонт: чем дальше прогноз, тем больше накапливается неопределённость — ошибка на 30 дней вперёд всегда хуже, чем на 7. Поэтому горизонт выбирают от бизнес-задачи (на сколько дней вперёд реально принимаются решения), а метрику считают отдельно по каждому шагу горизонта: усреднённое по 30 дням число прячет тот факт, что первая неделя предсказывается отлично, а последняя — на уровне подбрасывания монетки.
- «Как валидировать модель прогноза продаж?» — только сплит по времени, лучше walk-forward: несколько последовательных отрезков «обучение на прошлом — проверка на будущем».
- «Почему naive-бейзлайн обязателен?» — он задаёт планку почти бесплатно; сложная модель, не бьющая seasonal naive, не даёт ценности.
- «Какие фичи нельзя брать?» — всё, что использует данные после момента предсказания: центрированные окна, агрегаты за «весь период», статистики, посчитанные по всему ряду до сплита.
- «Чем бы прогнозировали 10 000 рядов товаров?» — бустинг на лагах и календарных фичах: одна модель на все ряды, внешние признаки добавляются тривиально.