Skip to main content

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. ACSTriageModel wraps a scikit-learn Pipeline. Replace the GradientBoostingClassifier in model.py with 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.py and model.py both read from that single list, so there is only one place to update.
  • Different institutions, different formats. load_raw_csv assumes the RSCM export format (semicolon delimiter, comma decimal, title row). If your data comes from a different export, load it with plain pandas.read_csv yourself and pass the resulting DataFrame straight into prepare_features or prepare_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 y you pass into .fit(), not a change to the package internals.

Authors and credits

This package accompanies the manuscript:

A Four-Class Machine Learning Framework for Emergency Department Differentiation of Acute Chest Pain in a Resource-Constrained Setting

  • Lies Dina Liastuti¹ ² † — corresponding author
  • Averina Geffanie Suwana¹ †
  • Muhammad Allam Rafi¹ — package maintainer
  • Adyatma Wijaksara Aryaputra Nugraha Yudha³
  • Muhammad Hannan Hunafa³
  • Wisnu Jatmiko³

¹ Faculty of Medicine, Universitas Indonesia, Jakarta, Indonesia ² Department of Cardiovascular Medicine, Cipto Mangunkusumo National Referral Hospital, Jakarta, Indonesia ³ Faculty of Computer Science, Universitas Indonesia, Jakarta, Indonesia

† These authors contributed equally to this work and share co-first authorship.

Corresponding author: Lies Dina Liastuti, MD, PhD; Department of Cardiovascular Medicine, Cipto Mangunkusumo National Referral Hospital, Jl. Diponegoro No. 71, Jakarta 10430, Indonesia. Email: lies.dina11@ui.ac.id

Citation

Liastuti LD*, Suwana AG*, Rafi MA, Yudha AWAN, Hunafa MH, Jatmiko W.
A Four-Class Machine Learning Framework for Emergency Department Differentiation
of Acute Chest Pain in a Resource-Constrained Setting. [Journal/Conference, year — pending].
*These authors contributed equally and share co-first authorship.

Preliminary decision support model for acute coronary syndrome triage,
developed and validated on a single-center cohort (RSUPN Dr. Cipto Mangunkusumo, 2024).

Update the journal, volume, and page numbers once the manuscript is accepted.

Publishing this package to PyPI

  1. 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.
  2. 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 ~/.pypirc or as an environment variable. Never commit it or paste it into a conversation.
  3. Build the distribution:
    pip install build twine
    python -m build
    
  4. Upload:
    twine upload dist/*
    
    or, for a test run first:
    twine upload --repository testpypi dist/*
    
  5. Confirm the package name acs-triage-ai is 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 in pyproject.toml if it is taken.

License

MIT. See LICENSE.

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

acs_triage_ai-0.1.2.tar.gz (460.5 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

acs_triage_ai-0.1.2-py3-none-any.whl (468.2 kB view details)

Uploaded Python 3

File details

Details for the file acs_triage_ai-0.1.2.tar.gz.

File metadata

  • Download URL: acs_triage_ai-0.1.2.tar.gz
  • Upload date:
  • Size: 460.5 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.12.10

File hashes

Hashes for acs_triage_ai-0.1.2.tar.gz
Algorithm Hash digest
SHA256 f8b7524b98477e75ae9c2d6f41c55dfc538391a43a075cd6b4e04be7582a0f3c
MD5 7f3a1cea0b6804498f9ea1c977514e5f
BLAKE2b-256 51e08ea0234aca0a712808ec45679c43803f87bacaf72e16b1820c1f4b57eb31

See more details on using hashes here.

File details

Details for the file acs_triage_ai-0.1.2-py3-none-any.whl.

File metadata

  • Download URL: acs_triage_ai-0.1.2-py3-none-any.whl
  • Upload date:
  • Size: 468.2 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.12.10

File hashes

Hashes for acs_triage_ai-0.1.2-py3-none-any.whl
Algorithm Hash digest
SHA256 592b657f9720bcb933f6f1759ec85106daad5ffdd08da385e879aa6c20742b8f
MD5 9cdef9f5aa6cca9287ba436711f423ed
BLAKE2b-256 b681770e6425732de5c3674d1af922317251971a88199d9427eb990c11fca5b0

See more details on using hashes here.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page