workface/coronary-artery-disease
Coronary Artery Disease Risk Estimator
Feature-selection-driven binary classifier for coronary artery disease, trained on the UCI Cleveland heart disease dataset and deployed as a Streamlit app.
  
Live demo: huggingface.co/spaces/workface/coronary-artery-disease
[!WARNING] Educational project — not medical advice. This model is trained on 303 records from a 1988 UCI dataset and has not been clinically validated. Do not use for diagnosis, treatment, or any medical decision.
Problem
Coronary artery disease (CAD) is typically confirmed by angiography — an invasive, expensive procedure. This project asks: given routinely-collected patient data (demographics, stress-test results, ECG findings), how accurately can we predict CAD before angiography, and which features actually matter? The answer informs which non-invasive measurements clinicians should prioritise.
Dataset
- Source: UCI Cleveland heart disease dataset
- Size: 303 patients, 14 columns
- Target:
ca_disease(0 = no disease, 1–4 = increasing severity → binarised to 0/1) - Class balance: roughly 54% / 46% — no rebalancing required.
- Missing values: 6 total (
?sentinels innum_major_vesselsandthallium_scint) → median imputation.
Methodology
- Cleaning — coerce
?to NaN, median-impute the 6 missing values, remapthallium_scintcodes{3:0, 7:1, 6:2}so they are ordered by severity, binarise the target. - EDA — distributions, correlations, violin plots for continuous features, bar charts for categoricals.
- Feature selection — four methods compared, keeping features that scored highly in at least two:
- statsmodels Logit coefficient significance
mlxtendexhaustive 1-feature searchSelectKBest(f_classiffor continuous,chi2for categorical)- Decision Tree and Random Forest feature importances
- Modelling — scaled Logistic Regression (deployed) and a Multi-Layer Perceptron (compared). Identical
random_state=0split as the notebook for reproducibility.
Results
Final 8-feature scaled Logistic Regression vs the 13-feature unscaled baseline (test set: 76 patients):
The final model uses fewer features, scales every feature so convergence is dramatically faster, and improves on the baseline across accuracy, recall, and ROC-AUC — at a small cost in precision.
Selected features
Features dropped (age, rest_blood_press, cholesterol, fasting_blood_sugar, rest_ecg) either failed every test or had their signal absorbed by a correlated retained feature (e.g. age ↔ maxheartrate).
Run locally
git clone https://github.com/tejaswirajgit/Coronary-Artery-Disease-Feature-Selection.git
cd Coronary-Artery-Disease-Feature-Selection
pip install -r requirements.txt
python -m src.train # writes models/model.pkl, models/scaler.pkl, models/metrics.json
streamlit run app.pyProject structure
.
├── app.py # Streamlit app (HF Spaces entry point)
├── data/
│ └── processed_cleveland.data
├── models/
│ ├── model.pkl # Trained Logistic Regression
│ ├── scaler.pkl # StandardScaler fit on train split
│ └── metrics.json # Test-set metrics + coefficients
├── notebooks/
│ └── coronary-artery-disease-feature-selection.ipynb
├── src/
│ ├── __init__.py
│ ├── preprocess.py # Cleaning + feature selection
│ └── train.py # Reproducible training pipeline
├── .github/workflows/train.yml # CI: retrains on every push to main
├── requirements.txt
├── LICENSE
└── README.mdTech stack
- Modelling: scikit-learn (LogisticRegression, StandardScaler, traintestsplit)
- Data: pandas, numpy
- App: Streamlit
- Persistence: joblib
- Plotting (sidebar): matplotlib
- Notebook-only extras: statsmodels, mlxtend, seaborn, Graphviz (for tree visualisations)
- CI: GitHub Actions
Limitations
- Only 303 patients; ROC-AUC of 0.89 on 76 test samples carries non-trivial uncertainty.
- Single-centre, single-era data (Cleveland Clinic, late 1980s) — no guarantee of external validity for other populations or modern clinical protocols.
- The model exposes correlations, not causation.
- Class labels were binarised — severity information (originally 0–4) is discarded.
- Not validated for clinical use under any circumstances.
License
MIT. The Cleveland dataset is provided by the UCI Machine Learning Repository under their own terms.
