ARIMA: классический метод прогнозирования временных рядов
Что такое ARIMA
ARIMA (AutoRegressive Integrated Moving Average) — классическая модель для прогнозирования временных рядов. Расшифровка:
- AR (AutoRegressive) — текущее значение зависит от прошлых значений.
- I (Integrated) — differencing для получения стационарности.
- MA (Moving Average) — текущее значение зависит от прошлых ошибок прогноза.
ARIMA записывается как ARIMA(p, d, q), где p — порядок AR, d — порядок differencing, q — порядок MA.
Разработана Box и Jenkins в 1970-х, до сих пор используется как baseline во многих forecasting задачах.
Когда применять ARIMA
ARIMA хорошо работает для:
- Стационарных (или легко приводимых к стационарности) рядов.
- Без сильной сезонности (или с SARIMA для сезонных).
- Univariate (одна временная переменная).
- Относительно короткие горизонты прогноза.
Плохо для:
- Сложные нелинейные паттерны.
- Множественные внешние факторы.
- Очень длинные ряды (10 000+ точек — ML подходы лучше).
- Intermittent demand (много нулей).
В product analytics ARIMA хороша для прогнозирования DAU, revenue, orders — когда паттерн относительно стабилен.
Компоненты: AR, I, MA
AR(p). Autoregressive.
y_t = c + φ₁·y_(t-1) + φ₂·y_(t-2) + ... + φ_p·y_(t-p) + ε_tТекущее значение — линейная комбинация p прошлых значений плюс шум. Если продажи этой недели зависят от прошлых 2 недель, AR(2).
I(d). Integrated = differencing.
Если ряд не стационарен, берём разности.
y'_t = y_t - y_(t-1) # d=1
y''_t = y'_t - y'_(t-1) # d=2Обычно d=1 достаточно. Тренды ряды становятся стационарными после одной разности.
MA(q). Moving Average.
y_t = c + ε_t + θ₁·ε_(t-1) + ... + θ_q·ε_(t-q)Текущее значение зависит от q прошлых ошибок. «Корректирует» модель на основе recent errors.
Как определить p, d, q
d (differencing). Тест стационарности (Augmented Dickey-Fuller).
from statsmodels.tsa.stattools import adfuller
result = adfuller(y)
print(f'ADF statistic: {result[0]}')
print(f'p-value: {result[1]}')
# p < 0.05 → ряд стационаренЕсли p-value > 0.05, применяем diff() и тестируем снова.
p и q. ACF и PACF графики.
from statsmodels.graphics.tsaplots import plot_acf, plot_pacf
plot_acf(y) # помогает определить q
plot_pacf(y) # помогает определить pЭмпирические правила:
- Если PACF имеет резкий cutoff после lag p, а ACF затухает → AR(p).
- Если ACF cutoff после lag q, PACF затухает → MA(q).
- Оба затухают → ARMA(p,q), определять через grid search.
Практика в Python
from statsmodels.tsa.arima.model import ARIMA
# Fit модель
model = ARIMA(y_train, order=(1, 1, 1))
fitted = model.fit()
print(fitted.summary())
# Forecast на 10 периодов
forecast = fitted.forecast(steps=10)
print(forecast)
# Forecast с CI
forecast_result = fitted.get_forecast(steps=10)
mean = forecast_result.predicted_mean
ci = forecast_result.conf_int()summary() показывает коэффициенты AR/MA, их significance, AIC/BIC.
Auto-ARIMA
Вместо ручного подбора — автоматический:
from pmdarima import auto_arima
model = auto_arima(
y_train,
start_p=0, max_p=5,
start_q=0, max_q=5,
d=None, # автоматически выбирается
seasonal=False,
trace=True,
error_action='ignore',
suppress_warnings=True,
stepwise=True
)
print(model.summary())
forecast = model.predict(n_periods=10)auto_arima перебирает комбинации (p, d, q), минимизирует AIC, возвращает лучшую модель. Очень удобно для первой итерации.
SARIMA для сезонных
SARIMA — ARIMA с сезонностью. Параметры: (p, d, q) × (P, D, Q)s, где s — период сезонности (12 для месячных, 7 для дневных с недельной сезонностью).
from statsmodels.tsa.statespace.sarimax import SARIMAX
model = SARIMAX(
y_train,
order=(1, 1, 1),
seasonal_order=(1, 1, 1, 12) # годовая сезонность
)
fitted = model.fit()
forecast = fitted.forecast(steps=12)Большинство бизнес-рядов имеют сезонность — SARIMA чаще используется, чем базовая ARIMA.
Альтернативы
Exponential Smoothing (ETS). Старый метод, но часто competitive. Holt-Winters для tрендов и сезонности. Проще ARIMA, хорошо работает out-of-the-box.
Prophet (Facebook). Декомпозиция на тренд, сезонность, праздники. Handle missing data. Хорошо для business time series. Но «чёрный ящик» сравнительно.
LSTM / Deep Learning. Для сложных паттернов и множества features. Нужен большой объём данных.
Gradient Boosting (LightGBM, XGBoost). Популярный подход — делают fe из time features (lag, rolling means) и учат boosting. Часто побеждает ARIMA на Kaggle.
Neural Prophet. Prophet + neural нетwork. Хорошая combination для больших данных.
Современные практики: начать с ARIMA/Prophet как baseline, потом пробовать ML при наличии data.
Временные ряды — важная тема для аналитиков в finance, ops, marketing. В тренажёре Карьерник есть задачи на time series analysis и forecasting.
Метрики оценки
Для train/test split используют временной split (не random):
train_size = int(len(y) * 0.8)
y_train, y_test = y[:train_size], y[train_size:]Метрики:
- MAE (Mean Absolute Error).
mean(|y - y_hat|). Интерпретируется в единицах y. - RMSE (Root Mean Squared Error).
sqrt(mean((y - y_hat)^2)). Штрафует большие ошибки. - MAPE (Mean Absolute Percentage Error).
mean(|y - y_hat| / y) * 100%. Относительная ошибка. - SMAPE. Symmetric MAPE, устойчивее к near-zero values.
Для бизнеса MAPE — наиболее интерпретируемая.
Residual diagnostics
После fit проверяем residuals (остатки = факт - прогноз):
residuals = fitted.resid
# 1. Residuals должны быть белым шумом (no autocorrelation)
from statsmodels.stats.diagnostic import acorr_ljungbox
lb_test = acorr_ljungbox(residuals, lags=[10])
# p > 0.05 — остатки похожи на белый шум, модель адекватна
# 2. Нормальность (желательно)
from scipy import stats
stat, p = stats.jarque_bera(residuals)
# 3. Visual inspection
fitted.plot_diagnostics(figsize=(15, 8))Если residuals имеют автокорреляцию — модель что-то упустила, нужно увеличить p или q.
Cross-validation для time series
Обычный k-fold не работает (leakage). Используется expanding window или rolling window:
from sklearn.model_selection import TimeSeriesSplit
tscv = TimeSeriesSplit(n_splits=5)
for train_idx, test_idx in tscv.split(y):
y_train, y_test = y[train_idx], y[test_idx]
# fit model, evaluateДаёт robust оценку performance.
Обработка пропусков
ARIMA чувствительна к пропускам. Опции:
- Forward fill (если редкие).
- Interpolation (линейная или сезонная).
- Seasonal decomposition и imputation по тренду/сезонности.
- State space models (SARIMAX handles natively).
Prophet умеет работать с пропусками из коробки — одно из преимуществ.
Типичные ошибки
Игнорирование стационарности. Fitting ARIMA на нестационарном ряде → результаты бессмысленны. Всегда проверять и differences.
Overfitting. Высокие p, q → хорошо на train, плохо на test. Используйте AIC/BIC и cross-validation.
Экстраполяция далеко. ARIMA надёжна на короткие горизонты (3-12 периодов). Дальше — CI становятся очень широкими.
Не учитывать внешние факторы. Promo, праздники, события — влияют, но ARIMA их не знает. Используйте SARIMAX с exogenous variables или Prophet с holidays.
Читайте также
FAQ
ARIMA устарела?
Для многих задач — competitive. Для сложных multi-variate — уступает ML. Но начинать с ARIMA как baseline — правильно.
Сколько данных нужно?
Минимум 50 точек для простой ARIMA. Для SARIMA — 2-3 полных цикла сезонности.
ARIMA или Prophet?
Prophet — easier, хорошо для business time series с trends/seasonality/holidays. ARIMA — more control, better для stationary-like series.
Что такое ARIMAX?
ARIMA с exogenous переменными. Например, прогноз продаж + marketing spend как X. Мощнее для случаев с внешними факторами.