Содержание
  1. Что такое временной ряд
  2. Как подготовить данные для анализа временных рядов
  3. Стационарность: главная проверка перед прогнозом
  4. Методы анализа временных рядов
  5. Пример анализа временного ряда
  6. Как проверить прогноз: валидация и метрики ошибки
  7. Три ошибки, из-за которых анализ временных рядов даёт неверный прогноз
  8. Инструменты и библиотеки для анализа временных рядов
  9. Чек-лист анализа временного ряда
  10. Заключение
  11. Частые вопросы об анализе временных рядов
СправочникОбновлено · 09.2026

Анализ временных рядов (Time Series Analysis)

13 июля 2023 · 18 минут чтения

Анализ временных рядов (Time Series Analysis) — это работа с данными, где у каждого значения есть отметка времени: продажи по дням, температура по часам, котировки по минутам. Наблюдения раскладывают на тренд, сезонность и шум, ряд проверяют на стационарность, затем строят прогноз и измеряют его ошибку на отрезке, которого модель не видела.

Коротко, что нужно знать до первой модели:

  • Порядок точек несёт информацию: перемешивать наблюдения при обучении и проверке нельзя, иначе модель обучится на будущем и будет проверена на прошлом.
  • Большинство классических моделей ждут стационарный ряд — с постоянным средним и дисперсией. Нестационарность лечат дифференцированием и стабилизацией разброса.
  • Разложение на тренд, сезонность и остаток требует данных минимум на два полных сезонных цикла.
  • Выбор модели диктует сам ряд: длина истории, число сезонных циклов, регулярность шага, наличие нулей в значениях.
  • Метрика ошибки выбирается под данные: MAPE ломается на рядах, где встречается ноль.

Дальше — по порядку: из чего состоит временной ряд, как подготовить данные, как проверить стационарность, какие методы и модели существуют, как оценить прогноз и на чём чаще всего ошибаются. Если временные ряды нужны вам как прикладной инструмент прогноза, посмотрите также, как ИИ прогнозирует поведение клиентов в B2B и как строят модели финансового анализа и оценки рисков: обе задачи опираются на те же ряды наблюдений.

Что такое временной ряд

Временной ряд — упорядоченный набор данных, где каждое наблюдение состоит из двух частей: временной метки и значения. Примеры — цены акций на бирже, температура воздуха, ежедневные продажи в магазине, число заявок на сайте по часам.

Отличие от обычной таблицы в одном: строки связаны порядком. Значение вчерашнего дня влияет на сегодняшнее, а перестановка строк уничтожает смысл данных. Из этого следуют все дальнейшие ограничения — от способа заполнения пропусков до способа разбить данные на обучение и проверку.

Цель анализа

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

Характеристики

Характеристики ряда определяют, какие методы к нему применимы. Основных четыре:

  1. Тренд — долгосрочное направление изменения ряда. Он бывает возрастающим, убывающим или отсутствовать вовсе.
  2. Сезонность — повторяющиеся изменения с фиксированным периодом: рост продаж перед праздниками, суточный профиль нагрузки, недельный цикл заявок.
  3. Цикличность — повторяющиеся колебания без фиксированного периода. Пример — бизнес-циклы длиной в несколько лет.
  4. Шум — случайные колебания, которые не объясняются ни трендом, ни сезонностью.

Пятая характеристика редко попадает в учебные списки, но решает на практике: длина истории. Ряд из двенадцати месячных точек не даст оценить годовую сезонность — на неё просто не хватает повторов.

Как подготовить данные для анализа временных рядов

Путь анализа временного ряда: от сырых наблюдений до проверенного прогноза
Путь анализа временного ряда: от сырых наблюдений до проверенного прогноза

Подготовка занимает больше времени, чем сама модель, и ошибки на этом шаге дальше не исправляются.

Шаг ряда должен быть регулярным. Классические модели ждут наблюдения через равные интервалы. Нерегулярные данные приводят к нужной частоте агрегацией: в pandas за это отвечает метод resample, документация описывает его как «Resample time-series data» и требует, чтобы «The object must have a datetime-like index (DatetimeIndex, PeriodIndex, or TimedeltaIndex)». Смысл требования простой: библиотека должна распознавать столбец с датами как временной индекс, иначе агрегация по периодам недоступна.

