Прогноз нейросетями: LSTM и обзор
Разбираемся, как нейросети прогнозируют ряды, что такое LSTM и когда тяжёлая артиллерия действительно нужна.
LSTM — рекуррентная нейросеть с механизмом «памяти» (ячейкой состояния и вентилями), способная улавливать длинные зависимости в последовательностях.
Зачем нейросети для рядов
ARIMA и сглаживание линейны и одномерны. Когда зависимости нелинейны, рядов много и они связаны (тысячи товаров, сотни магазинов), а признаков целый ворох, нейросети начинают выигрывать. Они учат сложные паттерны напрямую из данных. Но это дорого: нужно много данных, тщательная настройка и инфраструктура. Для одного короткого ряда нейросеть почти всегда проигрывает простому Хольту-Винтерсу.
Ключевое слово здесь — масштаб. Если у вас один ряд продаж за два года, нейросеть не на чем учиться: классика обыграет её и по точности, и по стоимости. Но если у ритейлера тысячи товаров в сотнях точек, картина меняется. Спрос на молоко в одном магазине похож на спрос в соседнем; продажи зонтов коррелируют с дождём; новый товар без истории можно прогнозировать по поведению похожих товаров. Одна большая нейросеть учится сразу на всём этом массиве и переносит знание между рядами — это называют global-моделью, и для классики такой трюк недоступен.
Второй драйвер — богатство признаков. В реальном спросе намешано множество факторов: цена, скидка, день недели, погода, остаток на складе, активность конкурентов, рекламный бюджет. Линейная модель с этим справляется плохо, потому что эффекты нелинейны и переплетены: скидка работает иначе в выходные, чем в будни, и иначе на дорогих товарах, чем на дешёвых. Нейросеть впитывает такие взаимодействия автоматически, без ручного конструирования каждой комбинации признаков.
Как ряд подаётся в сеть
Рекуррентную сеть кормят окнами-последовательностями: берут L подряд идущих точек как вход и следующую точку как цель. Скользящее окно нарезает ряд на множество таких обучающих примеров.
series = [1, 2, 3, 4, 5, 6, 7, 8]
L = 3 # длина входной последовательности
samples = []
for i in range(len(series) - L):
x = series[i:i+L]
y = series[i+L]
samples.append((x, y))
for x, y in samples:
print("вход:", x, "-> цель:", y)
Вывод:
вход: [1, 2, 3] -> цель: 4 вход: [2, 3, 4] -> цель: 5 вход: [3, 4, 5] -> цель: 6 вход: [4, 5, 6] -> цель: 7 вход: [5, 6, 7] -> цель: 8
Так одномерный ряд превращается в набор пар «последовательность → следующее значение». Сеть учится по этим парам, а на инференсе ей подают последние L точек и получают прогноз. Реальный код использует PyTorch/TensorFlow, который в браузере не запустить.
Длина окна L — важный гиперпараметр. Сделаете окно слишком коротким — сеть не увидит сезонный цикл и не сможет его учесть; слишком длинным — резко вырастет число параметров и потребность в данных, а обучение замедлится. Обычно L выбирают так, чтобы окно покрывало хотя бы один полный период сезонности: для дневного ряда с недельным ритмом это минимум 7 точек, а лучше несколько недель. Заметьте также, что нарезка окон сокращает выборку на L точек — короткому ряду после такой нарезки попросту не из чего учиться.
import torch.nn as nn
class Forecaster(nn.Module):
def __init__(self, hidden=32):
super().__init__()
self.lstm = nn.LSTM(input_size=1, hidden_size=hidden, batch_first=True)
self.head = nn.Linear(hidden, 1)
def forward(self, x):
out, _ = self.lstm(x)
return self.head(out[:, -1, :]) # прогноз по последнему шагу
Архитектура минимальна: слой LSTM прокатывает последовательность и хранит внутреннее состояние, а линейная «голова» превращает финальное состояние в одно число — прогноз. Параметр hidden задаёт размер памяти сети: больше нейронов — выше ёмкость и риск переобучения, меньше — модель проще и устойчивее. Брать прогноз именно из последнего шага (out[:, -1, :]) логично: к нему сеть уже «прочитала» всю историю окна и накопила нужный контекст.
Семейство архитектур
| Модель | Идея |
| LSTM / GRU | рекуррентная память последовательности |
| 1D-CNN | свёртки по времени, ловят локальные паттерны |
| Transformer (Informer и др.) | внимание на длинные зависимости |
| N-BEATS / NHITS | специализированы под прогноз рядов |
LSTM и GRU — классика рекуррентного подхода, надёжная, но медленная из-за последовательной обработки шаг за шагом. Свёрточные 1D-CNN считаются параллельно и хорошо ловят локальные формы вроде коротких всплесков. Трансформеры через механизм внимания связывают далеко отстоящие точки напрямую и сейчас задают тон в длинногоризонтном прогнозе. А N-BEATS и NHITS созданы специально под временные ряды и нередко бьют универсальные архитектуры на бенчмарках, оставаясь при этом частично интерпретируемыми.
Как работает под капотом
LSTM хранит ячейку состояния, проходящую сквозь время почти без изменений, и три вентиля (забывания, входной, выходной), которые решают, что запомнить и что выдать. Это спасает от затухания градиента, мучившего простые RNN, и позволяет помнить события за десятки шагов. Обучение идёт обратным распространением во времени: ошибка прогноза прокатывается назад по всей развёрнутой последовательности.
Разберём роль вентилей чуть подробнее. Вентиль забывания решает, какую долю старой памяти стереть; входной — сколько новой информации с текущего шага записать; выходной — что из накопленного отдать наружу как ответ. Каждый вентиль — это маленькая обучаемая функция, выдающая числа от 0 до 1, то есть «ворота», которые сеть сама учится открывать и закрывать в нужный момент. Благодаря почти линейному пути ячейки состояния градиент при обратном распространении не затухает экспоненциально, как в простых RNN, и сеть реально дотягивается до зависимостей за многие шаги назад — например, до прошлого понедельника или до того же дня в прошлом году.
Частые ошибки
- Брать нейросеть для одного короткого ряда — простые модели тут точнее и дешевле.
- Забыть нормировать вход — сети чувствительны к масштабу признаков.
- Нарезать окна с заглядыванием в будущее — та же утечка, что и везде.
- Считать параметры нормировки по всему ряду, включая тест, — статистики из будущего утекают в обучение.
- Гнаться за сложной архитектурой, не проверив сначала простой бейзлайн на честном бэктесте.
Итоги
- Нейросети оправданы при множестве связанных рядов, нелинейностях и обилии признаков.
- Ряд подаётся окнами-последовательностями «вход → следующая точка».
- LSTM помнит длинные зависимости через ячейку состояния и вентили.
- Длину окна выбирают под период сезонности, а перед обучением входы нормируют.