Model Card

Model Name
demand_forecaster (weekly)
Model Type
Random forest regressor (scikit-learn)
Target
Units an item will use over its supplier lead time, net of the component requirements of jobs booked by the forecast date; the forecast is those requirements plus that remainder
Prediction Type
Regression on log(1 + usage), one forecast per item per week
Features
26 (rolling usage, calendar, item attributes, order book)
Tuning
Optuna, 12 trials per candidate, validation WAPE on total lead-time demand
Cadence
Refreshed every Monday; retrained monthly
Outputs
Reorder point and order quantity per item, loaded into the ERP
Held-out 2025 WAPE, total demand
43.0%
Live 1H 2026 WAPE (April 2026)
44.7%
Purpose
Forecasts each stocked item's usage over its supplier lead time and turns it into a reorder point and order quantity for the ERP's reorder queue. Intended as decision support for reordering: buyers review the queue and release or override each line.

Training Data

The demand forecasting model learns from the shop's weekly usage of its stocked items. It scores 1,336 of the 1,339 stocked items; the other three are successor parts with no usage history yet. Each training row is one item on one forecast date. Its features describe the item's usage and order book up to that date, and its target is the usage over the following lead time, rounded to whole weeks.

The historical data is split by date and never shuffled. Training rows start at week 52 of the history, because every forecast needs a full year of usage behind it. A 26-week validation block before 2025 was used to tune and compare the candidates, and 2025 was held out to score the winner. Each split keeps its whole forecast horizon before the next window starts, so no training target overlaps a validation week and no validation target overlaps 2025.

The first six months of 2026 are the model's live output; the model is retrained monthly on every forecast date whose outcome is known.

SplitForecast datesForecastsItemsMedian target (units)Zero-usage share
Train2024-01-01 to 2024-07-0127,8621,3362514%
Validation2024-07-08 to 2024-12-3026,5261,3362414%
Test2025-01-06 to 2025-12-2259,9261,3362713%
Live2025-12-29 to 2026-06-2226,4011,3342614%
Weekly Usage by Split

The model's 26 features fall into four groups. The first is Rolling Usage, including usage windows (4, 13, 26 and 52 weeks), the count of weeks with any usage, the time since the last usage and the recent variability. The second is Calendar Features, to let the model learn seasonal demand patterns. The third is Item Attributes, including cost, lead time, demand pattern, value class and category, to tell the model how to read each item's usage history. The fourth is the Order Book: the component requirements of jobs booked on or before the forecast date, namely the requirements due inside the lead-time window and in the four weeks after it, the subset already released, the open job count, the book's cover of average usage, and the product-family backlog. The correlation figures presented are Spearman rank correlations with the target on the training rows, which suit the skewed, zero-heavy usage.

FeatureDescriptionTypeCorr. with target
s4Usage, last 4 weeksRolling usage+0.35
s13Usage, last 13 weeksRolling usage+0.60
s26Usage, last 26 weeksRolling usage+0.61
s52Usage, last 52 weeksRolling usage+0.61
nz13Weeks with usage, last 13Rolling usage+0.41
nz52Weeks with usage, last 52Rolling usage+0.43
since_nzWeeks since last usageRolling usage-0.20
cv13Week-to-week variability, last 13 weeksRolling usage-0.19
trendRecent trend (4-week rate less 13-week rate)Rolling usage-0.15
lyUsage in the same weeks last yearRolling usage+0.73
mean_allAverage weekly usage since history beganRolling usage+0.61
woyWeek of yearCalendar-0.11
monthMonthCalendar-0.11
std_costStandard unit costItem attribute-0.36
leadSupplier lead time (days)Item attribute+0.40
annualAnnual usageItem attribute+0.51
seg_codeDemand patternItem attribute-0.19
abc_codeValue class (ABC)Item attribute+0.03
cls_codeItem categoryItem attribute-0.18
hForecast horizon (lead time, weeks)Item attribute+0.40
firm_hComponent requirements of booked jobs due inside the lead-time windowOrder book-0.00
firm_rel_hOf those, the requirements of jobs already releasedOrder book-0.01
firm_next4Requirements of booked jobs due in the four weeks after the windowOrder book-0.08
open_jobsOpen booked jobs drawing the itemOrder book-0.01
book_coverBooked requirements as a share of average usage over the windowOrder book-0.07
fam_backlogProduct-family backlog of booked jobsOrder book-0.05

