Skip to content

MSARIMA

Ivan Svetunkov edited this page Apr 14, 2026 · 8 revisions

MSARIMA - Multiple Seasonal ARIMA

MSARIMA (Multiple Seasonal ARIMA) is an optimized implementation of ARIMA for handling multiple seasonal patterns. It is a wrapper of ADAM that skips zero polynomials, making it substantially faster and more accurate than SSARIMA for high-frequency data.

Overview

MSARIMA efficiently handles complex seasonal structures like:

  • Hourly data with daily (24) and weekly (168) patterns
  • Daily data with weekly (7) and annual (365) patterns
  • Sub-daily data with multiple intraday and interday cycles

The implementation differs from SSARIMA by directly mapping non-zero components, reducing the state dimension and improving computational efficiency.

Read more about ADAM ARIMA (and thus MSARIMA) in Svetunkov (2023), Chapter 9.

Python Usage

from smooth import MSARIMA
import numpy as np

y = np.array([...])  # your time series

# Default: ARIMA(0,1,1)
model = MSARIMA()
model.fit(y)
print(model)

# ARIMA(1,1,1)
model = MSARIMA(ar_order=1, i_order=1, ma_order=1)
model.fit(y)

# SARIMA(1,1,1)(1,1,1)[12] via dict
model = MSARIMA(
    orders={"ar": [1, 1], "i": [1, 1], "ma": [1, 1]},
    lags=[1, 12],
)
model.fit(y)

# ARIMA(1,1,1) with drift
model = MSARIMA(ar_order=1, i_order=1, ma_order=1, constant=True)
model.fit(y)
print(f"Drift: {model.constant_value:.4f}")

# Fixed ARMA coefficients (not estimated)
model = MSARIMA(ar_order=1, i_order=1, ma_order=1,
                arma={"ar": [0.5], "ma": [0.2]})
model.fit(y)

# Forecasts
forecasts = model.predict(h=12)
forecasts = model.predict(h=12, interval="prediction", level=0.95)

Automatic Order Selection

# Auto-select using information criteria
model = MSARIMA(arima_select=True)
model.fit(y)

# With maximum orders specified
model = MSARIMA(
    orders={"ar": [2, 1], "i": [1, 1], "ma": [2, 1], "select": True},
    lags=[1, 24],
)
model.fit(y)

R Usage

library(smooth)

# Basic non-seasonal ARIMA(1,1,1)
msarima(y, orders=c(1,1,1), lags=1)

# SARIMA(1,1,1)(0,1,1)[12]
msarima(y, orders=list(ar=c(1,0), i=c(1,1), ma=c(1,1)), lags=c(1,12))

# Complex multiple seasonality
# SARIMA(1,1,1)(0,1,1)[24](2,0,1)[168](0,0,1)[720]
msarima(y,
    orders=list(ar=c(1,0,2,0), i=c(1,1,0,0), ma=c(1,1,1,1)),
    lags=c(1,24,168,720)
)

# With holdout validation
msarima(y, orders=list(ar=c(1,1), i=c(1,1), ma=c(1,1)),
        lags=c(1,24), h=48, holdout=TRUE)

# Fixed ARMA coefficients
msarima(y, orders=c(1,1,1), arma=list(ar=0.5, ma=0.2))

Automatic Order Selection

auto.msarima() is a wrapper of auto.adam().

# Automatic selection
auto.msarima(y, h=24, holdout=TRUE)

# With maximum orders
auto.msarima(y, orders=list(ar=c(2,1), i=c(1,1), ma=c(2,1)), lags=c(1,24))

# Check constant necessity
auto.msarima(y, constant=NULL)

Parameters

Parameter Type (R) Type (Python) Default Description
y vector/ts NDArray - Time series data
orders list/vector Dict/None None ARIMA orders per lag (R-style dict)
ar_order - int/List[int] 0 AR order(s); Python-preferred alternative
i_order - int/List[int] 1 Integration order(s)
ma_order - int/List[int] 1 MA order(s)
lags numeric vector List[int]/None None Seasonal period(s)
arima_select orders$select bool False Automatic order selection
constant logical/numeric bool/float False Include constant/drift
arma list Dict/None None Fixed AR/MA parameter values
initial character str/Dict "backcasting" Initialization method
initial_X initialX NDArray/None None Initial regressor coefficients
bounds character str "usual" Parameter bounds
ic character str "AICc" Information criterion
loss character str "likelihood" Loss function
h integer int/None None Forecast horizon
holdout logical bool False Use holdout validation
regressors character str "use" How to handle regressors

