Gradient boosting decision support model for four-class acute coronary syndrome triage (preliminary research tool)
Project description
acs-triage-ai
A gradient boosting decision support package for four-class triage of suspected acute coronary syndrome: NonACS, UAP (unstable angina), NSTEMI, and STEMI.
Built from a de-identified clinical dataset collected at RSUPN Dr. Cipto Mangunkusumo (RSCM), Jakarta, 2024 (n = 8,296 patients). Given a patient's demographics, vital signs, history, presenting symptoms, ECG findings, laboratory results, and standard risk scores (TIMI, GRACE, HEART), the model returns a probability distribution across the four diagnostic categories.
Status and intended use
This is a preliminary research tool and clinical decision support system. It is not a certified or regulatory-approved diagnostic device.
- It is meant to support, not replace, clinical judgment and standard diagnostic workup.
- Predictions should be reviewed by a qualified clinician alongside the full clinical picture.
- Performance figures below come from a single-center dataset and a held-out internal test split. They have not been validated on an external cohort, so they describe how the model performs on data similar to what it was trained on, not a general guarantee.
- This package accompanies an ongoing manuscript describing the model's development and validation. Cite the manuscript (see Citation below) when using this package in academic work.
What's in the box
acs_triage_ai/
├── schema.py # the exact clinical fields the model expects
├── preprocessing.py # CSV loading and feature preparation
├── model.py # ACSTriageModel: fit, predict, save, load
├── interpret.py # turns probabilities into a readable triage flag
├── train.py # command-line training script
└── predict.py # command-line scoring script
The design goal is that each piece works on its own. You can use ACSTriageModel directly in your own pipeline, or run train.py / predict.py from the command line without writing any code.
Installation
Once published:
pip install acs-triage-ai
For local development, from the project root:
pip install -e ".[dev]"
Quick start
from acs_triage_ai import ACSTriageModel, load_raw_csv, prepare_training_data
# Load a raw clinical CSV export (semicolon-delimited, comma-decimal,
# with a title row, matching the RSCM export format)
df = load_raw_csv("Dataset_SKA_RSCM_2024.csv")
X, y = prepare_training_data(df)
model = ACSTriageModel()
report = model.fit(X, y)
print(report.summary())
model.save("acs_triage_model.joblib")
Scoring new patients:
from acs_triage_ai import ACSTriageModel, prepare_features
from acs_triage_ai.interpret import interpret_batch
model = ACSTriageModel.load("acs_triage_model.joblib")
X_new = prepare_features(new_patients_df)
probabilities = model.predict_proba(X_new)
for result in interpret_batch(probabilities):
print(result)
Example output for a single patient:
Predicted class: NSTEMI
Class probabilities: NSTEMI: 99.4%, NonACS: 0.1%, STEMI: 0.3%, UAP: 0.2%
High-risk (NSTEMI/STEMI) probability: 99.6%
Flag: HIGH ATTENTION: strong model signal toward NSTEMI/STEMI. Recommend urgent clinical correlation.
Command line
# Train a model from a CSV file
acs-triage-train --data Dataset_SKA_RSCM_2024.csv --output model.joblib
# Score new patients
acs-triage-predict --model model.joblib --data new_patients.csv --output predictions.csv
Input schema
The model expects 70 clinical fields across seven groups: demographics, vitals, history, symptoms, ECG findings, labs, and risk scores. Run python -c "from acs_triage_ai import describe_schema; print(describe_schema())" to print the full breakdown, or read schema.py directly, which is the single source of truth for field names.
If your input data is missing a required column, prepare_features raises a ValueError naming exactly which column is missing, rather than failing silently or filling in a guess.
Verified performance (internal held-out split)
Trained on the full RSCM 2024 cohort (n = 8,296), stratified 80/20 split, 300-estimator gradient boosting classifier:
| Metric | Value |
|---|---|
| Accuracy | 0.937 |
| Macro F1 | 0.936 |
| Class | Precision | Recall | F1 |
|---|---|---|---|
| NonACS | 0.92 | 0.91 | 0.92 |
| UAP | 0.90 | 0.92 | 0.91 |
| NSTEMI | 0.95 | 0.97 | 0.96 |
| STEMI | 0.97 | 0.95 | 0.96 |
Top predictive features by importance: initial troponin T, ECG ST-elevation, HEART score, serial troponin T, TIMI score. This ranking is clinically consistent with how ACS is worked up in practice, which is a useful sanity check on the model, not just a numbers exercise.
These numbers come from one train/test split on one dataset. Re-run train.py on your own data or a different split to check stability before relying on them.
A note on scikit-learn versions
The bundled pretrained model is a serialized scikit-learn pipeline, and scikit-learn's pickle format is not always compatible across versions. This package pins scikit-learn>=1.9,<1.10 for that reason. If you retrain your own model with a different scikit-learn version and plan to distribute the resulting .joblib file, pin your dependency to match, or you will get a ModuleNotFoundError or InconsistentVersionWarning on someone else's machine, confirmed during testing of this package.
Extending the package
- Swap the algorithm.
ACSTriageModelwraps a scikit-learnPipeline. Replace theGradientBoostingClassifierinmodel.pywith any other scikit-learn-compatible classifier without touching the rest of the package. - Add features. Add new field names to the appropriate group in
schema.py.preprocessing.pyandmodel.pyboth read from that single list, so there is only one place to update. - Different institutions, different formats.
load_raw_csvassumes the RSCM export format (semicolon delimiter, comma decimal, title row). If your data comes from a different export, load it with plainpandas.read_csvyourself and pass the resulting DataFrame straight intoprepare_featuresorprepare_training_data. - New target granularity. If you want to collapse to a binary ACS vs. NonACS problem, or split STEMI by territory, that is a change to the
yyou pass into.fit(), not a change to the package internals.
Authors and credits
- Muhammad Allam Rafi — Faculty of Medicine, Universitas Indonesia / RSUPN Dr. Cipto Mangunkusumo (FKUI-RSCM). Project lead, model development.
A note on the author list: this README currently lists the author confirmed from this conversation. The manuscript's full author list was to be pulled from a Word document, but no such file was provided along with the dataset. Add the remaining co-authors here (and in pyproject.toml) before publishing, in the author order agreed for the manuscript.
Citation
[Author list], "[Manuscript title placeholder]," [Journal/Conference, year — pending].
Preliminary decision support model for acute coronary syndrome triage,
developed and validated on a single-center cohort (RSUPN Dr. Cipto Mangunkusumo, 2024).
Replace the bracketed fields once the manuscript is finalized.
Publishing this package to PyPI
- Revoke any API token that has ever been pasted into a chat, a script, or a public place. A token that has been seen outside your own machine should be treated as compromised, full stop.
- Generate a fresh token from https://pypi.org/manage/account/token/ (or https://test.pypi.org for a test upload) and store it only in a local, private
~/.pypircor as an environment variable. Never commit it or paste it into a conversation. - Build the distribution:
pip install build twine python -m build
- Upload:
twine upload dist/*
or, for a test run first:twine upload --repository testpypi dist/*
- Confirm the package name
acs-triage-aiis actually available before your first upload. PyPI names are first-come, first-served and cannot be reused once claimed by someone else; check at https://pypi.org/project/acs-triage-ai/ and rename inpyproject.tomlif it is taken.
License
MIT. See LICENSE.
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file acs_triage_ai-0.1.1.tar.gz.
File metadata
- Download URL: acs_triage_ai-0.1.1.tar.gz
- Upload date:
- Size: 459.9 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.12.10
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
1f7251b93bc7b348c3196a059620d1f10f1c57bf6b8f7604ee2b99f6f298b3f5
|
|
| MD5 |
e6c40123fb212ebe732265e937af8ce9
|
|
| BLAKE2b-256 |
2477e15a188ca4b100d5487820f50dd37abcf914f83f2ab9263025eb52bd0ab7
|
File details
Details for the file acs_triage_ai-0.1.1-py3-none-any.whl.
File metadata
- Download URL: acs_triage_ai-0.1.1-py3-none-any.whl
- Upload date:
- Size: 467.9 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.12.10
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
62eebaf3605cb509d6f59d99708233a7ff88a05f330cee3dc8c9d360fb613536
|
|
| MD5 |
bc69e8b68b047de625d56eb35eebbeaf
|
|
| BLAKE2b-256 |
6512125bbf0435c8ba33a036fc51e104b53d5db717a6f40ec6eb76886961eb52
|