Views
No views yet
scikit-learn multi-output RandomForestRegressor that predicts concrete
workability — slump (mm) and flow (mm) — from mix proportions. Trained on the
public UCI Concrete Slump Test dataset.Status: honest, modest baseline — read this before using it. Slump and flow are substantially harder to predict from mix proportions alone than compressive strength: they depend heavily on admixture chemistry, aggregate shape/grading, mixing energy, temperature, and time-since-batching that a 7-number mix vector simply does not capture. On this dataset the model explains only about a third of the variance (slump R² ≈ 0.36, flow R² ≈ 0.38 in 5-fold CV). It is a useful rough directional estimate and a transparent baseline — not a strong result, and not a substitute for a slump test. This is deliberately published at the same rigor as our strength model (R² ≈ 0.88), so the contrast in difficulty is visible rather than hidden.
app/backend/ml_models/data/slump_test.data.| Target | R² (5-fold CV) | MAE |
|---|---|---|
| Slump | 0.362 | 52.0 mm |
| Flow | 0.384 | 108.7 mm |
app/backend/ml_models/slump_predictor.py
(RandomForestRegressor(n_estimators=300, min_samples_leaf=2, random_state=42),
KFold(5, shuffle=True, random_state=42)).scaler.skops (a StandardScaler fit on the dataset):cement (kg/m³)blast_furnace_slag (kg/m³)fly_ash (kg/m³)water (kg/m³)superplasticizer (kg/m³)coarse_aggregate (kg/m³)fine_aggregate (kg/m³)_sklearn_version). Loading with a different scikit-learn raises
InconsistentVersionWarning and can change predictions — pin these exact
versions for guaranteed-consistent output:scikit-learn==1.9.0
skops==0.14.0
numpy==2.4.6pip install -r requirements.txt # bundled in this repo1import numpy as np
2from skops.io import load, get_untrusted_types
3
4f = "model.skops"
5model = load(f, trusted=get_untrusted_types(file=f))
6scaler = load("scaler.skops", trusted=get_untrusted_types(file="scaler.skops"))
7
8# cement, slag, fly_ash, water, SP, coarse, fine
9x = np.array([[273, 82, 105, 210, 9, 904, 680]], dtype=float)
10slump_mm, flow_mm = model.predict(scaler.transform(x))[0]
11print(round(slump_mm, 1), "mm slump /", round(flow_mm, 1), "mm flow")
12# -> 232.3 mm slump / 624.9 mm flow