Inspiration
What it does
How we built it## Inspiration
Coronary artery disease is usually confirmed with angiography, which is invasive and expensive. Most AI risk tools give you one number and no sense of how far to trust it. In medicine that is the wrong way around: a clinician needs to know which artery is affected and how sure the model is. We wanted to build a prototype that shows per-artery risk and is honest about its own limits.
What it does
HrudayAI estimates four probabilities from a patient's clinical, ECG, lab and echo findings: overall CAD, and stenosis of the LAD, LCX and RCA arteries.
- Interactive 3D heart: each coronary artery is a separate mesh, coloured by its predicted probability.
- Test ladder: predictions at four cumulative steps (history and exam, then ECG, labs, echo), so a clinic without an echo machine still gets a validated estimate.
- Honest uncertainty: every probability has a 10th to 90th percentile range from 200 bootstrap refits, and weak models carry a "lower reliability" tag.
- Explanations: exact SHAP contributions per patient, shown on the original measurements.
How we built it
Data: the Z-Alizadeh Sani extension dataset (UCI), 303 patients and 54 usable features.
Models: for each target we compared L2 logistic regression, random forest, XGBoost and LightGBM. Tree models scored up to 0.027 higher in cross-validated ROC-AUC, but a Nadeau-Bengio corrected resampled t-test showed the gaps were within noise ($p = 0.22$ to $0.51$). We chose logistic regression for all four targets, which also gives exact SHAP values.
Calibration and thresholds: probabilities drive the colours, so they must be trustworthy. Platt scaling beat isotonic regression on Brier score for every target:
$$\text{Brier} = \frac{1}{N}\sum_{i=1}^{N}(p_i - y_i)^2$$
Decision thresholds were tuned by maximising Youden's $J = \text{sensitivity} + \text{specificity} - 1$ on out-of-fold predictions.
Validation: a 61-patient hold-out set touched only for the final report, plus 5-fold × 5-repeat stratified cross-validation on the remaining 242 patients. Preprocessing, fitting, calibration and threshold tuning are all repeated inside every fold.
Stack: a FastAPI backend serves the models and SHAP explanations, and a Next.js + React Three Fiber frontend renders the 3D heart. A single feature_schema.json drives preprocessing, API validation and the input form. We built the project with the help of Claude Code and reviewed and tested the result.
Results
| Target | CV ROC-AUC | Hold-out ROC-AUC (95% CI) |
|---|---|---|
| CAD | 0.925 ± 0.033 | 0.872 (0.77 to 0.95) |
| LAD | 0.837 ± 0.056 | 0.818 (0.70 to 0.91) |
| LCX | 0.716 ± 0.064 | 0.686 (0.54 to 0.82) |
| RCA | 0.740 ± 0.074 | 0.671 (0.52 to 0.81) |
Challenges
- Tiny dataset. With 303 patients, leakage and overfitting are easy to introduce. We never use the four label columns as inputs, enforce that in one place, and test it by scrambling those columns and confirming predictions don't change.
- Weak vessel models. LCX and RCA are close to chance on the hold-out set. Rather than hide it, we tag them "lower reliability" everywhere in the app.
- A narrow range isn't a good range. The LCX range is narrow only because that model is so heavily regularised it barely moves from the base rate, so the interface never presents range width as accuracy.
- Fitting a real heart in a browser. We reduced BodyParts3D anatomy from about 590,000 to about 75,000 triangles and compressed it to 351 KB, with one named mesh per artery so predictions map to anatomy by name.
- Colour that is readable by everyone. We used a single-hue lightness scale checked for colour-vision deficiency and always show the probability as text.
What we learned
- Our assumption that more tests give better estimates was wrong. History and examination carry most of the signal, and only one step change out of twelve (echo for LAD, $p = 0.01$) was distinguishable from noise. Labs added nothing measurable. We show this finding in the app.
- A simpler model that is statistically tied with a complex one is usually the better choice, especially when you need exact explanations.
- Reporting weak results honestly makes a medical AI demo more credible, not less.
Limitations and what's next
HrudayAI is a decision-support and educational prototype, not a diagnostic device. The data is single-centre, probably from Iran, so performance on other populations (including India) is unknown. Everyone in the dataset was already referred for angiography, so it is not a tool for acute chest pain or general-population screening. Next steps are external validation, a subgroup audit by sex and age, and clinical review.
Challenges we ran into
Accomplishments that we're proud of
What we learned
What's next for HrudayAi
Built With
- bodyparts3d
- fastapi
- gltf
- joblib
- lightgbm
- next.js
- pydantic
- python
- react
- react-three-fiber
- recharts
- scikit-learn
- shadcn-ui
- shap
- tailwind-css
- three.js
- typescript
- uv
- xgboost
Log in or sign up for Devpost to join the conversation.