The rolling usage windows are strongly correlated with one another, since they overlap in time. The weeks-since-last-usage and variability features move against the usage windows, as expected for intermittent items. Unit cost runs against usage (-0.44 to -0.48), because expensive items are used in smaller quantities. Last year's usage correlates only +0.71 with the 52-week total, so its timing adds information beyond the average level. The order-book features correlate weakly with the target because the target is usage net of booked requirements; their value is in the booked quantity itself, which enters the forecast directly, and in book_cover, which the model uses to read how much of an item's usage the book already explains.

Feature Correlation Heatmap (numeric features, Spearman)

The target is heavily right-skewed: most lead-time windows use a few dozen units, while fasteners and consumables run to thousands. The model is therefore trained on log(1 + usage), so the few very high-volume items do not dominate the fit and the model learns proportional patterns across items of very different sizes. This distribution is stable across the three splits, as shown below.

Target Distribution (usage net of booked requirements): Train / Validation / Held-out Test

Known Demand and the Forecast Target

Part of an item's usage over its lead time is known on the forecast date: the component requirements of jobs already booked. On the parts that sit on a bill of materials, those requirements cover 36% of usage over the lead time; parts on no bill have none. The order book's own timing error against what the floor actually backflushed in the window is 16.7% (WAPE). The model forecasts only the remainder, because the ERP nets the booked requirements itself: forecasting them too would count them twice.

PartsItemsShare of lead-time usage covered by booked jobs
Parts on a bill of materials51636%
Parts on no bill8200%

Model Selection & Performance

Model Selection

Three candidates, a ridge regression, a random forest and an XGBoost gradient-boosted model, were each tuned with Optuna (12 trials per model) on the validation weeks, using weighted absolute percentage error (WAPE) on total lead-time demand (the booked requirements plus the forecast remainder) as the objective. The selection rule picks the lowest validation WAPE on total demand; the booster is preferred only when it finishes within half a point of the best, and within 0.3 points the smaller feature set wins. The models were then refit on train plus validation and scored once on the held-out 2025 year. The random forest had the lowest validation error and was selected.

ModelValidation WAPEHeld-out 2025 WAPETuned hyperparameters
Random forest ✔ Selected45.6%43.0%n_estimators 300, max_depth 16, min_samples_leaf 8
XGBoost47.6%45.7%n_estimators 250, max_depth 4, learning_rate 0.0219, subsample 0.798, colsample_bytree 0.755, min_child_weight 3, reg_lambda 3.4
Linear regression (ridge)74.2%78.6%alpha 76.1

The best random forest model has 300 trees with a maximum depth of 16 and at least 8 rows per leaf. The relatively large leaf-size floor keeps the model from fitting individual spikes and instead learning the items' typical usage patterns.

Model Performance

Accuracy is measured as WAPE: the total absolute gap between forecast and actual usage across all forecasts, divided by total actual usage. The fair comparison is the order book plus the best simple method by demand pattern, which knows the same booked requirements: on the held-out 2025 year it scores 47.2%, against 43.0% for the model's raw forecast. The reorder points use the bias-corrected forecast (Section 5), which trades some accuracy (43.0% to 46.5% on the held-out year) for forecasts that do not run systematically low. Live figures are the monitor's latest matured month.

MetricValidationHeld-out 2025Live, Apr 2026
Order book + best simple method by pattern, WAPEn/a47.2%44.7%
Model, raw forecast, WAPE45.6%43.0%n/a
Model, bias-corrected forecast (used for reorder points), WAPEn/a46.5%44.7%
Best simple method by pattern (usage history only), WAPEn/a49.7%n/a
Forecast bias, after correctionn/a+4.2%+5.7%
Forecasts scored26,52659,9264,669

