-
Notifications
You must be signed in to change notification settings - Fork 22
Initialisation
This page documents the initial parameter and initialisation methods used across smooth models.
| Field | Value |
|---|---|
| Argument name | initial |
| Type | string, or list / dict of numeric vectors |
| Valid values (string) |
"backcasting", "optimal", "two-stage", "complete", "gradient"
|
| Valid values (provided) | R: list(level=…, trend=…, seasonal=…, xreg=…, arima=…). Python: dict with the same keys. |
| Default | "backcasting" |
| Applies to | R: adam, auto.adam, es, ces, msarima, ssarima, gum, om, omg. Python: ADAM, AutoADAM, ES, CES, MSARIMA, OM, OMG. |
The initial parameter controls how initial state values are determined before model estimation begins.
R
# Use backcasting (default)
model <- adam(y, model="AAA", lags=12, initial="backcasting")
# Optimize all initial states
model <- adam(y, model="AAA", lags=12, initial="optimal")Python
# Use backcasting (default)
model = ADAM(model="AAA", lags=12, initial="backcasting")
# Optimize all initial states
model = ADAM(model="AAA", lags=12, initial="optimal")| Method | Description | Speed | Recommended For |
|---|---|---|---|
"backcasting" |
Initialize via backcasting procedure | Fast | High-frequency data, large datasets |
"optimal" |
Optimize all initial states | Slow | Short series, when accuracy is critical |
"two-stage" |
Backcast first, then optimize | Slower | Refine the initials, gain in accuracy |
"complete" |
Full backcasting including regressors | Fast | ETSX/ARIMAX models on large datasets |
"gradient" |
Solve the initials by least squares / Gauss-Newton at the current dynamics | Fast | Optimal-quality initials at near-backcasting cost; seasonal-with-trend models where backcasting can diverge |
The default method. Runs the model forward and backwards through the data to estimate initial states:
- Start from the beginning of the data, apply the model
- Revert the model and move from the end of the series to the beginning
- Use the resulting states as initial values
Note: This method still estimates the values of the parameters for the explanatory variables.
Advantages:
- Fast, especially for long series
- Works well for high-frequency data
- Provides reasonable starting points
- Requires fewer parameters to estimate
When to use: Default choice for most situations, especially with high-frequency or long series.
model <- adam(y, model="AAA", lags=12, initial="backcasting")model = ADAM(model="AAA", lags=12, initial="backcasting")The number of iterations in backcasting can be controlled via the nIterations parameter:
model <- adam(y, model="AAA", lags=12, initial="backcasting", nIterations=2)model = ADAM(model="AAA", lags=12, initial="backcasting", n_iterations=2)Default is 2 iterations, which suffices in the majority of cases. Larger values will slow down the estimation.
All initial states are treated as parameters and optimized along with other model parameters:
- Initial states are included in the parameter vector
- Optimizer finds values that minimize the loss function
- Results in potentially better fit but more parameters to estimate
Advantages:
- Can improve fit for short series
- This is the default approach in all the other ETS implementations
Disadvantages:
- Slower, especially for seasonal models with long lags and large datasets
- More parameters to estimate
- Parameter estimates for initial states are neither efficient, nor consistent
- Might become a nightmare in case of large order ARIMA
When to use: Short time series where initial states significantly impact the fit.
model <- adam(y, model="AAA", lags=12, initial="optimal")model = ADAM(model="AAA", lags=12, initial="optimal")Combines backcasting and optimization:
- First, perform backcasting to get initial estimates
- Then, refine these estimates through optimization
Advantages:
- Better starting point for optimization
- Can achieve better fit than pure backcasting
Disadvantages:
- The same as in case of "optimal".
When to use: When you want a better model fit, and are not satisfied with the "optimal" ones.
model <- adam(y, model="AAA", lags=12, initial="two-stage")model = ADAM(model="AAA", lags=12, initial="two-stage")Full backcasting that also initializes explanatory variable coefficients:
- Backcast all states including regressor parameters
- No optimization of initial values for ETS/ARIMA components
Advantages:
- Fast for models with regressors
- Consistent treatment of all components
Disadvantages:
- Estimates of parameters for explanatory variables might be biased
When to use: ETSX, ARIMAX, or other models with explanatory variables.
model <- adam(data, model="AAN", formula=y~x1+x2, initial="complete")model = ADAM(model="AAN", regressors="use", initial="complete")
model.fit(y, X)Solves for the initial state directly instead of running the backcasting backward pass. Given the current dynamics (persistence / ARMA), the in-sample residuals are a known function of the initial state, so the initials are recovered by a single solve rather than optimised as free parameters:
- For additive single-source-of-error models (additive ETS, additive
ARIMA,
ces/gum/ssarima/sparma) the residuals are an affine function of the initial state. The design matrix is propagated analytically alongside one forward pass and the initials are recovered by one pivoted-QR least-squares solve — no backward pass, no per-initial iteration. - For multiplicative / mixed ETS the map is smooth-nonlinear, solved by Gauss-Newton with an analytic Jacobian (the state sensitivities propagated by the chain rule in one forward pass) plus a Levenberg-Marquardt fallback.
- When persistence is estimated, the optimiser estimates it while the initials are solved by gradient at each evaluation (nested — the backward pass is never run).
The whole solve runs in the shared C++ core (adamCore::gradientSolve), so R
and Python return identical initials and fitted values to machine precision.
Fix the smoothing parameters. There is a true conditional mean
μ_t = E[y_t | dynamics] we would like to fit, but it depends on the true
initial state v₀, which is unknown. From any chosen initial state the model
produces a fitted value ŷ_t — an estimate μ̂_t of μ_t that is biased by
the wrong initial.
Because the additive single-source-of-error recursion is linear in the initial
state, adjusting the initials by a vector v₀ shifts every fitted value by a
fixed linear amount:
μ̂_t(v₀) = μ̂_t(0) + D_t·v₀
where D_t = ∂ŷ_t/∂v₀ (a row vector, one entry per free initial) is the linear
map from the initial state to observation t's fitted value — it carries the
initial state forward through the recursion and reads off how much of ŷ_t that
initial is responsible for. Each entry says how strongly obs t "feels" one
initial parameter; the product D_t·v₀ is exactly the contribution of the
initial state to the fitted value, i.e. the initial-induced bias in the estimate
of μ_t. Observations early in the sample have large D_t (the initial still
drives them); later ones have D_t → 0 as the dynamics wash the initial out.
So the residual after adjusting the initials by v₀ is
y_t − μ̂_t(v₀) = ( y_t − μ̂_t(0) ) − D_t·v₀ = e_t − D_t·v₀
where e_t = y_t − μ̂_t(0) is the residual at the seed initials (v₀ = 0).
The residuals are therefore affine in v₀: after one forward pass gives
e_t and D_t, the residual for every candidate v₀ is known in closed form
— no re-simulation. Writing e = (e_t) and stacking the rows D_t into a design
matrix D, the seed residual decomposes as
e_t = ε_t + D_t·v₀*
— the true innovation ε_t plus the bias from the seed's initial-state error
v₀*. Choosing v₀ to minimise the in-sample SSE is then a plain linear least
squares that regresses that bias out of the residuals:
v̂₀ = argmin_{v₀} Σ_t ( e_t − D_t·v₀ )² ⇒ (DᵀD) v̂₀ = Dᵀe
What remains, e_t − D_t·v̂₀ ≈ ε_t, is the part no initial state can explain, so
μ̂_t(v̂₀) is the best (least-squares) estimate of the true μ_t at these
dynamics.
Getting D_t. It is built in the same forward pass by propagating the
state sensitivity S_t = ∂v_t/∂v₀ through the linearised recursion:
measurement: ŷ_t = w′·v_{t−1} ⇒ D_t = w′·S_{t−1}
update: v_t = F·v_{t−1} + g·e_t ⇒ S_t = F·S_{t−1} − g·D_t
(since ∂e_t/∂v₀ = −D_t)
starting from S₀ = P, the probe basis — the (states × free-initials) 0/1
matrix P = ∂v₀/∂(free initials) that says which state cells each free initial
controls (level and trend span the whole head, each seasonal / ARIMA / xreg slot
is its own column). P is not the identity in general: it is rectangular
(fewer free initials than state cells) and its level/trend columns carry several
1s (one initial seeds every head column). Because F, w, g are fixed
constants and every map is linear, S_t does not depend on the state values —
one pass yields the whole design D, then one QR solves v̂₀.
The probe basis P. The free initials v₀ are a compact vector — one entry
per estimated initial parameter — but the recursion needs a full state profile
(every component × every head lag). P is the bridge: an (state cells) × (free initials) 0/1 matrix with a 1 in column j on exactly the cells that
parameter j sets. It embeds the compact vector into the profile,
initial profile = seed + reshape(P·v₀)
so turning one knob v₀[j] moves every cell in P's column j together. Its
columns follow the model structure:
-
level and trend — one column each, with
1s across alllagsModelMaxhead columns of their row (a single initial seeds the whole head, then is walked forward), so these columns carry several1s; - each seasonal index, each ARIMA state-lag slot, and each xreg
coefficient — its own column with a single
1.
P is therefore generally rectangular (fewer free initials than cells) and not
the identity. It appears twice in the solve. First as the seed of the
sensitivity: since ∂(profile)/∂v₀ = P, the sensitivity starts at S₀ = P and
the recursion drags it forward to build the design D. Second as the embedding
that maps the answer back: the least squares returns the compact v̂₀, and
reshape(P·v̂₀) spreads it across the profile cells (added to the seed) to give
the solved initial states.
Each column of D is the time-signature of one initial parameter: the level
signature decays like (1−α)^{t−1} (its grip fades as the level adapts), the
trend signature ramps up (it compounds into the fitted path), a seasonal
signature is periodic, and an xreg coefficient's signature is essentially the
regressor series. The least squares projects the seed residuals onto these
signatures and returns the initial adjustment that cancels the part they explain.
For multiplicative / mixed models the residual is only approximately affine
(the sensitivities depend on the state), so the same D is recomputed at each
Gauss-Newton step (analytic Jacobian) and iterated to the minimum, with a
Levenberg-Marquardt fallback.
Advantages:
- Reaches optimal-quality initials at roughly backcasting cost
- Avoids a divergence
"backcasting"can exhibit for seasonal additive models with a trend and a moderate/large seasonal smoothing parameter (e.g. ETS(A,A,A) withlags=12), where backcasting could return badly wrong initials and a large in-sample penalty - Genuinely estimates the initials, so they count as degrees of freedom (like
"optimal") and the information criteria are comparable
Scope — what "gradient" solves vs. where it falls back to backcasting:
| Component | Additive error (E="A") |
Multiplicative error (E="M") |
|---|---|---|
| ETS (level/trend/seasonal) | solved (affine / Gauss-Newton) | solved (Gauss-Newton) |
| ARIMA | solved (exact affine least squares) | falls back to backcasting |
xreg (regressors="use"/"adapt") |
solved (exact affine least squares) | falls back to backcasting |
-
Additive xreg is solved exactly: the regression coefficients are just
more affine directions in the initial-state design, so the same one-pass
least-squares solve recovers them (matching
initial="optimal"to numerical precision). Both static ("use") and time-varying ("adapt") coefficients are covered — the adaptive persistence stays in the optimiser, only the initial coefficient is solved. - Multiplicative-error ARIMA / xreg fall back to backcasting. Although a multiplicative-error ARIMA is an additive ARIMA in logs (so an exact log-space solve is possible in principle), the only available multiplicative path is a finite-difference Gauss-Newton whose noise makes the outer persistence objective jagged and can converge poorly — so it is deliberately routed to backcasting instead.
- Custom loss functions fall back to backcasting for the initial solve. The solve runs in C++ and can only profile the built-in loss families; a user-supplied R/Python loss callable cannot be evaluated inside it. (The loss is still used normally for estimating the persistence.) The occurrence "fixed" type has no estimated initials and is likewise unaffected.
When to use: as a fast, robust alternative to "optimal", and specifically
when seasonal-with-trend backcasting looks unstable.
model <- adam(y, model="AAA", lags=12, initial="gradient")model = ADAM(model="AAA", lags=[12], initial="gradient").fit(y)Occurrence models:
initial="gradient"also works forom()/omg()(profiling the occurrence loss over the initials, coupled foromg), and for the occurrence models with ARIMA/xreg components (finite-difference Jacobian). See OM.
Instead of using a character method, you can provide specific initial values.
| Component | Description | Required For |
|---|---|---|
level |
Initial level value | All ETS models |
trend |
Initial trend value | ETS models with trend (A, Ad, M, Md) |
seasonal |
List/Vector of seasonal indices | Seasonal ETS models |
arima |
Initial ARIMA states | ARIMA components |
xreg |
Initial regressor coefficients | Models with explanatory variables |
# R: Provide specific initial values
model <- adam(y, model="AAA", lags=12,
initial=list(
level=100,
trend=1,
seasonal=c(0.9, 1.0, 1.1, 0.95, 1.05, 0.98,
1.02, 0.97, 1.03, 0.96, 1.04, 1.0)
))In case of several seasonal components, the list of components should be passed to seasonal with each element including a vector of components for respective lags.
# Python: Provide initial values as dictionary
model = ADAM(model="AAA", lags=12,
initial={"level": 100, "trend": 1, "seasonal": [0.9, 1.0, 1.1, ...]})If some components are provided but others are missing, the missing ones will be estimated:
# Provide level, estimate everything else
model <- adam(y, model="AAA", lags=12,
initial=list(level=100))model = ADAM(model="AAA", lags=12,
initial={"level": 100})Components can also be provided as a vector in the order: level, trend, seasonal, ARIMA, xreg (with no gaps).
# Order: level, trend, 12 seasonal values
init_vec <- c(100, 1, 0.9, 1.0, 1.1, 0.95, 1.05, 0.98, 1.02, 0.97, 1.03, 0.96, 1.04, 1.0)
model <- adam(y, model="AAA", lags=12, initial=init_vec)Note: Providing initial values as a plain vector is not supported in Python. Use a dictionary instead (see "As a Named List/Dict" above).
In R, The initialSeason parameter (in ES) allows specifying initial seasonal values separately:
# R: ES with specific seasonal initials
model <- es(y, model="AAA", lags=12,
initialSeason=c(0.9, 1.0, 1.1, 0.95, 1.05, 0.98,
1.02, 0.97, 1.03, 0.96, 1.04, 1.0))After fitting, you can access the initial values used:
# R: Access initial values
model <- adam(y, model="AAA", lags=12)
model$initial # Named list of initial values
model$initialType # Method used ("backcasting", "optimal", etc.)
model$initialEstimated # Which components were estimated# Python: Access initial values
model = ADAM(model="AAA", lags=12)
model.fit(y)
model.initial_states_ # Initial state values-
Default: Use
"backcasting"- it's fast and usually sufficient -
Short series: Consider
"optimal"or"gradient"if you don't like the model fit from "backcasting" -
Fast + accurate:
"gradient"gives optimal-quality initials at near-backcasting cost for additive / mixed models -
Seasonal + trend instability: If
"backcasting"returns odd initials on ETS(A,A,A)-type models, use"gradient" -
With regressors: If the sample size is large and you don't want to wait, use
"complete" - Domain knowledge: If you know reasonable initial values, provide them
- Numerical issues: If estimation fails, try different initialization methods
- Svetunkov, I. (2023). Forecasting and Analytics with the Augmented Dynamic Adaptive Model (ADAM). Online: https://openforecast.org/adam/
- Initialisation: Section 11.4.
- Hyndman, R.J., et al. (2008). Forecasting with Exponential Smoothing: The State Space Approach. Springer.
- ADAM - Main ADAM function
- ES - Exponential Smoothing
- Persistence - Smoothing parameters
- Coefficients-and-Parameters - Extracting estimated parameters