A live, interactive diabetes risk predictor — move the sliders, get a probability and a SHAP explanation of why, not just a number.
Try it live · scikit-learn · SHAP · Streamlit
Educational demo trained on a public research dataset. Not medical advice, not a diagnostic tool — do not use this for an actual health decision.
Most portfolio ML apps ship one model and assert it's good. This one:
- Compares three models honestly on 5-fold cross-validated ROC-AUC — a logistic regression baseline, a small ANN, and gradient boosting — and picks whichever actually wins, rather than defaulting to whichever is trendiest. (Logistic regression won here — 0.834 CV ROC-AUC vs. 0.792 for gradient boosting and 0.757 for the ANN. The simplest model beating both more complex ones is a real, common result on a 768-row dataset, not a letdown.)
- Explains individual predictions with SHAP, not just an aggregate feature-importance chart. Two patients with the same risk score can get there for completely different reasons; the app shows which measurements drove this prediction, in the units you actually typed.
- Treats implausible zeros as missing data, not as real measurements.
Several columns in this dataset use
0to mean "not recorded" (nobody has a blood pressure of zero) — imputing the median instead of training on literal zeros is a real, if small, data-quality fix over a naive read of the raw CSV.
diabetes.csv
│
▼
train.py impute (median) → scale → {logistic regression, ANN, gradient boosting}
│ 5-fold CV ROC-AUC picks the winner, retrained on the full train split
▼
model/ pipeline.joblib, background.joblib (for SHAP), metrics.json
│
▼
app.py loads the saved pipeline, predicts live, explains with SHAP
pip install -r requirements.txt
python train.py # trains, compares, saves model/
streamlit run app.pyRun python train.py to reproduce — it prints the cross-validated comparison
and the held-out test metrics for the winning model. The same numbers are
shown in the app's "About this model" panel, sourced from model/metrics.json
rather than hardcoded, so they can't drift out of sync with what's deployed.
Held-out test ROC-AUC: 0.874.
pytestCovers the missing-value handling (the zero-as-NaN fix is the one place a
silent bug would be easy to introduce) and confirms all three candidate
pipelines fit and predict without error before training ever compares them.
CI also retrains on every push and fails if the committed model/ artifacts
drift from what train.py actually produces.
notebook/ has the original exploratory notebook this project grew out of —
manual outlier capping, a single ANN, no saved artifacts, no live app. Kept
for reference rather than deleted; the current version replaced the ad-hoc
preprocessing with a proper sklearn Pipeline and added the model comparison,
SHAP explanations, tests, and the deployed app.
Pima Indians Diabetes Database — 768 samples, 8 features, binary outcome. Public research dataset, no personal data.
MIT