A live WAPE of 45% means that for every 100 units an item used over its lead time, the forecast was off by about 45 units in either direction. Across the matured months from January to April it ran 42.5% to 45.6%. That is typical for item-level forecasts of lumpy, job-driven demand, where a single job or spare-parts order can double an item's usage in a week. The errors largely cancel across items: over all live forecasts scored by June 30, total forecast usage was within 1.3% of actual. Most of the operational improvement comes from how the forecast is used, covered in Section 5.

The learning curve refits the selected model on growing random shares of the training and validation rows. The held-out error flattens well before the full training set, so more of the same history adds little.

Learning Curve

Calibration compares the mean forecast with the mean actual usage within each tenth of the forecasts, from smallest to largest. Points on the diagonal mean a forecast of, say, 50 units really does average about 50 units of usage. After the bias correction described in Section 5, the live forecasts track actual usage within 10% from about 23 units up, with the largest tenth running 6% high. Below that, actual usage runs above the forecast: the smallest tenth of live forecasts average 1.1 units against 2.4 used, and the held-out year shows the same shape more strongly. The safety buffer absorbs that gap on the smallest items.

Calibration: Mean Forecast vs Mean Actual, by Forecast Decile

Error varies by demand pattern. Smooth items are forecast best and intermittent items worst, since an item used a few times a year at random offers little to learn from. The table compares the model with the order book plus the best simple method for each pattern, in the held-out year and live. The model's gain over the order book plus the best simple method is concentrated in lumpy and intermittent items in the held-out year; on smooth items the simple method is as good.

Demand patternModel, 2025Order book + simple, 2025Model, 1H26Order book + simple, 1H26Bias, 1H26
Smooth34%32%34%33%-2%
Erratic53%53%51%52%+5%
Lumpy48%53%45%51%-3%
Intermittent68%74%62%61%+14%
Live WAPE by Demand Pattern, Model vs Order Book + Best Simple Method

Plotted against actual usage on log scales, the live forecasts cluster around the diagonal across four orders of magnitude, meaning the same model tracks items that use a handful of units per lead time as well as those that use thousands. The spread around the diagonal is the item-level error that the safety buffer absorbs.

Forecast vs Actual Usage, Live 1H 2026

Feature Study

Before go-live, groups of candidate features were added one at a time to the usage-history set: the order book, product families, shortage history, item lifecycle (also on a longer training history), supply, and calendar effects. Each rung was tuned and scored the same way, on total demand over the lead time. Only the order book improved held-out accuracy on the raw forecast, and it had the lowest validation error (45.3%); the later groups added features without improving the held-out raw forecast, so the smaller set was kept. The per-rung tables are in the appendix.

Held-Out 2025 WAPE by Rung of the Feature Study

Feature Importance (SHAP)

SHAP values measure each feature's average contribution to a forecast, here on a sample of the held-out 2025 forecasts and in units of log usage. The model leans most on usage in the same weeks last year, supplier lead time and the order book's cover of average usage. Last year's usage over the same weeks is by far the strongest, because it is the only feature measured over exactly the window being forecast. Lead time comes second, since it sets how long a window the forecast covers. The order book's cover of average usage comes third; the other order-book inputs, beyond the booked quantity itself, add little.

Calendar and category features contribute little. About 30% of items are seasonal, but each peaks at its own time of year, and last year's same-weeks usage already carries each item's own seasonal timing; a shared week-of-year or month feature adds little on top of it. Category adds little for a similar reason, since cost, usage level and demand pattern already capture most of what distinguishes the categories.

Mean Absolute SHAP Value by Feature

From Forecast to Reorder Decision

The model makes one prediction: the usage forecast, how many units each item will use over its supplier lead time. The reorder point and order quantity presented in the ERP are then calculated from that usage forecast using the rules below.

