Catalog PyPI
Back to packageRELEASE DETAILS

0.1.2

PyPI

acs-triage-ai

Gradient boosting decision support model for four-class acute coronary syndrome triage (preliminary research tool)

acuteboostingcardiologyclinicalcoronarydecisiongradientlearningmachinesupportsyndrometriage
Published15 Jul 2026
Direct dependencies7
Transitive dependenciesNot calculated

README

Version 0.1.2 documentation

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:

MetricValue
Accuracy0.937
Macro F10.936
ClassPrecisionRecallF1
NonACS0.920.910.92
UAP0.900.920.91
NSTEMI0.950.970.96
STEMI0.970.950.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.

Downloads & popularity

Awaiting observations

No metric observations yet

Download counts and popularity will appear here as the collector receives them.

Declared dependencies 7

Native requirements
7 direct targetsNot calculated transitive count
Package / targetRequirementRelationship
pandas
Environment
{
  "extras": "",
  "marker": null,
  "requires_python": ">=3.9",
  "evaluation": "NOT_EVALUATED"
}
pandas>=1.5runtime
numpy
Environment
{
  "extras": "",
  "marker": null,
  "requires_python": ">=3.9",
  "evaluation": "NOT_EVALUATED"
}
numpy>=1.23runtime
scikit-learn
Environment
{
  "extras": "",
  "marker": null,
  "requires_python": ">=3.9",
  "evaluation": "NOT_EVALUATED"
}
scikit-learn<1.10,>=1.9runtime
joblib
Environment
{
  "extras": "",
  "marker": null,
  "requires_python": ">=3.9",
  "evaluation": "NOT_EVALUATED"
}
joblib>=1.2runtime
pytest
Environment
{
  "extras": "",
  "marker": "extra == \"dev\"",
  "requires_python": ">=3.9",
  "evaluation": "NOT_EVALUATED"
}
pytest>=7.0; extra == "dev"runtime
build
Environment
{
  "extras": "",
  "marker": "extra == \"dev\"",
  "requires_python": ">=3.9",
  "evaluation": "NOT_EVALUATED"
}
build; extra == "dev"runtime
twine
Environment
{
  "extras": "",
  "marker": "extra == \"dev\"",
  "requires_python": ">=3.9",
  "evaluation": "NOT_EVALUATED"
}
twine; extra == "dev"runtime

Distribution files

2 collected
acs_triage_ai-0.1.2-py3-none-any.whl

bdist_wheel · 457.18 KB · Python py3

Source file
acs_triage_ai-0.1.2.tar.gz

sdist · 449.74 KB · Python source

Source file

Repository

PENDING
your-username/acs-triage-ai

Shared repository data · GitHub

License detected in repository
Not collected

Metadata history

Meaningful changes
Current collected state Current

Observed since 20 Oct, 18:28 UTC

No superseded metadata states collected. Unchanged observations do not create new revisions.

Record identity

package_version:f593eb30117301652ec26f677279747278eb3368e9df2f87fdc8e7fe0ba435fc

Other collected versions

View all collected versions →