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.

Plant B · Tue · Standardabout 144 m³ across the day · busiest 9:00, 10:00, 11:005:006:007:008:009:0010:0011:0012:0013:0014:0015:0016:0017:0018:0002142m³busiest hoursmodel range

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.

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.
4.38 m³average error per active plant-hour on held-out weeks (real result)
37% lowervalidation error than the historical median: 5.23 against 8.37 m³ (real result)

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.

Decision 01Chronological selection

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.

No leaks

Ticket volume, ticket count and average ticket size describe the answer, so they never feed the model.

Later weeks only

Models are chosen on weeks after their training data, the way the tool meets new days.

A person decides

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.

  1. 01

    Pilot with one plant's dispatch team before any wider rollout.

  2. 02

    Forecast every hour, including hours with no demand, using only what is known at forecast time.

  3. 03

    Replace the spread across trees with calibrated prediction ranges.

Next projectFleet Maintenance and Inventory Optimization