Orders Specification

Each element in ar, i, ma vectors corresponds to the lag at the same position:

# SARIMA(1,1,1)(1,0,1)[12](0,1,1)[52]
orders = list(
    ar = c(1, 1, 0),   # AR(1) at lag 1, AR(1) at lag 12, AR(0) at lag 52
    i  = c(1, 0, 1),   # I(1) at lag 1, I(0) at lag 12, I(1) at lag 52
    ma = c(1, 1, 1)    # MA(1) at all lags
)
lags = c(1, 12, 52)
# Python equivalent using dict
model = MSARIMA(
    orders={"ar": [1, 1, 0], "i": [1, 0, 1], "ma": [1, 1, 1]},
    lags=[1, 12, 52],
)

See Orders-and-Lags for full details.

Fixed ARMA Parameters (arma)

Use arma to fix AR or MA coefficients at specified values instead of estimating them. The dict keys "ar" and "ma" take lists of values matching the total AR/MA order.

# Fix only MA coefficient
model = MSARIMA(ar_order=0, i_order=1, ma_order=1, arma={"ma": [0.3]})

# Fix both AR and MA
model = MSARIMA(ar_order=1, i_order=1, ma_order=1,
                arma={"ar": [0.5], "ma": [0.2]})

# Seasonal ARIMA — provide one value per total AR/MA term
# SARIMA(1,0,0)(0,0,1)[12]: fix AR at lag 1 and MA at lag 12
model = MSARIMA(
    orders={"ar": [1, 0], "i": [1, 1], "ma": [0, 1]},
    lags=[1, 12],
    arma={"ar": [0.5], "ma": [0.3]},
)

Fixed parameters do not appear in model.coef (nothing to estimate). They are accessible via model._arima["arma_parameters"].

Initialization Methods

  • "backcasting": Recommended for high-frequency data
  • "optimal": Optimize initial states
  • "two-stage": Backcast then optimize
  • "complete": Full backcasting including regressors

More detailed explanation is provided in Section 11.4 of Svetunkov (2023).

With External Regressors

# R: MSARIMAX model
msarima(y, orders=list(ar=c(1,0), i=c(1,1), ma=c(1,1)),
        lags=c(1,24), xreg=X)
# Python
model = MSARIMA(ar_order=[1, 0], i_order=[1, 1], ma_order=[1, 1], lags=[1, 24])
model.fit(y, X=X)

Output / Attributes

Element (R) Element (Python) Type (R) Type (Python) Description
modelName() model_name character str Full model name (e.g., "ARIMA(0,1,1)")
orders() _arima["ar_orders"] etc. list Dict ARIMA orders used
lags() lags_used vector List Lags vector used
arma _arima["arma_parameters"] list list/None AR/MA parameter values (fixed or initialized)
constant constant_value numeric float/None Constant/drift value
B coef vector NDArray Estimated parameters (empty when all ARMA fixed)
fitted() fitted vector Series In-sample fitted values
residuals() residuals vector Series Model residuals
states states matrix DataFrame State matrix over time
transition transition matrix NDArray Transition matrix F
persistence persistence_vector vector Dict Persistence vector g
measurement measurement matrix NDArray Measurement matrix W
logLik loglik / loss_value numeric float Log-likelihood / loss value
AIC aic numeric float Akaike Information Criterion
AICc aicc numeric float Corrected AIC
BIC bic numeric float Bayesian Information Criterion
distribution distribution_ character str Error distribution used
scale scale / sigma numeric float Scale parameter

MSARIMA vs SSARIMA

Feature MSARIMA SSARIMA
Speed Fast Slow
Memory usage Low High
Multiple seasonality Optimized Full polynomial expansion
High-frequency data Recommended Can be slow

Use MSARIMA (or ADAM) for:

  • Hourly, sub-hourly data
  • Multiple seasonal patterns
  • Large datasets

References

See Also

Related Functions

  • ADAM - Unified framework (Python/R)
  • SSARIMA - Original State Space ARIMA
  • ES - Exponential Smoothing

Parameter Documentation

Clone this wiki locally