smooth.ADAM
- class smooth.ADAM(model='ZXZ', lags=None, ar_order=0, i_order=0, ma_order=0, arima_select=False, constant=False, regressors='use', distribution=None, loss='likelihood', loss_horizon=None, outliers='ignore', outliers_level=0.99, ic='AICc', bounds='usual', occurrence='none', persistence=None, phi=None, initial='backcasting', n_iterations=None, arma=None, verbose=0, h=None, holdout=False, fast=False, lambda_param=None, frequency=None, profiles_recent_provided=False, profiles_recent_table=None, nlopt_initial=None, nlopt_upper=None, nlopt_lower=None, nlopt_kargs=None, reg_lambda=None, gnorm_shape=None, smoother='lowess', **kwargs)
ADAM: Augmented Dynamic Adaptive Model for Time Series Forecasting.
ADAM is an advanced state-space modeling framework that combines ETS (Error, Trend, Seasonal) and ARIMA components into a unified Single Source of Error (SSOE) model. It provides a flexible, data-driven approach to time series forecasting with automatic model selection, parameter estimation, and prediction intervals.
Mathematical Form:
The ADAM model is specified in state-space form as:
\[ \begin{align}\begin{aligned}y_t &= o_t(w(v_{t-l}) + h(x_t, a_{t-1}) + r(v_{t-l})\epsilon_t)\\v_t &= f(v_{t-l}, a_{t-1}) + g(v_{t-l}, a_{t-1}, x_t)\epsilon_t\end{aligned}\end{align} \]where:
\(y_t\): Observed value at time t
\(o_t\): Occurrence indicator (Bernoulli variable for intermittent data, 1 otherwise)
\(v_t\): State vector (level, trend, seasonal, ARIMA components)
\(l\): Vector of lags
\(x_t\): Vector of exogenous variables
\(a_t\): Parameters for exogenous variables
\(w(\cdot)\): Measurement function
\(r(\cdot)\): Error function (additive or multiplicative)
\(f(\cdot)\): Transition function (state evolution)
\(g(\cdot)\): Persistence function (smoothing parameters)
\(\epsilon_t\): Error term (various distributions supported)
Key Features:
Unified Framework: Seamlessly combines ETS and ARIMA in a single model
Multiple Seasonality: Supports multiple seasonal periods (e.g., daily + weekly)
Automatic Selection: Branch & Bound algorithm for efficient model selection
Flexible Distributions: Normal, Laplace, Gamma, Log-Normal, and more
Intermittent Demand: Built-in occurrence models for sparse data
External Regressors: Include covariates with adaptive or fixed coefficients
Scikit-learn Compatible: Familiar .fit() and .predict() API
Model Specification:
Models are specified using a string notation:
ETS Models: “ETS” where E=Error, T=Trend, S=Seasonal
E (Error): “A” (Additive), “M” (Multiplicative)
T (Trend): “N” (None), “A” (Additive), “Ad” (Additive Damped), “M” (Multiplicative), “Md” (Multiplicative Damped)
S (Seasonal): “N” (None), “A” (Additive), “M” (Multiplicative)
Examples: “ANN” (Simple Exponential Smoothing), “AAN” (Holt’s Linear), “AAA” (Holt-Winters Additive)
Automatic Selection:
“ZZZ”: Select best model using Branch & Bound
“XXX”: Select only additive components
“YYY”: Select only multiplicative components
“ZXZ”: Auto-select error and seasonal, additive trend only (default, safer)
“FFF”: Full search across all 30 ETS model types
ARIMA Models: Specified via ar_order, i_order, ma_order parameters
Supports seasonal ARIMA: SARIMA(p,d,q)(P,D,Q)m
Multiple seasonality: e.g., hourly data with daily (24) and weekly (168) patterns
Supported Error Distributions:
Normal (
distribution="dnorm"): Default for additive errorsGamma (
distribution="dgamma"): Default for multiplicative errorsLaplace (
distribution="dlaplace"): For heavy-tailed errors (MAE loss)Log-Normal (
distribution="dlnorm"): For positive-only dataInverse Gaussian (
distribution="dinvgauss"): For skewed positive dataS distribution (
distribution="ds"): For extremely heavy-tailed dataGeneralized Normal (
distribution="dgnorm"): Flexible shape parameter
Distribution is auto-selected based on loss function if
distribution=None.Loss Functions:
loss="likelihood": Maximum likelihood estimation (default)loss="MSE": Mean Squared Errorloss="MAE": Mean Absolute Errorloss="HAM": Half-Absolute Momentloss="MSEh": Multi-step MSE (h-step ahead)loss="LASSO": L1 regularization for variable selectionloss="RIDGE": L2 regularization for shrinkage
Multistep loss functions:
loss="MSEh": Mean Squared Error for specific h-steps aheadloss="TMSE": Trace Mean Squared Error (sum of MSEh from 1 to h)loss="GTMSE": Geometric Trace Mean Squared Error (sum of logs of MSEh from 1 to h)loss="MSCE": Mean Squared Cumulative Error (sum of MSEh from 1 to h and covariances between them)loss="GPL": Generalised Predictive Likelihood (minimum of the determinant of the covariance matrix of multistep errors)
Initialization Methods:
initial="optimal": Optimize all initial states (default)initial="backcasting": Use backcasting to initialize statesinitial="two-stage": Backcast then optimizeinitial="complete": Pure backcasting without optimizationinitial={"level": 100, ...}: Provide custom initial states
Workflow Example:
from smooth import ADAM import numpy as np # Generate sample data y = np.array([112, 118, 132, 129, 121, 135, 148, 148, 136, 119, 104, 118] * 3) # Automatic model selection model = ADAM(model="ZZZ", lags=[12], ic="AICc") ADAM_fit = model.fit(y) print(ADAM_fit) # Generate 12-step ahead forecasts with intervals forecasts = model.predict(h=12, calculate_intervals=True, level=0.95) print(forecasts) # Access fitted parameters print(f"Model: {model.model_name}") print(f"Alpha: {model.persistence_level_:.3f}") print(f"AICc: {model.aicc}")
Attributes (After Fitting):
The model stores fitted results as attributes with trailing underscores (scikit-learn convention):
persistence_level_: Level smoothing parameter (α)persistence_trend_: Trend smoothing parameter (β)persistence_seasonal_: Seasonal smoothing parameter(s) (γ)phi_: Damping parameter (φ)initial_states_: Estimated initial statesarma_parameters_: AR/MA coefficients (if ARIMA)
Additional fitted attributes:
model_name: Full model specification stringcoef: Estimated parameter vector Bstates: State matrix over timepersistence_vector: Named persistence parameterstransition: Transition matrix
Performance Considerations:
Small Data (T < 100): Use “backcasting” initialization, it’s faster
Large Data (T > 1000): “optimal” initialization works well
Multiple Seasonality: Can be slow; consider simpler models first
Model Selection: “ZZZ” with Branch & Bound is much faster than “FFF” exhaustive search
Common Use Cases:
Automatic Forecasting:
ADAM(model="ZXZ", lags=[12])- Let the model chooseIntermittent Demand:
ADAM(model="ANN", occurrence="auto")- For sparse dataExternal Regressors:
ADAM(model="AAN").fit(y, X=regressors)- Include covariatesMultiple Seasonality:
ADAM(model="AAA", lags=[24, 168])- Hourly data with daily/weekly patternsARIMA:
ADAM(model="NNN", ar_order=1, i_order=1, ma_order=1)- Pure ARIMA(1,1,1)Custom Model:
ADAM(model="MAM", persistence={"alpha": 0.3})- Fix some parameters
Comparison to R’s smooth::adam:
This Python implementation is a direct translation of the R smooth package’s
adam()function, maintaining mathematical equivalence while adapting to scikit-learn conventions:R:
adam(data, model="ZZZ", h=10)→ Python:ADAM(model="ZZZ").fit(y).predict(h=10)R:
persistence=list(alpha=0.3)→ Python:persistence={"alpha": 0.3}R:
orders=list(ar=c(1,1))→ Python:ar_order=[1, 1]
References:
Svetunkov, I. (2023). Forecasting and Analytics with the Augmented Dynamic Adaptive Model. https://openforecast.org/adam/
Hyndman, R.J., et al. (2008). “Forecasting with Exponential Smoothing”
Svetunkov, I. & Boylan, J.E. (2017). “State-space ARIMA for supply-chain forecasting”
Svetunkov, I. & Kourentzes, N. & Killick, R. (2023). “Multi-step estimators and shrinkage effect in time series models”. DOI: 10.1007/s00180-023-01377-x
See also
adam.fitFit the ADAM model to data
adam.predictGenerate point forecasts
adam.predict_intervalsGenerate prediction intervals
selectorAutomatic model selection function
estimatorParameter estimation function
forecasterForecasting function
printPrint the outputs of the ADAM class
Examples
Simple exponential smoothing:
>>> from smooth import ADAM >>> import numpy as np >>> y = np.array([112, 118, 132, 129, 121, 135, 148, 148, 136, 119, 104, 118]) >>> model = ADAM(model="ANN", lags=[1]) >>> model.fit(y) >>> forecasts = model.predict(h=6) >>> print(forecasts)
Automatic model selection with multiple seasonality:
>>> model = ADAM(model="ZZZ", lags=[12], ic="AICc") >>> model.fit(y) >>> print(f"Selected model: {model.model_name}")
SARIMA(1,1,1)(1,1,1)₁₂:
>>> model = ADAM( ... model="NNN", # Pure ARIMA ... ar_order=[1, 1], ... i_order=[1, 1], ... ma_order=[1, 1], ... lags=[1, 12] ... ) >>> model.fit(y) >>> forecasts = model.predict(h=12)
With external regressors:
>>> X = np.random.randn(len(y), 2) # Two regressors >>> X_future = np.random.randn(6, 2) # Regressors for forecast period >>> model = ADAM(model="AAN", regressors="use") >>> model.fit(y, X=X) >>> forecasts = model.predict(h=6, X=X_future)
Fix some parameters, estimate others:
>>> model = ADAM( ... model="AAA", ... lags=[12], ... persistence={"alpha": 0.3}, # Fix alpha, estimate beta and gamma ... initial="backcasting" ... ) >>> model.fit(y)
Intermittent demand forecasting:
>>> sparse_data = np.array([0, 0, 15, 0, 0, 23, 0, 0, 0, 18, 0, 0]) >>> model = ADAM(model="ANN", occurrence="auto") >>> model.fit(sparse_data) >>> forecasts = model.predict(h=6) # Accounts for zero-demand probability
Methods
|
Fit the ADAM model to time series data. |
|
Generate point forecasts using the fitted ADAM model. |
|
Generate prediction intervals using the fitted ADAM model. |
Select the best model based on information criteria and update model parameters. |
|
|
Generate a formatted summary of the fitted model. |
Attributes
Return original in-sample data. |
|
Return Akaike Information Criterion. |
|
Return corrected Akaike Information Criterion. |
|
$B). |
|
Return Bayesian Information Criterion. |
|
Return corrected Bayesian Information Criterion. |
|
Return estimated coefficients (parameter vector B). |
|
$constant). |
|
$data). |
|
$distribution). |
|
'A' (additive) or 'M' (multiplicative). |
|
Return in-sample fitted values. |
|
$holdout). |
|
$ICw). |
|
$initialType). |
|
$initial). |
|
Return True if model is a combination of multiple models. |
|
Return the vector of lags used in the model. |
|
Return log-likelihood of the fitted model. |
|
$loss). |
|
$lossValue). |
|
$measurement). |
|
modelName()). |
|
Return ETS model type code (e.g., 'AAN', 'AAA', 'MAdM'). |
|
$models). |
|
$nParam). |
|
Return number of observations used for fitting. |
|
Return number of estimated parameters. |
|
Return ARIMA orders as dict with 'ar', 'i', 'ma' keys. |
|
$persistence). |
|
$phi). |
|
$profile). |
|
Return model residuals (errors from fitting). |
|
$scale). |
|
Return scale/standard error estimate. |
|
$states). |
|
Time taken to fit the model in seconds. |
|
$transition). |