Forecasting intermittent demand with Croston, ADIDA and TSB

Today let's understand how to forecast demand that is mostly zero, the kind a spare part gets when it only sells once in a while.

A parts warehouse stocks a replacement bearing for a factory conveyor. Here is how many of these bearings it sold, week by week, over the last 104 weeks.

Look at how the bars sit flat on the floor almost everywhere. Only a handful of weeks show a bar at all, and even then the height never climbs past single digits. That is what makes this series different from the sales charts you have forecast before, and it is going to need a different set of tools.

What makes a demand series intermittent

A series like this one has a name in forecasting: intermittent demand. Most periods see no demand at all, and the periods that do see demand arrive at irregular gaps.

Every week in a series like this carries two separate facts. The first is demand occurrence: did an order happen this week, yes or no. The second is demand size: if an order did happen, how many units did it ask for. A week can report zero on occurrence, and in that case size never even comes up. Keeping these two facts apart is going to matter a lot very soon.

Two numbers describe how intermittent a series actually is. The average demand interval (ADI) is the average number of weeks between one order and the next. The squared coefficient of variation of demand size (CV2) measures how much order size varies from one order to the next, relative to its average: a CV2 near 0 means every order is about the same size, and a larger CV2 means order sizes bounce around a lot.

The tsintermittent package computes both of these from the raw series, and recommends which smoothing method fits the pattern it finds.

RInteractive R
# Build the bearing's 104-week demand series and measure how intermittent it is library(tsintermittent) set.seed(9) n <- 104 occurs <- rbinom(n, 1, 0.14) sizes <- rpois(n, 2) + 1 demand <- occurs * sizes round(mean(demand == 0), 3) idc <- idclass(matrix(demand, nrow = 1)) idc$p round(idc$cv2, 3) idc$summary #> [1] 0.808 #> [1] 5.05 #> [1] 0.295 #> Series #> Croston 0 #> SBA 1 #> SES 0

  

80.8% of weeks really do show zero, matching the chart you just looked at. The average demand interval is 5.05 weeks between orders, and CV2 is 0.295, meaning order sizes vary a fair amount but not wildly. The summary table is idclass()'s recommendation: a 1 next to SBA and 0s next to Croston and SES means this series calls for the SBA-corrected variant of Croston's method, not plain Croston and not simple exponential smoothing (SES). You will meet SBA by name later in this lesson.

One more fact worth having on hand: across the 20 weeks that do carry an order, order size ranges from 1 to 7 units.