ElementRule
Reorder pointThe component requirements of booked jobs plus the forecast of remaining usage over the lead time, plus safety buffer; the ERP nets the booked requirements against released jobs
Fill-rate targetsProduction items 99%, spare parts 98.5%, shop supplies 98.5%
Safety bufferk × σ, with k the smallest multiple whose expected shortfall per cycle, on the model's own error distribution, fits (1 - fill target) × order quantity
σ (uncertainty, in units)The typical size of the gap between the usage forecast and actual usage over the item's lead time (one standard deviation): √(forecast error² + (daily usage × lead-time standard deviation)²). The forecast error is the standard deviation of the item's own forecast misses, scaled to its lead time; the second term is the variability of the supplier's delivery time
Order-book visibilityCustomer orders are booked 28 to 56 days before their jobs are released, and jobs require their components 10 to 46 days after release, so the order book shows a component requirement 38 to 102 days ahead (about 5 to 15 weeks)
Order quantityEconomic lot: √(2 × annual usage × $35 per order line ÷ (25% holding × unit cost)), kept between 14 and 120 days of usage.
Annual usage: the model's usage forecast, at a yearly rate. Unit cost: standard cost from the item master. $35 per order line (assumption): the fully loaded cost of placing and processing one line (buyer time, receiving and inspection, putaway, invoice matching); published estimates for manufacturers run roughly $20 to $100+ per purchase order, less per line. 25% holding (assumption): the usual 20 to 30% rule of thumb covering cost of capital, storage, handling, insurance and obsolescence. 14 to 120 days (judgment): no item ordered more often than about every two weeks, and no more than four months of a cheap item at once, below the buyers' manual 135-day lot. Supplier minimum order quantities, price breaks and freight are not modeled.
Change thresholdA reorder point moves only when the new value differs by more than 20%
Lead timesThe corrected supplier lead time from the item master, refreshed from receipts; a supplier-level lead-time review in monitoring flags masters that have drifted
Inbound ordersPushed back when not yet needed; never on production items

Bias correction. Trained on log usage, the model's back-transformed forecasts estimate the median rather than the mean, so they run low. Each demand pattern's forecasts are scaled by a factor re-estimated at each monthly retrain from the trailing 52 weeks of out-of-sample errors. The table shows the factors at the first live retrain and the corrected bias by month from the monitor. The correction removes the systematic under-forecasting for smooth, erratic and lumpy items; intermittent items were over-corrected in March and April.

Demand patternFactor, Jan 2026 retrainCorrected bias, JanCorrected bias, FebCorrected bias, MarCorrected bias, Apr
Smooth×1.22-1%-4%-1%+2%
Erratic×1.47+1%+3%+7%+9%
Lumpy×1.25-7%-5%+5%+2%
Intermittent×1.70+3%+6%+27%+24%

Order quantity. The recommended order quantity for each item, calculated from its usage forecast, balances the cost of placing an order line against the cost of holding stock. Expensive, heavily used items are ordered every few weeks, and cheap items a few times a year.

The chart below groups items by value class. The classes are set by annual usage value (units used × unit cost): A items are those that together make up the first 80% of usage value, B items the next 15% and C items the last 5%. In 2025 the typical A item used about $11.5K of stock a year (most above $5.4K) at a median unit cost of $36; a typical B item about $3.1K a year at $11; and a typical C item about $640 a year at $2. The A items, where most of the money sits, are bought in the smallest lots. See the ML Model Overview report for more detail on this order quantity approach.

Order Quantity in Days of Usage, by Value Class

Safety buffer. The buffer is calculated as k standard errors of the item's own forecast error: k × σ, where σ combines the forecast's miss over the lead time with the variability of the supplier's delivery time, and k sets how many of those standard errors to hold. k is not taken from a normal curve. It is set on the model's actual errors so that the expected shortfall per replenishment cycle stays within the fill-rate target for the item's criticality group. The errors have much fatter tails than a normal curve: at k = 2 the expected shortfall is 2.5 times what a normal distribution implies, and at k = 3, 7.1 times. This is important to ensure an adequate buffer size. Because the shortfall allowance scales with the order quantity, an item ordered in large lots needs less buffer (its own lot protects most of the cycle), and an item ordered often needs more.

