Metadata-Version: 2.4
Name: acs-triage-ai
Version: 0.1.1
Summary: Gradient boosting decision support model for four-class acute coronary syndrome triage (preliminary research tool)
Author-email: Muhammad Allam Rafi <your-email@example.com>
License-Expression: MIT
Project-URL: Homepage, https://github.com/your-username/acs-triage-ai
Project-URL: Repository, https://github.com/your-username/acs-triage-ai
Project-URL: Issues, https://github.com/your-username/acs-triage-ai/issues
Keywords: acute coronary syndrome,clinical decision support,machine learning,cardiology,triage,gradient boosting
Classifier: Development Status :: 3 - Alpha
Classifier: Intended Audience :: Healthcare Industry
Classifier: Intended Audience :: Science/Research
Classifier: Programming Language :: Python :: 3
Classifier: Programming Language :: Python :: 3.9
Classifier: Programming Language :: Python :: 3.10
Classifier: Programming Language :: Python :: 3.11
Classifier: Programming Language :: Python :: 3.12
Classifier: Topic :: Scientific/Engineering :: Medical Science Apps.
Classifier: Topic :: Scientific/Engineering :: Artificial Intelligence
Requires-Python: >=3.9
Description-Content-Type: text/markdown
License-File: LICENSE
Requires-Dist: pandas>=1.5
Requires-Dist: numpy>=1.23
Requires-Dist: scikit-learn<1.10,>=1.9
Requires-Dist: joblib>=1.2
Provides-Extra: dev
Requires-Dist: pytest>=7.0; extra == "dev"
Requires-Dist: build; extra == "dev"
Requires-Dist: twine; extra == "dev"
Dynamic: license-file

# 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:

```bash
pip install acs-triage-ai
```

For local development, from the project root:

```bash
pip install -e ".[dev]"
```

## Quick start

```python
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:

```python
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

```bash
# 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

- **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

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:
   ```bash
   pip install build twine
   python -m build
   ```
4. Upload:
   ```bash
   twine upload dist/*
   ```
   or, for a test run first:
   ```bash
   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`.