Пропуски заполняются с учётом времени. Среднее по всему ряду сюда не годится — оно затирает тренд. Обычно берут соседние значения (протягивание последнего известного, линейная интерполяция) или значение того же периода прошлого цикла, если сезонность выражена.

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

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

Стационарность: главная проверка перед прогнозом

Стационарный ряд — это ряд, у которого статистические свойства не меняются во времени: среднее держится на одном уровне, разброс постоянен, связь между соседними значениями зависит только от расстояния между ними. Классические модели семейства ARIMA построены именно на таком допущении, поэтому проверка стационарности идёт раньше выбора модели.

Формальный инструмент — расширенный тест Дики — Фуллера (ADF). В библиотеке statsmodels он реализован функцией adfuller, и официальная документация формулирует его логику дословно: «The null hypothesis of the Augmented Dickey-Fuller is that there is a unit root, with the alternative that there is no unit root. If the pvalue is above a critical size, then we cannot reject that there is a unit root». Функция возвращает статистику теста, p-value и критические значения «at the 1 %, 5 %, and 10 % levels». Практическое чтение результата: большое p-value означает, что ряд считать стационарным оснований нет.

Нестационарный ряд приводят к стационарному двумя приёмами.

  • Дифференцирование — переход от значений к их приращениям. Убирает тренд; для сезонной составляющей берут разность с лагом сезона, например с лагом 12 для месячных данных с годовым циклом.
  • Стабилизация разброса — логарифмирование или преобразование Бокса — Кокса. Нужны, когда амплитуда колебаний растёт вместе с уровнем ряда: продажи растут вдвое, и сезонный размах растёт вдвое.

После приведения ряда смотрят автокорреляцию. Функция автокорреляции (ACF) показывает связь ряда с самим собой на разных сдвигах; в statsmodels график строит plot_acf, который, по описанию функции, «Plots lags on the horizontal and the correlations on vertical axis». Частная автокорреляция (PACF) очищает эту связь от влияния промежуточных лагов. По двум графикам подбирают порядки авторегрессии и скользящего среднего, а заодно видят период сезонности: всплеск на лаге 7 говорит о недельном цикле, на лаге 12 в месячных данных — о годовом.

Мини-вывод: связка «тест ADF → дифференцирование → графики ACF и PACF» даёт и ответ о стационарности, и стартовые параметры модели. Пропуск этого шага приводит к модели, которая красиво повторяет историю и разваливается на первом же прогнозе.

Методы анализа временных рядов

Методы делятся на две группы: описательные — они объясняют, как устроен ряд, и прогнозные — они дают будущие значения. На практике идут по порядку от первых ко вторым.

Визуальный и статистический анализ

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

Декомпозиция: разложение на тренд, сезонность и остаток

Декомпозиция разбирает ряд на составляющие. В statsmodels базовый инструмент — seasonal_decompose, «Seasonal decomposition using moving averages», и документация задаёт две модели дословно: «The additive model is Y[t] = T[t] + S[t] + e[t]», «The multiplicative model is Y[t] = T[t] * S[t] * e[t]». Аддитивная подходит, когда сезонный размах постоянен; мультипликативная — когда размах растёт вместе с уровнем ряда.

Два ограничения инструмента прописаны там же. Первое — данных должно хватать: «x must contain 2 complete cycles», то есть для годовой сезонности на месячных данных нужно минимум 24 точки. Второе — сама библиотека называет метод базовым: «This is a naive decomposition. More sophisticated methods should be preferred», и в качестве более точной альтернативы указывает STL — «Season-Trend decomposition using LOESS».

Методы сглаживания

Сглаживание убирает шум и обнажает тренд. Скользящее среднее усредняет значения в окне фиксированной ширины. Экспоненциальное сглаживание даёт свежим наблюдениям больший вес, чем старым, и в развитой форме — модели Хольта — Уинтерса — описывает уровень, тренд и сезонность одновременно. В statsmodels за неё отвечает класс ExponentialSmoothing с параметром seasonal_periods: «The number of periods in a complete seasonal cycle, e.g., 4 for quarterly data or 7 for daily data with a weekly cycle». Период сезонности здесь задаёт аналитик, поэтому ошибка в нём портит прогноз сильнее, чем выбор между аддитивной и мультипликативной формой.

Модели прогнозирования: ARIMA, SARIMA, Prophet, нейросети

