Курс
Представьте, что вы прогнозируете ежемесячный спрос на электроэнергию. У вас есть надёжная модель ARIMA, которая учитывает автокорреляцию и тренд ряда. Вдруг накрывает жара — и ваш прогноз промахивается на 15%. Ряд не изменился; изменилась погода. Именно для таких ситуаций и создан ARIMAX: прогнозирование временных рядов, когда внешние факторы объясняют не меньше вариации, чем собственная история ряда.
Разберём, что такое ARIMAX, чем он отличается от ARIMA и SARIMAX, и когда имеет смысл использовать ту или иную модель. Также пройдём полный путь реализации на Python: подготовка данных, обучение модели, диагностика и оценка прогноза — чтобы вы могли применить это на практике.
Что такое ARIMAX?
ARIMAX расшифровывается как AutoRegressive Integrated Moving Average with eXogenous variables. Это модель ARIMA, которая также принимает внешние входы — предикторы вне самого целевого ряда. Примеры: рекламные расходы, температура, флаги промоакций, процентные ставки.
Обозначение: ARIMAX(p, d, q) с одним или несколькими экзогенными регрессорами. Параметры p, d и q имеют тот же смысл, что и в ARIMA: порядок авторегрессии, степень дифференцирования и порядок скользящего среднего. «X» означает, что можно передать дополнительные столбцы, которые, по вашему мнению, влияют на цель. Важно отметить: некоторые пакеты реализуют ARIMAX как регрессию с ошибками ARIMA, а не как прямой ввод внешних переменных в AR-часть. Математически различие тонкое, но оно влияет на интерпретацию коэффициентов. Мы вернёмся к этому, когда посмотрим на вывод statsmodels.
Как работает ARIMAX
ARIMAX сочетает две вещи: «память» самого ряда и объясняющую силу внешних переменных.
Компоненты AR, I и MA
Компонент AR (авторегрессионный) использует лаговые значения целевого ряда для предсказания текущего значения. Если в прошлом месяце продажи были высокими — это важно.
Компонент I (интегрированный) дифференцирует ряд, чтобы убрать тренды или единичные корни и сделать его стационарным.
Компонент MA (скользящее среднее) использует прошлые ошибки прогноза, чтобы корректировать систематические промахи модели.
Вместе эти три элемента покрывают большую часть факторов типичного временного ряда: тренды, циклы и автокорреляцию в остатках.
Роль внешних переменных
Экзогенные переменные добавляют информацию, которой в истории ряда нет. Если вы прогнозируете продажи, прошлые продажи отражают типичные паттерны. Но снижение цены или выход конкурента — новая информация. Модель оценивает коэффициент для каждого внешнего предиктора, одновременно учитывая автокорреляцию в ошибках.
Практически это так: если ваш целевой ряд хорошо объясняется собственными прошлыми значениями и у вас нет надёжных внешних предикторов, скорее всего, достаточно обычной ARIMA. Но когда вы знаете, что действуют внешние факторы, и у вас действительно будут их будущие значения, ARIMAX обычно даёт более точные прогнозы.
ARIMA vs. ARIMAX vs. SARIMAX
SARIMAX расширяет SARIMA, добавляя экзогенные переменные. На практике большинство реализаций ARIMAX в Python используют SARIMAX() из statsmodels с нулевым сезонным порядком.
Это не обходной путь, а стандартный подход. SARIMAX — хороший выбор, если в ряду есть выраженная сезонность или если нужны внешние регрессоры; он аккуратно обрабатывает и то и другое. Один нюанс: «ARIMAX» и «SARIMAX» не всегда взаимозаменяемы в разных библиотеках. В одних пакетах SARIMAX без сезонных членов и ARIMAX функционально идентичны. В других — различаются тем, как внешние переменные входят в функцию правдоподобия. Сверяйтесь с документацией вашего инструмента.
Когда использовать ARIMAX
Обычно всё упирается в одно: есть ли у вас внешние предикторы, которые правдоподобно влияют на цель, и будут ли у вас их будущие значения к моменту прогнозирования?
Ситуации, где ARIMAX приносит пользу
Хорошие кандидаты: прогноз продаж с флагами промоакций или изменениями цены, спрос на энергию с температурой, трафик сайта с расходами на кампании, экономические индикаторы вместе с данными по ставкам. Во всех случаях внешняя переменная даёт информацию, которую сам ряд не генерирует.
Обычная ARIMA может быть достаточной, когда внешние предикторы недоступны, ненадёжны или попросту не улучшают точность на отложенной выборке. Добавление предикторов, которые вносят шум без сигнала, не помогает. Больше входов не гарантирует лучших прогнозов. Оценивайте любой претендент-предиктор на отложенных данных, прежде чем включать его.
Пару слов о причинности
Связь между предиктором и целью не устанавливает причинность. ARIMAX — это рамка для прогнозирования; она оценивает ассоциации. Если расходы на рекламу коррелируют с продажами, потому что оба растут в декабре, модель это уловит, но не скажет, что рост вызвала реклама. Это различие важно, если вы используете прогнозы для принятия решений, а не просто предсказываете исходы. Стоит проговаривать это при представлении результатов.
Как построить модель ARIMAX в Python
Переходим к реализации.
Возьмём воспроизводимый пример: ежемесячные продажи мороженого (единиц продано) с температурой (°C) и флагом промоакции в качестве экзогенных предикторов. Набор данных охватывает 48 месяцев, из них 36 — обучение и 12 — оценка.
Подготовьте данные
Начните с загрузки или конструирования DataFrame с согласованным ежемесячным индексом дат. Определите целевую переменную и экзогенные столбцы, затем выровняйте всё по дате. Обработайте пропуски до разбиения. Не выполняйте импутацию через границу train/test — это приведёт к утечке.
Правило, которое важно усвоить: какие бы экзогенные значения вы ни подавали при обучении, эквивалентные будущие значения понадобятся при прогнозе. Если вы не можете получить прогноз температуры на будущее, вы не можете использовать температуру как предиктор. Это не мелкая оговорка — она отсеивает множество кандидатов.
import pandas as pd
import numpy as np
from statsmodels.tsa.statespace.sarimax import SARIMAX
from statsmodels.tsa.stattools import adfuller
from sklearn.metrics import mean_absolute_error
# Construct a sample monthly dataset
np.random.seed(42)
dates = pd.date_range(start="2020-01", periods=48, freq="MS")
temperature = 15 + 10 * np.sin(np.linspace(0, 4 * np.pi, 48)) + np.random.normal(0, 1, 48)
promotion = np.where((np.arange(48) % 6 == 0), 1, 0)
sales = (
500
+ 8 * temperature
+ 150 * promotion
+ np.cumsum(np.random.normal(0, 10, 48))
)
df = pd.DataFrame({"sales": sales, "temperature": temperature, "promotion": promotion}, index=dates)
# Train/test split
train = df.iloc[:36]
test = df.iloc[36:]
Масштабирование обычно не требуется для оценивания в statsmodels, но помогает численной устойчивости, когда предикторы сильно различаются по шкале. Решение о масштабировании — вопрос суждения.
Проверьте ряд и предикторы
Перед выбором параметров модели изучите целевой ряд визуально и выполните тест на стационарность. Стандарт — расширенный тест Дики-Фуллера (ADF). Значение p ниже 0,05 говорит, что ряд стационарен и, вероятно, дифференцирование не нужно (d=0). Если у ряда явный тренд, обычно выбирают d=1. Тесты — лишь одна из опор; важны также предметные знания и визуальный анализ.
Проверьте и предикторы: выровнены ли они с целью? Нет ли риска, что предиктор измерен после даты прогноза? Флаг промоакции, установленный до начала месяца, — нормально. Выручка за этот же месяц — нет.
Выберите кандидатные параметры и обучите модель
Графики ACF и PACF подскажут кандидаты для p и q. Существенный пик на лаге 1 в PACF при затухающем ACF часто указывает на AR(1); обратная картина — на MA(1). Сравните небольшой набор кандидатов по AIC или BIC на обучающих данных, а тестовую выборку оставьте только для финальной оценки.
# Fit ARIMAX(1,1,1) via SARIMAX with no seasonal order
exog_train = train[["temperature", "promotion"]]
exog_test = test[["temperature", "promotion"]]
model = SARIMAX(
train["sales"],
exog=exog_train,
order=(1, 1, 1),
seasonal_order=(0, 0, 0, 0),
trend="n"
)
result = model.fit(disp=False)
print(result.summary())
Вывод summary() показывает коэффициенты ARIMA вместе с коэффициентами для внешних переменных. Коэффициент при температуре показывает, насколько изменение температуры на один градус связано с изменением уровня продаж после того, как авторегрессионная структура учла собственную инерцию ряда. Важно знать: statsmodels использует формулировку «регрессия с ошибками ARIMA», что означает, что дифференцирование (d=1) применяется к процессу ошибок, а не к самой регрессионной части. Коэффициент отражает эффект на уровень продаж вне зависимости от d. В формулировке ARIMAX с передаточной функцией (transfer function), применяемой в некоторых других пакетах, d=1 означал бы, что коэффициенты отражают эффекты на изменения, а не на уровни. Это частая ловушка, поэтому стоит проверить документацию используемого инструмента.
Проверьте остатки и оцените прогнозы
Остатки должны напоминать белый шум. Проверьте ACF остатков на наличие оставшейся автокорреляции. Значимые пики означают, что модель упускает структуру. Если видите систематические паттерны на сезонных лагах, переходите к SARIMAX с сезонным порядком.
# Generate out-of-sample predictions
predictions = result.forecast(steps=12, exog=exog_test)
# Evaluate
mae = mean_absolute_error(test["sales"], predictions)
# Naive baseline: forecast each period using the previous period's actual value
naive_forecast = np.concatenate([[train["sales"].iloc[-1]], test["sales"].values[:-1]])
naive_mae = mean_absolute_error(test["sales"], naive_forecast)
print(f"ARIMAX MAE: {mae:.1f}")
print(f"Naive MAE: {naive_mae:.1f}")
Сравните MAE ARIMAX с наивной базовой линией (прогноз — значение предыдущего периода). Если ARIMAX не превосходит наивную модель на тесте, это значимый результат: дополнительная сложность не оправдана. Такое случается чаще, чем можно ожидать, особенно когда экзогенные предикторы шумнее, чем кажутся внутри выборки.
Прогнозируйте будущие значения
Прогноз за пределами обучающего периода делается так же, как и вневыборочная оценка: передайте будущие экзогенные значения вместе с вызовом forecast(). Для флагов промоакций это обычно несложно, так как промокалендарь известен заранее. Для температуры обычно используют прогноз погоды или исторические сезонные средние.
Важно не забыть: доверительные интервалы, которые возвращает statsmodels, условны на тех значениях предикторов, которые вы подаёте. Они не учитывают неопределённость самих предикторов. Если прогноз температуры неопределён, реальная неопределённость прогноза шире, чем показывают интервалы. Это стоит донести до тех, кто может принимать решения на их основе.
Типичные сложности и ограничения
Выше описан «счастливый путь». Вот где обычно возникают проблемы.
- Будущие предикторы могут быть неизвестны: это самый частый практический барьер. Если вы не можете надёжно получить будущие значения экзогенных переменных, использовать их нельзя. Прогноз спроса на энергию с завтрашней температурой требует прогноза температуры, а не вчерашней.
- Предикторы могут приводить к утечке: Переменная, измеренная после даты прогноза, может сделать вашу оценку на обучении намного лучше, чем в реальности. Будьте внимательны к тому, каким временным меткам соответствуют ваши предикторы.
- Связи могут меняться: коэффициенты, оценённые на исторических данных, могут не сохраниться в будущем. Эластичность цены, стабильная два года, может сдвинуться после рыночного шока, а 2024 и 2025 годы таких шоков дали достаточно, чтобы это перестало быть теорией. Переобучать модель периодически — хорошая практика.
- Коррелированные предикторы усложняют интерпретацию: сильная коллинеарность делает оценки отдельных коэффициентов нестабильными. Это не всегда вредит точности прогноза, но мешает понять, какой предиктор «делает работу».
- Больше входов не гарантирует лучшие прогнозы: оценивайте каждый предлагаемый предиктор против базовой линии на отложенных данных. Некоторые признаки, которые выглядят информативно на обучении, вносят шум на тесте.
- Сезонность требует сезонных членов: если в ряду есть стабильная сезонность, например, всплеск в декабре, нужен SARIMAX с сезонным порядком. Один ARIMAX этого не поймает.
- Причинность не устанавливается: повторим: ARIMAX — это метод прогнозирования, а не причинно-следственный анализ. Не используйте знаки коэффициентов для причинных утверждений без дополнительного исследования.
Выводы
ARIMAX оправдан, когда есть внешние факторы, действительно влияющие на цель, и вы можете предоставить их будущие значения во время прогноза. Это естественное расширение ARIMA, а не её замена. Если ваш ряд «послушный» и надёжных предикторов нет, начинать обычно лучше с ARIMA. Добавление переменных создаёт ощущение прогресса. Порой это не так.
Рабочий процесс сводится к четырём вещам, сделанным качественно:
- корректно выровняйте предикторы,
- проверьте утечки до оценки,
- валидируйте на действительно отложенных данных,
- всегда сравнивайте с простой базовой линией.
Модель ARIMAX, которая едва превосходит наивный прогноз, не лучше наивного прогноза. Она просто дороже.
Если хотите глубже разобраться в основах временных рядов, наш курс Time Series Analysis in Python подробно рассматривает ARIMA, стационарность и диагностику. А курс Introduction to Regression with statsmodels in Python поможет выстроить статистическую интуицию, необходимую для интерпретации сводок модели и проверки остатков.
Винод Чугани начал карьеру в Токио как самый молодой руководитель отдела продаж хедж‑фондов в JPMorgan, позже установил индивидуальный рекорд по продажам в Lehman Brothers, затем построил дистрибуционный бизнес электроники в 30 странах с выручкой свыше 100 млн сингапурских долларов, прежде чем переключиться на сферу данных. Выпускник по экономике из Duke и выпускник NYC Data Science Academy, он стал одним из трёх стипендиатов из более чем 100 заявителей на курс Hugo Bowne-Anderson "Building AI Applications" на платформе Maven. Сегодня он пишет для DataCamp, KDnuggets, Machine Learning Mastery и Statology на темы от статистики до агентного ИИ и наставляет специалистов по данным в NYC Data Science Academy, проведя более 1000 индивидуальных сессий.
FAQs
В чём разница между ARIMAX и ARIMA?
ARIMA строит прогнозы целевого ряда, используя только его собственные прошлые значения и прошлые ошибки прогноза. ARIMAX расширяет это, включая экзогенные переменные — внешние входы вроде температуры, промоакций или процентных ставок, — которые, как считается, влияют на цель. Если эти внешние факторы действительно определяют вариацию вашего ряда и вы можете предоставить их будущие значения, ARIMAX обычно даст более точные прогнозы, чем одна ARIMA.
Чем ARIMAX отличается от SARIMAX?
ARIMAX работает с внешними переменными, но не учитывает сезонные паттерны. SARIMAX добавляет сезонные члены AR, дифференцирования и MA поверх ARIMAX, что делает его правильным выбором, когда ваш ряд имеет повторяющуюся сезонную структуру. В statsmodels для Python ARIMAX обычно реализуется через SARIMAX() с сезонным порядком (0, 0, 0, 0). В этой конфигурации функционально это одна и та же модель.
Нужно ли предоставлять будущие значения экзогенных переменных для прогноза с ARIMAX?
Да — это одно из важнейших практических ограничений. При генерации прогнозов за пределами обучающего периода вы должны предоставить значения для каждой экзогенной переменной на каждый будущий шаг. Для флагов промоакций или индикаторов праздников это обычно просто. Для таких переменных, как температура или цены на сырьё, понадобятся прогнозные значения или разумные допущения, что вносит дополнительную неопределённость.
Как выбрать p, d и q для модели ARIMAX?
Начните с графиков ACF и PACF (дифференцированного) целевого ряда. Значимый пик на лаге 1 в PACF при затухающем ACF часто указывает на AR(1); обратный паттерн — на MA(1). Используйте предметные знания и тест ADF, чтобы определить d. Затем сравните небольшой набор комбинаций (p, d, q) по AIC или BIC на обучающих данных. Избегайте использования тестовой выборки на этапе подбора — её следует применять только для финальной оценки.
Что означает коэффициент при экзогенной переменной в модели ARIMAX?
Коэффициент представляет собой оценённое изменение уровня целевого ряда, связанное с увеличением данного предиктора на одну единицу, после учёта авторегрессионной структуры. В statsmodels это верно даже при d=1, потому что дифференцирование применяется к процессу ошибок, а не к регрессионному уравнению (формулировка «регрессия с ошибками ARIMA»). Некоторые другие пакеты используют формулировку с передаточной функцией, где при d=1 коэффициенты отражали бы влияние на изменения, а не на уровни, поэтому проверяйте документацию вашего инструмента. Интерпретация также усложняется, когда предикторы на разных шкалах или коррелируют между собой, поэтому имеет смысл стандартизировать входы, если важно сравнивать коэффициенты.
Как обнаружить и обработать мультиколлинеарность среди экзогенных предикторов?
Рассчитайте фактор инфляции дисперсии (VIF) для каждого предиктора до обучения. Значения выше 10 указывают на проблемную коллинеарность. В таком случае попробуйте удалить наименее теоретически обоснованный предиктор или объедините коррелирующие переменные в один составной признак. Сильная коллинеарность не обязательно ухудшит точность прогноза, но сделает отдельные коэффициенты ненадёжными и трудными для интерпретации.
Как оценить, действительно ли ARIMAX добавляет ценность?
Всегда сравнивайте с простой базовой линией — хороший старт это наивный прогноз (значение предыдущего периода). Если ARIMAX не превосходит его на отложенных тестовых данных, модель не окупает свою сложность. MAE и RMSE — разумные метрики; MAE проще объяснить стейкхолдерам. Сравнение проводите на корректном тестовом наборе, который не использовался при выборе параметров.
Когда следует использовать SARIMAX вместо ARIMAX?
Используйте SARIMAX, когда ваш ряд показывает стабильную сезонность — ежемесячные продажи с пиком в декабре, еженедельный веб-трафик с всплеском по понедельникам и т. п. SARIMAX добавляет сезонные компоненты AR, дифференцирования и MA, которых нет в ARIMAX. Поскольку в Python statsmodels всё равно реализует ARIMAX через SARIMAX(), практический вопрос — установить ли ненулевой сезонный порядок. Если после подгонки ARIMAX остатки показывают значимую автокорреляцию на сезонных лагах, это сигнал добавить сезонные члены.
