Skip to content

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:

  1. Demand size — the magnitude of non-zero demands
  2. 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

from durbyn import CrostonSBA

model = CrostonSBA().fit(data)
fc = model.forecast(h=12)

CrostonSBJ

from durbyn import CrostonSBJ

model = CrostonSBJ().fit(data)
fc = model.forecast(h=12)

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:

from durbyn import Croston

model = Croston().fit(data)
fc = model.forecast(h=12)

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}")