ARIMA — авторегрессионная интегрированная скользящая средняя. Модель задаётся тройкой параметров: в statsmodels это «The (p,d,q) order of the model for the autoregressive, differences, and moving average components». Здесь p — сколько прошлых значений учитывать, d — сколько раз ряд продифференцировать, q — сколько прошлых ошибок включить в модель. Сезонная версия добавляет второй набор: «The (P,D,Q,s) order of the seasonal component of the model for the AR parameters, differences, MA parameters, and periodicity», по умолчанию (0, 0, 0, 0). Полная форма записывается как SARIMAX(p, d, q)x(P, D, Q, s).

Prophet — процедура прогнозирования от команды Core Data Science в Facebook, реализованная в R и Python. Официальное описание: «Prophet is a procedure for forecasting time series data based on an additive model where non-linear trends are fit with yearly, weekly, and daily seasonality, plus holiday effects. It works best with time series that have strong seasonal effects and several seasons of historical data. Prophet is robust to missing data and shifts in the trend, and typically handles outliers well». Отсюда область применения: бизнес-ряды с календарными эффектами и дырами в данных.

Машинное обучение подключают, когда прогноз зависит от внешних факторов: погоды, цен, промо-акций. Ряд превращают в таблицу признаков — лаги, скользящие статистики, календарные признаки — и обучают градиентный бустинг или регрессию. Рекуррентные нейронные сети (RNN, LSTM) применяют к длинным рядам высокой частоты и к задачам, где важна память о далёких состояниях. Устройство таких моделей разбирает отдельный материал о том, как работает машинное обучение.

Метод Что даёт Что требует от ряда Когда выбирать
Скользящее среднее Сглаженный тренд Регулярный шаг Быстрая оценка направления, база для сравнения
Декомпозиция (seasonal_decompose, STL) Тренд, сезонность, остаток Минимум два полных цикла Нужно объяснить структуру ряда
Экспоненциальное сглаживание, Хольт — Уинтерс Прогноз с трендом и сезонностью Известный период сезонности Короткая и средняя история, один устойчивый цикл
ARIMA Прогноз по прошлым значениям и ошибкам Стационарность после d дифференцирований Ряд без выраженной сезонности
SARIMA Прогноз с сезонной составляющей Стационарность и известный период s Сезонный ряд средней длины
Prophet Прогноз с праздниками и сменой тренда Несколько сезонов истории Бизнес-ряды с календарными эффектами и пропусками
Бустинг на лаговых признаках Прогноз с внешними факторами Длинная история и признаки Прогноз зависит от цен, погоды, промо
Нейросети (RNN, LSTM) Прогноз по сложным зависимостям Много данных, высокая частота Длинные ряды, много связанных рядов сразу

Мини-вывод: выбор метода задаёт сам ряд — длина истории, число полных сезонных циклов и наличие внешних факторов. Сложная модель на коротком ряде проигрывает скользящему среднему.

для id="пайтон2" двойной блок курсов не обнаружен

Пример анализа временного ряда

Разберём порядок работы на понятной задаче: есть ежемесячные продажи вина в магазине за несколько лет, нужен прогноз на следующий год. Ниже — та же последовательность шагов, что и в любом другом ряде, с указанием инструмента на каждом шаге.

  1. Привести данные к временному индексу. Столбец с датой становится индексом, частота фиксируется месячной. Пропущенные месяцы появляются явно, и их видно.
  2. Посмотреть график. На нём читаются тренд, годовой рисунок продаж и аномальные месяцы.
  3. Разложить ряд на компоненты. Для месячных данных с годовым циклом период равен 12, и для разложения нужно минимум два полных цикла — 24 наблюдения.
  4. Проверить стационарность. Тест ADF на исходном ряде, затем на продифференцированном.
  5. Обучить модель и оценить прогноз. Последние 12 месяцев откладываются как проверочный отрезок; модель обучается на остальном и сравнивается с фактом на этом хвосте.
import pandas as pd
from statsmodels.tsa.seasonal import seasonal_decompose
from statsmodels.tsa.stattools import adfuller
from statsmodels.tsa.statespace.sarimax import SARIMAX

sales = pd.read_csv("wine.csv", parse_dates=["month"], index_col="month")
sales = sales["volume"].resample("MS").sum()

