Autoregressive Integrated Moving Average (ARIMA) models for time series.
Classes
Autoregressive Integrated Moving Average (ARIMA) model for non-stationary time series forecasting.
ARIMA is a generalization of the ARMA model that includes differencing to handle non-stationary time series data. It is characterized by the triplet (p, d, q), representing the autoregressive order, the degree of differencing, and the moving average order, respectively.
Constructor
__init__( self, order: Tuple[int, int, int] = (), trend: str | None = None, method: str = 'css-mle', maxiter: int = 50, )
Overview
The ARIMA modeling procedure follows these steps:
- Apply d rounds of differencing to make the series stationary.
- Estimate the AR coefficients using Yule-Walker equations.
- Initialize the MA coefficients (set to zero initially).
- Compute the constant term based on the trend specification.
- Optionally refine parameters via simplified MLE (gradient descent).
- Forecast on the differenced scale and invert the differencing to
Theory
The \text{ARIMA}(p, d, q) process is defined using the lag operator L as:
(1 - \sum_{i=1}^p \phi_i L^i) (1 - L)^d y_t = (1 + \sum_{j=1}^q \theta_j L^j) \epsilon_t
where:
- y_t: The time series value at time t.
- L: The lag operator, such that L y_t = y_{t-1}.
- d: The degree of differencing required to make the series stationary.
- p: The number of autoregressive lags.
- q: The number of moving average lags.
- \phi_i: Autoregressive parameters.
- \theta_j: Moving average parameters.
- \epsilon_t: White noise error term.
Parameters
order
tuple of (int, int, int), 0, 0)
= (1
The :math:`(p, d, q)` order of the model:
- •:math:`p`: Autoregressive order.
- •:math:`d`: Degree of differencing.
- •:math:`q`: Moving average order.
trend
{"c", "t", "ct", None}
= None
The trend component to include:
- •
"c": Constant term. - •
"t": Linear trend. - •
"ct": Both constant and linear trend. - •
None: No trend.
method
{"css", "mle", "css-mle"}
= "css-mle"
The estimation method used to fit the model.
maxiter
int
= 50
Maximum number of iterations for the optimization.
Attributes
ar_params_
np.ndarray of shape (p,)
Fitted autoregressive coefficients :math:`(\phi_1, \phi_2, \dots, \phi_p)`.
ma_params_
np.ndarray of shape (q,)
Fitted moving average coefficients :math:`(\\theta_1, \\theta_2, \dots, \\theta_q)`.
const_
float
The fitted constant (intercept) term.
resid_
np.ndarray of shape (n_obs - d,)
The estimated residuals from the fitted model.
sigma2_
float
The variance of the residuals (:math:`\sigma^2`).
n_obs_
int
The total number of observations used for fitting.
Notes
Complexity:
- Training: O(n \cdot \text{maxiter} \cdot (p+q)^2) where n
- Prediction: O(p+q) per step, plus O(d \cdot n) for
When to use ARIMA:
- Non-stationary time series that can be made stationary by differencing
- Data with trends but without strong seasonal patterns
- When both autoregressive and moving average components are needed
- Short-to-medium term forecasting of univariate series
seasonal_order argument that was stored and never read, so passing (1, 1, 1, 12) quietly fitted a non-seasonal model and returned forecasts with no seasonal structure at all. The argument has been removed rather than left to mislead. For seasonal terms, exogenous regressors, exact Gaussian maximum likelihood via a Kalman filter, and forecast intervals, use SARIMAX, which supersedes this class on every axis except speed.
Parameters here are estimated by minimising the conditional sum of squares, conditioning on the first \max(p, q) observations, rather than the exact likelihood.
References
Box2015
Box, G. E., Jenkins, G. M., Reinsel, G. C., & Ljung, G. M. (2015).
Time series analysis: forecasting and control.
John Wiley & Sons.
Hyndman2018
Hyndman, R. J., & Athanasopoulos, G. (2018).
Forecasting: principles and practice. OTexts.
See Also
python
>>> import numpy as np
>>> from tuiml.algorithms.timeseries import ARIMA
>>> # Generating a non-stationary random walk
>>> np.random.seed(42)
>>> y = np.cumsum(np.random.normal(size=100))
>>> model = ARIMA(order=(1, 1, 1))
>>> _ = model.fit(y) # fit returns self; bind it to keep doctest quiet
>>> model.predict(steps=5).shape
(5,)
The moving-average term is genuinely estimated, so q is not decorative:
python
>>> rng = np.random.default_rng(0)
>>> e = rng.normal(size=2001)
>>> ma_series = e[1:] + 0.6 * e[:-1] # MA(1) with theta = 0.6
>>> fitted = ARIMA(order=(0, 0, 1)).fit(ma_series)
>>> bool(abs(fitted.ma_params_[0] - 0.6) < 0.1)
True
Methods
predict
(self, steps: int=1, _X: Optional[np.ndarray]=None) -> np.ndarray
predict
(self, steps: int=1, _X: Optional[np.ndarray]=None) -> np.ndarray
Forecast future values using the fitted ARIMA model.
Parameters
steps
int
= 1
Number of future time steps to forecast.
_X
np.ndarray
= None
Exogenous variables (not yet supported).
Returns
forecast
np.ndarray of shape (steps,)
Forecasted values.
fit_predict
(self, y: np.ndarray, steps: int=1) -> np.ndarray
fit_predict
(self, y: np.ndarray, steps: int=1) -> np.ndarray
Fit the model and forecast future values in one step.
Parameters
y
np.ndarray of shape (n_samples,)
Time series values to fit.
steps
int
= 1
Number of future time steps to forecast.
Returns
forecast
np.ndarray of shape (steps,)
Forecasted values.