Predictive Maintenance MLOps Platform
Industrial equipment rarely fails without warning; the warning is just buried in sensor data. This project turns that data into a failure-prediction service with the production loop around it: a cost-tuned alert threshold, per-prediction explanations, drift monitoring, and CI that retrains the model from scratch on every push.
Why this project
Before moving into data, I worked as a mechanical engineer, and I later spent nine years building failure-prediction models for engineering teams as a data analyst. Unplanned downtime is expensive and mostly preventable. Most ML portfolio projects stop at a notebook with a good F1 score; in industry the hard part starts after that, when the model has to run reliably as data shifts underneath it.
What it does
- Trains an XGBoost failure classifier on the AI4I 2020 dataset (10,000 machining cycles, 3.4% failure rate), against a logistic regression baseline it has to beat
- Picks the alert threshold by minimising expected cost: a missed failure (~£8,000 unplanned stop) hurts 27x more than a false alarm (~£300 inspection), so the deployed threshold trades precision for 96% recall on purpose
- Serves predictions through a FastAPI service with strict Pydantic validation; every prediction returns its top SHAP drivers so an engineer sees why the machine was flagged
- Monitors serving batches for drift with a Population Stability Index monitor implemented from scratch, referenced to the training distribution
- CI retrains the model from scratch on every push, runs the API tests against the fresh artifacts, builds the Docker image and smoke-tests a live prediction
Architecture
FeaturesOne shared feature function for training and serving, so skew cannot happen; leaky per-mode failure flags dropped at load
↓
TrainingBaseline vs XGBoost with stratified CV; cost-tuned threshold; artifacts + metrics + drift reference saved
↓
Inference APIFastAPI /predict with SHAP drivers, /drift, /health; Dockerised with healthcheck
↓
MonitoringPSI per feature vs training reference; a simulated heatwave scenario flags exactly the shifted features
↓
CI/CDGitHub Actions: retrain -> test -> docker build -> live smoke test on every push
Results
- PR-AUC 0.888 and ROC-AUC 0.987 on a 2,000-cycle holdout
- Cross-validated PR-AUC 0.855 vs 0.459 for the logistic baseline
- 96% recall at the cost-optimal threshold (precision 39%, by design; the cost model is documented in the repo)
- Drift monitor: clean replays stay under 0.03 PSI; a simulated heatwave plus stretched tool-change interval flags air temperature, cooling gap and tool wear and nothing else
- 14 tests including live API tests; MLflow logging is optional (one env var) so the repo runs with zero infrastructure
Skills demonstrated
- Imbalanced classification done properly: PR-AUC selection, baseline comparison, cost-based threshold tuning
- MLOps: reproducible training, drift monitoring, retrain-on-every-push CI, model explainability (SHAP)
- API engineering with FastAPI and Pydantic, containerised with Docker
- Leakage and skew defences: shared train/serve feature code, leaky columns dropped explicitly
- Domain knowledge: a decade around industrial equipment and maintenance data