Project
Ready-Mix Concrete Demand Forecasting
A concrete-demand screening system helps dispatch planners estimate active plant-hour volumes and administrators compare replacement models before promotion.
- Period
- April–June 2026
- Status
- Industry forecasting project
- Stack
- PythonFlaskscikit-learnpandasNumPyJoblibGunicornDockerpytestHTMLCSS
Demand forecast
Concrete demand per plant, hour by hour. Built for dispatch planning.
The product: pick a plant, weekday and product, and get the expected cubic metres for every hour, the range the model is unsure within, and the hours that will be busiest.
Two test weeks · pick a day
cell = one hour · brighter = larger error · dim = no demand that hour
Built on a company's real operating data. Under a confidentiality agreement, the numbers shown come from a masked replica that keeps the data's shape, not its values. The model race and the held-out test result are real results.
What it does
Hourly concrete demand per plant, so dispatch can plan the busy hours.
- Forecasts cubic metres per plant and hour for any weekday and product.
- Shows the busiest hours and the range the model is unsure within.
- Retrains on new data, but a person approves every model swap.
01Context
The problem,and my part in it.
The problem
Ready-mix dispatch planning depends on the alignment of orders, plant capacity, delivery schedules and route conditions. A daily total alone can conceal a busy hour at a particular plant. The modeling unit is therefore concrete volume summed for one plant, date and assignment hour, giving planners a measure aligned with hourly workload screening.
What I did
I owned the data and the model, from about 90,000 raw delivery tickets to the hourly forecast dispatch uses.
- Defined the target as concrete volume per plant per hour, the unit dispatch actually plans in.
- Cleaned the tickets into about 17,000 plant-hour rows and built 41 features from schedules, routes and plant capacity.
- Removed every input that leaks the answer and selected models only on later weeks, so the test matches how the tool meets new days.
- Compared four models and chose the Random Forest: 37% lower validation error than the historical median.
02Decisions
How it was built,and why.
Date-ordered partitions and time-aware folds reflect prediction into a later period. Random splitting was rejected because it mixes operating periods; chronology reduces the flexibility to shuffle observations for balanced samples.
03Guardrails
Three guardrailskeep the forecast honest.
Ticket volume, ticket count and average ticket size describe the answer, so they never feed the model.
Models are chosen on weeks after their training data, the way the tool meets new days.
A retrained model is scored on the same held-out hours as the current one and replaces it only when someone accepts; the old one stays for rollback.
04Next
Where it goesfrom here.
- 01
Pilot with one plant's dispatch team before any wider rollout.
- 02
Forecast every hour, including hours with no demand, using only what is known at forecast time.
- 03
Replace the spread across trees with calibrated prediction ranges.