Home/Case Studies/ML Inventory Forecasting
Retail & Supply Chain

A forecast nobody trusts is a spreadsheet with extra steps.

Demand planning built to be used: forecasts at the SKU and location level buyers order at, with confidence ranges visible so the planner can tell when to override it.

Machine-learning powered inventory and demand forecasting
SectorRetail & supply chainGrainSKU and locationHorizonReplenishment cycleShowsConfidence range, not a single numberHandlesSeasonality, promotions, new linesIntegratesInto the existing ordering process
The situation

Two failure modes, and both of them cost money quietly.

Stockouts lose the sale and sometimes the customer. Overstock ties up capital, occupies space and ends in markdown. Most planning processes trade one against the other using last year's numbers plus judgement, and the judgement is held by a small number of experienced people.

Statistical forecasting is not new, and that is precisely why previous attempts had failed. Forecasts produced at the wrong grain (category rather than SKU, national, not per location) are not actionable, because that is not the level at which anyone places an order.

The deeper problem was trust. A model that emits a single number with no indication of confidence gives a planner no basis for deciding when to override it, so they override it always, and the forecast becomes decoration.

What we built

Forecast where the decision is made, and show the uncertainty.

Forecasts are produced at SKU and location level over the replenishment horizon, because that is the unit of an actual buying decision. Anything coarser is a report instead of a tool.

Every forecast carries a confidence range instead of a point estimate. That single design decision is what makes the system usable: the planner can see where the model is confident and leave it alone, and where it is not and apply judgement.

The model accounts for seasonality, promotional uplift, day-of-week effects and the long tail of slow-moving lines where naive approaches perform worst. New products, which have no history at all, are handled by analogue rather than pretending a forecast exists.

It is delivered into the existing ordering workflow, not as a separate dashboard, with the planner's overrides captured as feedback. Overrides are signal: a line that is always overridden is telling you something the features do not yet capture.

Inside the system

What the system does.

01

SKU-location forecasting

At the grain buying decisions are made, over the replenishment horizon.

02

Confidence ranges

A band instead of a number, so overriding becomes a judgement instead of a habit.

03

Seasonality and promotions

Recurring patterns and promotional uplift modelled explicitly rather than smoothed away.

04

Slow movers

Explicit handling of the long tail, where naive forecasting is at its worst and the capital is quietly tied up.

05

New product handling

Analogue-based estimates, clearly labelled as such, instead of a forecast with no history behind it.

06

Override capture

Planner adjustments recorded as feedback, because a persistently overridden line is a missing feature.

07

Replenishment integration

Delivered into the existing ordering process rather than into another dashboard.

Built with

Built with.

Modelling

Gradient-boosted treesTime-series featuresHierarchical reconciliation

Data

Sales historyPromotional calendarStock positionsFeature store

Serving

Scheduled batch forecastingConfidence intervalsBacktesting harness

Delivery

Replenishment integrationPlanner review UIOverride feedback loop
What changed

What changed.

  • Forecasts became actionable. At SKU and location level, over the replenishment horizon, not at a grain nobody orders at.
  • Planners could tell when to intervene. Confidence ranges gave a basis for overriding some lines and trusting others, which is the difference between a used model and an ignored one.
  • The slow-moving tail stopped being ignored. Explicit handling of low-velocity lines, where the capital sits and where naive methods perform worst.
  • Overrides became a development input. Persistent manual adjustment identifies missing features, not being treated as user error.