Intermediate

Classical Time Series Methods

Master ARIMA, SARIMA, and exponential smoothing — the foundation of statistical time series forecasting.

ARIMA

ARIMA (AutoRegressive Integrated Moving Average) combines three components:

  • AR(p): AutoRegressive — uses past values to predict the current value. p is the number of lag observations.
  • I(d): Integrated — differencing to make the series stationary. d is the number of times the data is differenced.
  • MA(q): Moving Average — uses past forecast errors. q is the size of the moving average window.
Python — ARIMA with statsmodels
from statsmodels.tsa.arima.model import ARIMA
import pandas as pd

# Load data
df = pd.read_csv('airline_passengers.csv', parse_dates=['date'], index_col='date')

# Fit ARIMA(p=5, d=1, q=0)
model = ARIMA(df['passengers'], order=(5, 1, 0))
fitted = model.fit()
print(fitted.summary())

# Forecast 12 steps ahead
forecast = fitted.forecast(steps=12)
print(forecast)

# Plot
import matplotlib.pyplot as plt
fig, ax = plt.subplots(figsize=(12, 5))
df['passengers'].plot(ax=ax, label='Observed')
forecast.plot(ax=ax, label='Forecast', color='red')
ax.legend()
plt.title("ARIMA Forecast")
plt.show()

Choosing p, d, q

ParameterHow to ChooseTool
dNumber of differences to achieve stationarityADF test, visual inspection
pNumber of significant lags in PACFPACF plot
qNumber of significant lags in ACFACF plot
Python — Auto ARIMA (automatic parameter selection)
import pmdarima as pm

# Automatically find best ARIMA parameters
auto_model = pm.auto_arima(
    df['passengers'],
    start_p=0, start_q=0,
    max_p=5, max_q=5,
    d=None,           # auto-detect d
    seasonal=False,
    stepwise=True,
    suppress_warnings=True,
    information_criterion='aic'
)
print(auto_model.summary())

SARIMA

SARIMA extends ARIMA with seasonal components: SARIMA(p,d,q)(P,D,Q,s) where s is the seasonal period.

Python — SARIMA for seasonal data
from statsmodels.tsa.statespace.sarimax import SARIMAX

# SARIMA with seasonal period of 12 (monthly data)
model = SARIMAX(
    df['passengers'],
    order=(1, 1, 1),             # (p, d, q)
    seasonal_order=(1, 1, 1, 12) # (P, D, Q, s)
)
fitted = model.fit(disp=False)

# Forecast with confidence intervals
forecast = fitted.get_forecast(steps=24)
ci = forecast.conf_int()

fig, ax = plt.subplots(figsize=(12, 5))
df['passengers'].plot(ax=ax, label='Observed')
forecast.predicted_mean.plot(ax=ax, label='Forecast', color='red')
ax.fill_between(ci.index, ci.iloc[:, 0], ci.iloc[:, 1],
                color='red', alpha=0.1, label='95% CI')
ax.legend()
plt.title("SARIMA Forecast with Confidence Intervals")
plt.show()

Exponential Smoothing

Exponential smoothing methods assign exponentially decreasing weights to past observations. Holt-Winters handles both trend and seasonality.

Python — Holt-Winters exponential smoothing
from statsmodels.tsa.holtwinters import ExponentialSmoothing

# Triple exponential smoothing (Holt-Winters)
model = ExponentialSmoothing(
    df['passengers'],
    trend='add',          # additive trend
    seasonal='mul',       # multiplicative seasonality
    seasonal_periods=12
)
fitted = model.fit()
forecast = fitted.forecast(steps=12)

# Simple exponential smoothing (no trend, no seasonality)
from statsmodels.tsa.holtwinters import SimpleExpSmoothing
ses = SimpleExpSmoothing(df['passengers']).fit(smoothing_level=0.2)
ses_forecast = ses.forecast(12)
When to use classical methods: Classical methods excel with univariate data, small datasets, and when interpretability is important. They often outperform deep learning on short, clean time series. Always start with a classical baseline before trying complex models.
Common mistakes: (1) Not checking stationarity before fitting ARIMA. (2) Ignoring seasonal patterns and using ARIMA instead of SARIMA. (3) Overfitting by using too many AR or MA terms. (4) Not validating with proper time series cross-validation.