Intermittent
polars_ts.applications.perishables.intermittent
Intermittent-demand models for sparse perishables SKUs.
Slow movers sell on a minority of days; standard smoothers collapse to near-zero or chase noise. Implements the classical sparse-demand family:
- Croston — separate exponential smoothing of nonzero demand sizes and inter-demand intervals.
- SBA (Syntetos-Boylan Approximation) — Croston with the
1 - alpha/2bias correction. - TSB (Teunter-Syntetos-Babai) — smooths demand probability every period, so obsolete SKUs decay toward zero.
Plus the standard ADI / CV² demand classifier (Syntetos et al.) used by
:func:intermittent_forecast to dispatch per SKU.
classify_demand(df, target_col='y', id_col='unique_id', time_col='ds')
Classify each SKU's demand pattern via ADI and CV².
ADI (average inter-demand interval, in periods) and CV² (squared
coefficient of variation of nonzero demand sizes) split SKUs into
the four Syntetos-Boylan quadrants at ADI 1.32 and CV² 0.49:
smooth, erratic, intermittent, and lumpy.
Parameters
df Gap-free canonical sales frame. target_col, id_col, time_col Canonical column names.
Returns
pl.DataFrame
Columns [id_col, "adi", "cv2", "demand_class"]. SKUs with no
nonzero demand get infinite ADI and class "intermittent".
_croston_rate(values, alpha, bias_correction=1.0)
Return the smoothed per-period demand rate via Croston's method.
_tsb_rate(values, alpha, beta)
Return the smoothed per-period demand rate via TSB.
_flat_forecast(df, h, rate_fn, target_col, id_col, time_col)
Emit h rows per SKU with a constant per-period rate from rate_fn.
croston_forecast(df, h, alpha=0.1, target_col='y', id_col='unique_id', time_col='ds')
Croston's method: constant demand-rate forecast for sparse SKUs.
Parameters
df Gap-free canonical sales frame (zeros must be explicit rows). h Forecast horizon (number of periods). alpha Smoothing factor for both demand sizes and intervals. target_col, id_col, time_col Canonical column names.
Returns
pl.DataFrame
Columns [id_col, time_col, "y_hat"] with h rows per SKU;
y_hat is the expected demand per period.
sba_forecast(df, h, alpha=0.1, target_col='y', id_col='unique_id', time_col='ds')
Syntetos-Boylan Approximation: bias-corrected Croston.
Applies the 1 - alpha/2 correction that removes Croston's
positive bias; the recommended default for intermittent and lumpy
SKUs.
Parameters
df Gap-free canonical sales frame. h Forecast horizon. alpha Smoothing factor. target_col, id_col, time_col Canonical column names.
Returns
pl.DataFrame
Columns [id_col, time_col, "y_hat"].
tsb_forecast(df, h, alpha=0.1, beta=0.1, target_col='y', id_col='unique_id', time_col='ds')
Teunter-Syntetos-Babai forecast for sparse SKUs with obsolescence.
Unlike Croston, the demand probability updates every period, so a SKU that stops selling sees its forecast decay toward zero — the right behaviour for delisted or seasonal perishables.
Parameters
df Gap-free canonical sales frame. h Forecast horizon. alpha Smoothing factor for demand sizes. beta Smoothing factor for demand probability. target_col, id_col, time_col Canonical column names.
Returns
pl.DataFrame
Columns [id_col, time_col, "y_hat"].
intermittent_forecast(df, h, method='auto', alpha=0.1, beta=0.1, target_col='y', id_col='unique_id', time_col='ds')
Forecast sparse SKUs, optionally auto-dispatching per demand class.
With method="auto", each SKU is classified via
:func:classify_demand: intermittent and lumpy SKUs use SBA,
smooth and erratic SKUs use Croston.
Parameters
df
Gap-free canonical sales frame.
h
Forecast horizon.
method
"auto", "croston", "sba", or "tsb".
alpha, beta
Smoothing factors (beta only used by TSB).
target_col, id_col, time_col
Canonical column names.
Returns
pl.DataFrame
Columns [id_col, time_col, "y_hat"].