decomposition = seasonal_decompose(sales, model="additive", period=12)
decomposition.plot()

stat, pvalue = adfuller(sales)[:2]
stat_diff, pvalue_diff = adfuller(sales.diff().dropna())[:2]

train, test = sales[:-12], sales[-12:]
model = SARIMAX(train, order=(1, 1, 1), seasonal_order=(1, 1, 1, 12)).fit()
forecast = model.forecast(steps=12)

Что читать в результатах. Компоненты разложения показывают, есть ли устойчивый тренд и насколько велик сезонный размах относительно уровня продаж. Пара значений p-value до и после дифференцирования отвечает на вопрос, понадобился ли параметр d. Прогноз на отложенных двенадцати месяцах сравнивается с фактом — ошибку считают именно на этом хвосте. Ошибка на обучающей части показывает только то, насколько модель запомнила историю.

Порядки (1, 1, 1) и (1, 1, 1, 12) в примере — стартовая точка, которую уточняют по графикам ACF и PACF и по перебору соседних вариантов с оценкой на проверочном отрезке. Перебор ведут по небольшой сетке значений вокруг стартовой точки, сравнивая варианты одной и той же метрикой на одном и том же проверочном хвосте.

Как проверить прогноз: валидация и метрики ошибки

Разбиение ряда по времени: обучающая выборка растёт, проверочная сдвигается вперёд
Разбиение ряда по времени: обучающая выборка растёт, проверочная сдвигается вперёд

Прогноз без проверки на отложенных данных — это гипотеза. Проверка временного ряда устроена иначе, чем проверка обычной таблицы, и разница описана в документации scikit-learn для класса TimeSeriesSplit: он «Provides train/test indices to split time-ordered data, where other cross-validation methods are inappropriate, as they would lead to training on future data and evaluating on past data».

Механика такая. Данные сортируются по времени, первый отрезок уходит в обучение, следующий — в проверку, затем граница сдвигается вперёд, и шаг повторяется. Документация фиксирует ключевое свойство: «unlike standard cross-validation methods, successive training sets are supersets of those that come before them» — каждая следующая обучающая выборка включает предыдущую целиком. По умолчанию число разбиений равно 5 (значение изменилось с 3 на 5 в версии 0.22), а размер проверочной части по умолчанию — n_samples // (n_splits + 1). Дополнительный параметр gap позволяет оставить зазор между обучением и проверкой: он нужен, когда фактические данные приходят с задержкой.

Метрику выбирают под данные.

  • MAE — средняя абсолютная ошибка в единицах ряда: понятна бизнесу, ровно взвешивает все наблюдения.
  • RMSE — корень из средней квадратичной ошибки: сильнее штрафует крупные промахи, полезна там, где дорог именно большой промах.
  • MAPE — средняя абсолютная ошибка в процентах: удобна для сравнения рядов разного масштаба, но имеет жёсткое ограничение.

Ограничение MAPE документировано у sklearn прямо: «MAPE output is non-negative floating point. The best value is 0.0. But note that bad predictions can lead to arbitrarily large MAPE values, especially if some y_true values are very close to zero. Note that we return a large value instead of inf when y_true is zero». В примере из документации на данных с одним нулевым фактическим значением метрика возвращает 112589990684262.48. Там же оговорена шкала: «Note that we are not using the common “percentage” definition: the percentage in the range [0, 100] is converted to a relative value in the range [0, 1] by dividing by 100. Thus, an error of 200% corresponds to a relative error of 2».

Мини-вывод: разбиение по времени плюс метрика, подходящая данным, дают честную оценку. Ряд с нулевыми значениями — например, продажи товара в дни отсутствия на складе — оценивают через MAE или RMSE.

Три ошибки, из-за которых анализ временных рядов даёт неверный прогноз

Эти ошибки встречаются чаще остальных и объединены одним свойством: модель показывает отличные цифры на бумаге и промахивается в проде.

1. Случайное перемешивание при разбиении. Привычный по табличным задачам приём — перетасовать строки и отрезать 20% на тест — во временных рядах ломает всё. Документация scikit-learn называет причину прямо: обычные способы кросс-валидации здесь неприменимы, поскольку «they would lead to training on future data and evaluating on past data». Модель, обученная на будущем, легко угадывает прошлое, и метрика на такой проверке ничего не значит. Лечение — разбиение по времени: TimeSeriesSplit либо простое отсечение последнего отрезка истории.

