Croston's method and its variants for intermittent demand forecasting.
Classes
Croston's method for intermittent demand forecasting.
__init__( self, alpha: float = 0.1, variant: str = 'classic', alpha_prob: float | None = None, )
Overview
- Walk through the series and record the non-zero demands and the
- Exponentially smooth the demand sizes into \hat{z}.
- Exponentially smooth the inter-arrival intervals into
- Form the per-period forecast \hat{y} = \hat{z} / \hat{p},
- The forecast is flat over the horizon.
Theory
Let z_j be the size of the j-th non-zero demand and q_j the number of periods since the previous one. On a period with a demand,
and on a period without demand both estimates are carried forward. The forecast is
with a variant-dependent correction factor c:
-
"classic": c = 1 (Croston, 1972). -
"sba": c = 1 - \alpha/2, the Syntetos-Boylan
-
"sbj": c = 1 - \alpha/(2 - \alpha), the
The "tsb" variant (Teunter, Syntetos and Babai, 2011) replaces the interval by the demand probability \hat{d}, updated every period,
which lets the forecast decay when demand stops -- Croston's estimate never does, making it obsolescence-blind.
Parameters
alpha
(0, 1].
variant
alpha_prob
"tsb" variant. Defaults to alpha when None. Ignored by the other variants.
Attributes
demand_
interval_
nan for the "tsb" variant, which does not estimate it.
probability_
nan for the Croston-family variants.
correction_
forecast_
n_nonzero_
fitted_values_
resid_
n_obs_
Notes
Complexity:
- Training: O(n).
- Prediction: O(h).
- Spare parts, slow-moving inventory and any series where most periods
- When the quantity of interest is the expected demand per period
-
Prefer
"sba"over"classic"in practice: the ratio estimator
-
Prefer
"tsb"when items go obsolete and the forecast must decay
References
See Also
>>> import numpy as np
>>> from tuiml.algorithms.timeseries.croston import CrostonForecaster
>>> y = np.array([0, 0, 0, 10, 0, 0, 0, 10, 0, 0, 0, 10], dtype=float)
>>> model = CrostonForecaster(alpha=0.1, variant="classic").fit(y)
>>> float(model.predict(steps=1)[0])
2.5
>>> sba = CrostonForecaster(alpha=0.1, variant="sba").fit(y)
>>> float(sba.predict(steps=1)[0])
2.375
Methods
fit
(self, y: np.ndarray, X: Optional[np.ndarray]=None) -> 'CrostonForecaster'
fit
(self, y: np.ndarray, X: Optional[np.ndarray]=None) -> 'CrostonForecaster'
Fit the Croston model to an intermittent demand series.
Parameters
y
X
Returns
self
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 the expected demand per period.
Parameters
steps
X
Returns
forecast
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 in one call.
Parameters
y
steps
Returns
forecast