Expected Shortfall vs Buffer Size: Actual Errors vs Normal

Known Limitations

Deployment & Operations

How the model runs in production and where its inputs come from.

SpecificationDetail
Scoring cadenceWeekly (Monday): a usage forecast, reorder point and order quantity for all 1,336 scored items; the ERP checks every item against its point daily
RetrainingMonthly, on a Lakeflow job (pipeline_update → train → promote → score → monitor). Promotion gates: selection, parity, completeness, beats-baseline and bias. A new version moves the champion alias in the Unity Catalog model registry only when every gate passes
Run timeOne single-node job cluster: pipeline update 3 to 4 minutes, train 32 to 35, score 14 to 15, monitor about 2
Outputsgold.reorder_schedule (per item and week: the reorder level, safety stock, forecast, horizon, reorder point and order quantity) and gold.reorder_queue (the as-of view the ERP's reorder queue reads)
Data lineageLanded extracts → Lakeflow pipeline (bronze; silver, with the data-quality flags; gold) → the dfm package → gold tables → ERP reorder queue. MLflow logs the input tables of every model version
Retraining triggersJudged on matured months (at least 80% of forecasts scored). Investigate when live WAPE is above its 2025 level, overall or for any demand pattern. Full re-tune when overall WAPE is more than 3 points above the 2025 reference, WAPE for a demand pattern is more than 5 points above its 2025 level, or corrected bias, overall or for a pattern, is outside ±10%. Safety buffers are recalibrated when achieved fill rate is more than 1 point below target for a criticality group; stockout episodes or jobs held for material above the 2025 monthly average call for investigation. The promotion's bias gate applies the monitor's bias rule to the schedule in force. See the monitoring report

Getting the numbers into the ERP takes two planning fields per item per week, the reorder point and the order quantity. They are written through the ERP's API where it offers one, and otherwise through its import utility after the purchasing manager reviews the queue; the buyers review the queue in both cases.

Every reported figure comes from a fixed-seed run, archived with a checksum manifest and reproduced on the platform.

Feature Study Tables

Held-out 2025 WAPE on total demand for the selected model at each rung, raw / bias-corrected.

Demand patternReferenceOrder bookFamiliesShortageLifecycleLifecycle on longer historySupplyCalendar
smooth34.4% / 36.8%32.2% / 34.1%32.4% / 33.9%32.8% / 34.1%33.2% / 34.0%32.6% / 33.0%32.9% / 33.9%33.4% / 33.5%
erratic49.8% / 54.7%47.8% / 53.0%48.0% / 53.0%48.5% / 53.0%48.6% / 52.6%49.2% / 53.4%49.6% / 53.7%48.1% / 51.0%
lumpy44.8% / 48.1%44.0% / 48.2%44.4% / 47.8%44.2% / 48.5%45.2% / 48.3%45.2% / 46.8%45.5% / 47.4%53.2% / 45.6%
intermittent70.4% / 72.6%66.6% / 68.3%66.4% / 68.6%67.0% / 69.4%66.2% / 67.7%69.1% / 73.0%69.5% / 73.7%69.2% / 68.0%
CriticalityReferenceOrder bookFamiliesShortageLifecycleLifecycle on longer historySupplyCalendar
line41.9% / 46.3%36.8% / 42.2%36.9% / 41.9%37.2% / 42.0%37.1% / 41.7%37.7% / 41.7%37.8% / 42.6%37.4% / 41.6%
service46.6% / 49.6%47.9% / 50.1%47.7% / 49.5%48.2% / 49.6%49.0% / 49.4%47.7% / 49.2%48.1% / 49.2%51.6% / 46.9%
standard46.2% / 49.2%46.2% / 48.8%46.7% / 48.9%46.9% / 49.5%47.5% / 49.0%47.8% / 48.7%48.3% / 49.3%51.0% / 46.9%
Item categoryReferenceOrder bookFamiliesShortageLifecycleLifecycle on longer historySupplyCalendar
Consumables39.5% / 40.8%39.2% / 39.7%39.2% / 39.8%39.6% / 40.8%40.1% / 40.8%38.6% / 38.7%38.8% / 39.3%39.9% / 38.0%
Electrical45.8% / 47.9%41.7% / 47.3%41.8% / 46.1%41.8% / 46.6%42.7% / 46.8%43.0% / 47.3%43.1% / 48.4%45.7% / 47.6%
Fasteners41.6% / 45.3%40.5% / 43.2%40.5% / 43.0%41.0% / 43.2%41.3% / 42.9%41.3% / 42.6%41.8% / 43.2%43.6% / 41.6%
Fittings46.0% / 51.3%43.9% / 49.9%44.6% / 50.1%44.7% / 50.2%45.2% / 49.3%46.0% / 48.7%45.8% / 48.6%48.4% / 47.5%
Hardware51.0% / 54.9%48.9% / 53.3%49.3% / 53.2%49.3% / 53.5%49.2% / 53.1%50.7% / 52.9%51.1% / 54.0%51.7% / 50.9%
MISC46.0% / 48.9%43.8% / 46.6%44.1% / 46.9%44.6% / 47.2%45.1% / 46.6%45.6% / 48.7%46.1% / 49.9%47.2% / 46.7%
Mechanical49.7% / 55.0%46.0% / 52.8%46.1% / 52.2%46.4% / 52.7%47.0% / 52.5%46.8% / 52.7%47.4% / 53.9%48.7% / 51.4%
Outside Service42.9% / 44.8%44.3% / 44.0%45.4% / 43.8%46.0% / 43.5%46.9% / 43.0%45.2% / 43.5%45.3% / 43.1%46.7% / 42.9%
Raw Material42.3% / 46.6%39.4% / 44.4%39.7% / 44.7%39.8% / 44.6%40.3% / 44.0%40.4% / 43.6%40.6% / 43.8%43.0% / 42.2%
Value classReferenceOrder bookFamiliesShortageLifecycleLifecycle on longer historySupplyCalendar
A44.8% / 46.9%42.5% / 44.7%42.7% / 44.4%43.1% / 45.0%43.9% / 45.2%43.5% / 44.6%43.7% / 44.9%46.7% / 44.5%
B43.8% / 46.5%42.1% / 44.6%42.1% / 44.0%42.8% / 44.5%43.0% / 43.9%42.9% / 43.4%43.2% / 44.1%45.7% / 43.7%
C45.0% / 50.0%43.4% / 48.8%43.9% / 49.1%43.7% / 49.0%44.0% / 48.6%44.8% / 48.9%45.2% / 49.8%45.3% / 45.8%

Bias-correction factors by demand pattern for the selected model at each rung, estimated on validation.

RungSmoothErraticLumpyIntermittent
Reference1.2011.3471.3491.420
Order book1.2201.4001.3691.382
Families1.2191.3881.3661.368
Shortage1.2361.4041.3791.361
Lifecycle1.2431.4111.3971.398
Lifecycle on longer history1.1921.3651.4511.351
Supply1.2471.3941.4981.364
Calendar1.2771.4411.4901.509

Simple methods on the feature-study rows.

Simple method (feature-study rows)Held-out 2025 WAPE
4-week rate87.8%
13-week rate56.3%
52-week rate54.1%
Same weeks last year61.4%
Best of the four by pattern49.9%
Order book + 13-week rate of the remaining usage53.7%
Order book + best of the four on the remaining usage, by pattern47.3%

Leakage tests: the order-book inputs replaced by their values four weeks earlier. A forecast that leaned on information not yet available on the forecast date would lose much of its accuracy when lagged; these lose 0.2 to 1.3 points.

Lagged four weeksHeld-out WAPE, as observedHeld-out WAPE, laggedChange
Order book (selected set): inputs42.8%43.1%+0.3 pts
Order book (selected set): inputs and booked total42.8%44.1%+1.3 pts
All groups: order-book inputs45.8%46.0%+0.2 pts
All groups: order-book inputs and booked total45.8%46.7%+0.9 pts