Intermittent Demand¶
Croston variants for sparse/intermittent demand data from the IntermittentDemand module.
Overview¶
Intermittent demand data has many zero values with occasional non-zero "demands". Standard forecasting methods perform poorly on such data. The Croston family of methods decompose the problem into:
- Demand size — the magnitude of non-zero demands
- Inter-arrival time — the interval between non-zero demands
Three variants are provided:
| Class | Method | Reference |
|---|---|---|
CrostonClassic |
Original Croston method | Croston (1972) |
CrostonSBA |
Syntetos-Boylan Approximation | Syntetos & Boylan (2001) |
CrostonSBJ |
Shale-Boylan-Johnston | Shale, Boylan & Johnston (2006) |
CrostonClassic¶
from durbyn import CrostonClassic
data = [0, 0, 1, 0, 0, 0, 2, 0, 0, 1, 0, 0, 0, 0, 3, 0, 0, 0, 1, 0,
0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 1, 0]
model = CrostonClassic().fit(data)
fc = model.forecast(h=12)
print(fc.mean) # flat forecast
print(model.fitted_values) # in-sample fitted values
print(model.residuals) # in-sample residuals
CrostonSBA¶
CrostonSBJ¶
Shared Parameters¶
All three classes accept the same parameters:
| Parameter | Type | Default | Description |
|---|---|---|---|
init_strategy |
str |
"mean" |
Initialisation: "mean" or "naive" |
number_of_params |
int |
2 |
Number of smoothing parameters: 1 or 2 |
cost_metric |
str |
"mar" |
Cost metric: "mar", "msr", "mae", "mse" |
optimize_init |
bool |
True |
Optimise initial values |
rm_missing |
bool |
False |
Remove missing values |
Note
Intermittent demand models do not use a seasonal period m. They produce flat forecasts without prediction intervals.
Simple Croston¶
durbyn also provides a simpler Croston wrapper from the ExponentialSmoothing module:
See Exponential Smoothing for details.
Example: Comparing Variants¶
from durbyn import CrostonClassic, CrostonSBA, CrostonSBJ
import numpy as np
data = [6, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 2, 1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0]
for cls in [CrostonClassic, CrostonSBA, CrostonSBJ]:
model = cls().fit(data)
fc = model.forecast(h=12)
print(f"{cls.__name__}: forecast = {fc.mean[0]:.4f}")