ARIMA Forecasting in Python — Core Concepts
What ARIMA actually models
ARIMA stands for AutoRegressive Integrated Moving Average. Each letter group maps to a specific behavior in the data:
- AR(p) — the autoregressive part. The current value depends linearly on the p most recent values. Think of momentum: if sales have been climbing for three days, AR captures that tendency to keep climbing.
- I(d) — the integrated part. Before fitting the model, the series is differenced d times to remove trends. First differencing turns a rising series into a flat one by modeling changes instead of levels.
- MA(q) — the moving average part. The current value depends on the q most recent forecast errors. If the model under-predicted yesterday, MA nudges today’s prediction upward.
Together, the three parameters are written as ARIMA(p, d, q).
Choosing p, d, and q
Step 1: Determine d
Plot the series. If it trends up or down, try d=1. If the first difference still trends, try d=2. Most real-world series need d ≤ 2. You can also run the Augmented Dickey-Fuller test to check stationarity:
from statsmodels.tsa.stattools import adfuller
result = adfuller(series)
if result[1] > 0.05:
# p-value too high — series is non-stationary, difference it
series_diff = series.diff().dropna()
Step 2: Determine p and q from ACF/PACF
After differencing, two plots guide parameter selection:
- ACF (autocorrelation function) — shows correlation at each lag. A sharp cutoff after lag q suggests the MA order.
- PACF (partial autocorrelation function) — shows the direct correlation at each lag after removing intermediate effects. A sharp cutoff after lag p suggests the AR order.
from statsmodels.graphics.tsaplots import plot_acf, plot_pacf
plot_acf(series_diff, lags=40)
plot_pacf(series_diff, lags=40)
Step 3: Use auto_arima as a sanity check
The pmdarima library automates parameter search using information criteria (AIC/BIC):
import pmdarima as pm
model = pm.auto_arima(
series,
seasonal=False,
stepwise=True,
suppress_warnings=True,
)
print(model.summary())
Fitting and forecasting
from statsmodels.tsa.arima.model import ARIMA
model = ARIMA(train, order=(2, 1, 1))
fitted = model.fit()
forecast = fitted.forecast(steps=30)
conf_int = fitted.get_forecast(30).conf_int()
The forecast gives point predictions. The conf_int gives upper and lower bounds — critical for decision-making because it tells you how uncertain the prediction is.
When ARIMA works well — and when it doesn’t
| Scenario | ARIMA fit |
|---|---|
| Monthly airline passengers | Great after log transform |
| Daily website traffic with weekly cycles | Needs SARIMA (seasonal extension) |
| Stock prices (random walk) | Poor — no exploitable pattern |
| Data with sudden regime changes | Poor — assumes stable structure |
ARIMA shines on single-variable, regularly-spaced data with consistent patterns. It struggles with multiple seasonalities, external factors, or structural breaks.
SARIMA: adding seasonality
When your data has weekly, monthly, or yearly cycles, SARIMA adds a second set of (P, D, Q, m) parameters:
from statsmodels.tsa.statespace.sarimax import SARIMAX
model = SARIMAX(train, order=(1, 1, 1), seasonal_order=(1, 1, 1, 12))
fitted = model.fit(disp=False)
Here m=12 means a 12-period seasonal cycle (monthly data with yearly seasonality).
Common misconception
Many beginners think higher p and q values always improve the model. In practice, overfitting kicks in fast. ARIMA(8, 2, 8) will memorize training noise and produce terrible forecasts. Most real-world series work well with p and q between 0 and 3.
The one thing to remember: ARIMA combines three intuitive ideas — use recent values, remove trends, and correct from past errors — but choosing the right parameters matters more than the model itself.
See Also
- Python Autocorrelation Analysis How today's number is connected to yesterday's, and why that connection is the secret weapon of time series analysis.
- Python Exponential Smoothing How exponential smoothing weighs recent events more heavily to predict what happens next, like trusting fresh memories more than old ones.
- Python Multivariate Time Series Why tracking multiple things at once gives you better predictions than tracking each one alone.
- Python Prophet Forecasting How Facebook's Prophet tool predicts the future by breaking data into easy-to-understand pieces.
- Python Seasonal Decomposition How Python breaks apart time data into trend, seasonal patterns, and leftover noise — like separating ingredients in a smoothie.