2. MAPE на ряде с нулями. Метрика делит на фактическое значение, поэтому нули и близкие к нулю значения раздувают её до величин, не связанных с качеством модели. В документации sklearn это показано числом: на примере, где одно фактическое значение равно нулю, метрика возвращает 112589990684262.48. Лечение — MAE или RMSE на таких рядах, а MAPE оставить для данных, гарантированно далёких от нуля.

3. Сезонная модель на истории короче двух циклов. Разложение и сезонные модели оценивают повторяемость, и для этого нужны повторы. Требование seasonal_decompose сформулировано в документации statsmodels буквально: «x must contain 2 complete cycles». Для месячных данных с годовой сезонностью это 24 точки, для недельного цикла в дневных данных — 14. На более короткой истории сезонная компонента становится пересказом шума. Лечение — либо укоротить период (перейти с годового цикла на недельный), либо остаться на простых моделях.

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

Инструменты и библиотеки для анализа временных рядов

Базовый стек на Python выглядит так:

  • pandas — загрузка, временной индекс, агрегация методом resample, лаги и скользящие окна.
  • statsmodels — тест adfuller, разложение seasonal_decompose и STL, графики ACF и PACF, модели ARIMA, SARIMAX и Хольта — Уинтерса.
  • scikit-learn — разбиение TimeSeriesSplit, метрики, регрессионные модели на лаговых признаках.
  • Prophet — автоматический прогноз с календарными эффектами, доступен в R и Python.

Подборка инструментов машинного обучения, которые применимы и к рядам, разобрана в материале о библиотеках для машинного обучения.

Чек-лист анализа временного ряда

  1. Собрать ряд с датой и значением, привести к регулярному шагу.
  2. Заполнить пропуски способом, который учитывает время: соседние значения или тот же период прошлого цикла.
  3. Построить график и отметить моменты смены процесса.
  4. Разложить ряд на тренд, сезонность и остаток, если истории хватает на два полных цикла.
  5. Проверить стационарность тестом ADF, при необходимости продифференцировать и стабилизировать разброс.
  6. Посмотреть графики ACF и PACF, снять с них период сезонности и стартовые порядки модели.
  7. Отложить последний отрезок истории как проверочный, обучить модель на остальном.
  8. Выбрать метрику под данные: MAE или RMSE для рядов с нулями, MAPE — для рядов, далёких от нуля.
  9. Сравнить модель с простой базой — скользящим средним или прогнозом «как в прошлом периоде».
  10. Зафиксировать порядок расчёта и повторить оценку на свежих данных через месяц.

Заключение

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

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

Частые вопросы об анализе временных рядов

Что такое анализ временных рядов простыми словами?

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

Какие методы анализа временных рядов существуют?

Описательные — визуальный анализ, описательные статистики, автокорреляция, декомпозиция на тренд, сезонность и остаток. Прогнозные — скользящее среднее, экспоненциальное сглаживание и модель Хольта — Уинтерса, ARIMA и SARIMA, Prophet, градиентный бустинг на лаговых признаках, рекуррентные нейронные сети.

Как проверить, что временной ряд стационарен?

Расширенным тестом Дики — Фуллера. В statsmodels он реализован функцией adfuller, её документация формулирует гипотезу так: нулевая гипотеза теста — наличие единичного корня, альтернативная — его отсутствие; если p-value выше критического уровня, гипотезу о единичном корне отвергнуть нельзя. Функция возвращает статистику, p-value и критические значения на уровнях 1 %, 5 % и 10 %.

Сколько данных нужно для прогноза с сезонностью?

Минимум два полных сезонных цикла: документация statsmodels для seasonal_decompose требует, чтобы ряд содержал два полных цикла. Для месячных данных с годовой сезонностью это 24 наблюдения, для недельного цикла в дневных данных — 14.

Какую метрику выбрать для оценки прогноза?

MAE и RMSE подходят любым рядам и считаются в единицах данных. MAPE удобна для сравнения рядов разного масштаба, но на значениях около нуля её результат перестаёт быть осмысленным: в примере документации scikit-learn с одним нулевым фактическим значением метрика возвращает 112589990684262.48.

Чем анализ временных рядов отличается от обычного машинного обучения?

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

Читайте также

3 материала