Forecasting and Uncertainty

This page collects the forecasting and uncertainty tutorials into a single, repeatable sequence.

Table of contents

Explore Demand Data and Define the Forecast Grain

Start by looking at the demand pattern at two grains.

  1. Start from a session with the 1-echelon 2017 dataset.
  2. Paste the script and run it.
  3. You should now see daily and weekly demand line charts.
read "/sample/Lokad_Orders.tsv.gz" as Orders expect [date] with
  "Date" as date : date
  Quantity : number

Day.Demand = sum(Orders.Quantity)
Week.Demand = sum(Day.Demand)

show linechart "Daily demand" with
  Day.Demand

show linechart "Weekly demand" with
  Week.Demand

You should now have a quick sense of which grain is smoother and easier to forecast.

Fit First Point Forecast Model with Autodiff

Fit a small trend model to a short demand series.

  1. Paste the script and run it.
  2. You should now see the fitted base and slope plus a table of the trend values.
  3. Adjust one demand value and re-run to see the fit change.
table History[date] = with
  [| as date, as Demand |]
  [| date(2024, 1, 1), 120 |]
  [| date(2024, 1, 2), 118 |]
  [| date(2024, 1, 3), 125 |]
  [| date(2024, 1, 4), 130 |]
  [| date(2024, 1, 5), 128 |]
  [| date(2024, 1, 6), 132 |]

History.Index = rank() scan date

autodiff History epochs:40 learningRate:0.05 with
  params base auto
  params slope auto
  Pred = base + slope * History.Index
  err = Pred - History.Demand
  return (err^2, mae: abs(err))

History.Trend = base + slope * History.Index

show summary "Fitted trend" with
  base
  slope

show table "Demand vs trend" with
  History.date
  History.Demand
  History.Trend

You should now have a first point-forecast model in place.

Turn a Point Forecast into a Quantile Forecast

Convert a point forecast into a set of quantiles you can act on.

  1. Paste the script and run it.
  2. You should now see a table with P10, P50, and P90 bands.
  3. Increase the dispersion to widen the bands.
start = date(2024, 3, 1)
keep span date = [start .. start + 13]

Day.t = date - start
Day.Point = 120 + 2 * Day.t
Day.Dist = negativeBinomial(Day.Point, 2)

Day.P10 = quantile(Day.Dist, 0.10)
Day.P50 = quantile(Day.Dist, 0.50)
Day.P90 = quantile(Day.Dist, 0.90)

show table "Quantile forecast" with
  date
  Day.Point
  Day.P10
  Day.P50
  Day.P90

You should now see how uncertainty bands wrap the point forecast.

Simulate Demand Paths with Monte Carlo

Use Monte Carlo sampling to capture variability in demand.

  1. Paste the script and run it.
  2. You should now see median and P90 demand for each day index.
  3. Increase the number of simulations for a smoother curve.
table Horizon = extend.range(14)
Horizon.Day = Horizon.N

montecarlo 200 with
  Horizon.Demand = random.poisson(20 into Horizon)
  sample Horizon.Dist = ranvar(Horizon.Demand)

Horizon.P50 = quantile(Horizon.Dist, 0.50)
Horizon.P90 = quantile(Horizon.Dist, 0.90)

show table "Monte Carlo demand" with
  Horizon.Day
  Horizon.P50
  Horizon.P90

You should now have a simple distribution view of demand paths.

Compute Demand Over Lead Time

Combine variable demand and variable lead time into a single lead-time demand distribution.

  1. Paste the script and run it.
  2. You should now see a lead-time demand P50 and P95 per SKU.
  3. Change the daily demand or lead time means to see the distribution shift.
table Items[id] = with
  [| as id, as DailyMean, as LeadTimeMean |]
  [| "A-100", 5, 7 |]
  [| "B-200", 8, 12 |]
  [| "C-300", 3, 5 |]

table Days max 1000 = extend.range(Items.LeadTimeMean * 4)

montecarlo 300 with
  Items.LeadTimeSample = 1 + random.poisson(Items.LeadTimeMean into Items)
  Days.DailySample =
      if Days.N <= Items.LeadTimeSample then
        random.poisson(Items.DailyMean into Days)
      else
        0
  Items.LeadTimeDemand = sum(Days.DailySample)
  sample Items.LeadTimeDist = ranvar(Items.LeadTimeDemand)

Items.LeadTimeP50 = quantile(Items.LeadTimeDist, 0.50)
Items.LeadTimeP95 = quantile(Items.LeadTimeDist, 0.95)

show table "Lead-time demand" with
  Items.id
  Items.LeadTimeMean
  Items.LeadTimeP50
  Items.LeadTimeP95

You should now have a lead-time demand distribution that accounts for both sources of variability.

Visualize Forecast Uncertainty for Decision-Making

Plot uncertainty bands so decisions can account for risk.

  1. Paste the script and run it.
  2. You should now see P10, P50, and P90 lines on the chart.
  3. Widen the standard deviation to see the band spread.
start = date(2024, 4, 1)
keep span date = [start .. start + 20]

Day.t = date - start
Day.Point = 80 + Day.t
Day.Dist = normal(Day.Point, 12)

Day.P10 = quantile(Day.Dist, 0.10)
Day.P50 = quantile(Day.Dist, 0.50)
Day.P90 = quantile(Day.Dist, 0.90)

show linechart "Forecast bands" with
  Day.P10 as "P10"
  Day.P50 as "P50"
  Day.P90 as "P90"

You should now see a clear uncertainty band for decision-making.

User Contributed Notes
0 notes + add a note