Metadata-Version: 2.4
Name: health-core
Version: 0.1.0
Summary: Công cụ ML cho hệ thống sàng lọc nguy cơ sức khỏe: hiệu chuẩn xác suất, phát hiện ca ngoài phân phối, trích đặc trưng âm thanh, vòng lặp phản hồi chuyên gia.
Project-URL: Homepage, https://github.com/dungaka/health-core
Project-URL: Repository, https://github.com/dungaka/health-core
Project-URL: Issues, https://github.com/dungaka/health-core/issues
Author-email: Nguyễn Hải Dũng <dungaka@gmail.com>
License: MIT License
        
        Copyright (c) 2026 Nguyễn Hải Dũng
        
        Permission is hereby granted, free of charge, to any person obtaining a copy
        of this software and associated documentation files (the "Software"), to deal
        in the Software without restriction, including without limitation the rights
        to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
        copies of the Software, and to permit persons to whom the Software is
        furnished to do so, subject to the following conditions:
        
        The above copyright notice and this permission notice shall be included in all
        copies or substantial portions of the Software.
        
        THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
        IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
        FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
        AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
        LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
        OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
        SOFTWARE.
        
        ---
        
        MEDICAL DISCLAIMER / TUYEN BO MIEN TRU Y TE
        
        This software is a research prototype. It is NOT a medical device, does NOT
        provide a diagnosis, and MUST NOT be used to make clinical decisions about
        real patients. Any deployment in a healthcare setting requires appropriate
        regulatory approval and physician oversight.
        
        Phan mem nay la ban mau nghien cuu. Day KHONG phai thiet bi y te, KHONG dua ra
        chan doan, va KHONG duoc dung de ra quyet dinh lam sang tren benh nhan that.
License-File: LICENSE
Keywords: calibration,clinical-decision-support,cost-sensitive-learning,medical-ai,out-of-distribution,risk-screening
Classifier: Development Status :: 3 - Alpha
Classifier: Intended Audience :: Science/Research
Classifier: License :: OSI Approved :: MIT License
Classifier: Natural Language :: Vietnamese
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 :: Artificial Intelligence
Classifier: Topic :: Scientific/Engineering :: Medical Science Apps.
Requires-Python: >=3.9
Requires-Dist: joblib>=1.2
Requires-Dist: numpy>=1.23
Requires-Dist: pandas>=1.5
Requires-Dist: scikit-learn>=1.3
Requires-Dist: scipy>=1.10
Provides-Extra: all
Requires-Dist: librosa>=0.10; extra == 'all'
Requires-Dist: matplotlib>=3.6; extra == 'all'
Requires-Dist: soundfile>=0.12; extra == 'all'
Provides-Extra: audio
Requires-Dist: librosa>=0.10; extra == 'audio'
Requires-Dist: soundfile>=0.12; extra == 'audio'
Provides-Extra: dev
Requires-Dist: build>=1.0; extra == 'dev'
Requires-Dist: pytest>=7.0; extra == 'dev'
Requires-Dist: twine>=4.0; extra == 'dev'
Provides-Extra: plot
Requires-Dist: matplotlib>=3.6; extra == 'plot'
Description-Content-Type: text/markdown

# health-core

Công cụ ML cho các hệ thống **sàng lọc nguy cơ sức khỏe** — thư viện gom những phần kỹ thuật mà hệ thống hỗ trợ ra quyết định lâm sàng nào cũng cần, nhưng ít ai làm đúng:

- Xác suất đầu ra có phản ánh đúng tần suất thực tế không? → **calibration**
- Mô hình có biết khi nào nó gặp ca chưa từng học không? → **OOD detection**
- Đánh giá theo chỉ số nào, khi accuracy gây hiểu lầm? → **evaluation**
- Làm sao để mô hình học được từ ý kiến chuyên gia? → **feedback loop**

Thư viện không gắn với một nhóm bệnh cụ thể nào. Nó làm việc với dữ liệu dạng bảng (triệu chứng, dấu hiệu sinh tồn, kết quả đo) và nhãn nguy cơ 3 mức: Thấp / Trung bình / Cao.

> ⚠️ **Không phải thiết bị y tế.** Đây là công cụ phục vụ nghiên cứu. Nó không chẩn đoán, không kê đơn, và không thay thế bác sĩ. Không dùng để ra quyết định lâm sàng trên bệnh nhân thật.

## Cài đặt

```bash
pip install health-core                # phần lõi
pip install health-core[audio]         # + xử lý âm thanh (librosa)
pip install health-core[plot]          # + vẽ reliability diagram (matplotlib)
pip install health-core[all]           # tất cả
```

Yêu cầu Python 3.9 trở lên.

## Dùng nhanh

```python
from health_core import RiskScreeningModel

model = RiskScreeningModel(feature_names=["age", "spo2", "dyspnea", ...])
model.train(X_train, y_train)

ket_qua = model.predict({"age": 78, "spo2": 91, "dyspnea": 1, ...})

print(ket_qua.risk_label)     # "Cao"
print(ket_qua.confidence)     # 0.87  — xác suất ĐÃ hiệu chuẩn
print(ket_qua.should_trust)   # False nếu là ca lạ (ngoài phân phối training)
print(ket_qua.top_features)   # (("spo2", 0.31), ("dyspnea", 0.22), ...)
```

Lưu và nạp lại:

```python
model.save("mo_hinh.joblib")
model = RiskScreeningModel.load("mo_hinh.joblib")
```

`RiskScreeningModel` mặc định dùng Random Forest cost-sensitive `{Thấp: 1, Trung bình: 3, Cao: 10}`, hiệu chuẩn bằng Platt scaling trên tập validation tách riêng, và gắn sẵn bộ phát hiện ca lạ.

## Các tính năng

### 1. Hiệu chuẩn xác suất (`health_core.calibration`)

Mô hình nói "nguy cơ 80%" thì trong 100 ca tương tự phải có khoảng 80 ca thật sự nguy cơ cao. Nếu chỉ 55 ca, mô hình đang **tự tin quá mức** — rất nguy hiểm trong y khoa.

```python
from health_core import expected_calibration_error, pick_best_calibration

ece = expected_calibration_error(y_true, y_prob)      # thường lấy mốc <= 0.05

# Thử cả Platt scaling và Isotonic, chọn cái ECE thấp hơn
ket_qua = pick_best_calibration(rf, X_train, y_train, X_val, y_val)
print(ket_qua["best_method"], ket_qua["ece_sigmoid"], ket_qua["ece_isotonic"])
```

Có sẵn: `expected_calibration_error`, `maximum_calibration_error`, `brier`, `calibration_report`, `reliability_curve`, `plot_reliability_diagram`, `fit_calibrated`, `pick_best_calibration`.

### 2. Phát hiện ca ngoài phân phối (`health_core.ood`)

Kết hợp **Isolation Forest** (bắt outlier "điểm") và **khoảng cách Mahalanobis** (bắt outlier "cấu trúc" — từng giá trị bình thường nhưng tổ hợp vô lý). Chỉ báo động khi **cả hai** cùng đồng ý, để giảm báo động giả.

```python
from health_core import OODDetector

det = OODDetector().fit(X_train)
kq = det.check(ca_moi)
if kq.is_ood:
    print(kq.message)   # "...KHÔNG nên tin kết quả AI. Khuyến cáo chuyển tuyến ngay."

print(det.ood_rate(X_test))   # tỉ lệ ca lạ trên tập test
```

Dùng pseudo-inverse nên không vỡ khi dữ liệu có đặc trưng hằng số hoặc hai cột tương quan hoàn toàn.

### 3. Trích đặc trưng âm thanh (`health_core.audio`)

Biến file `.wav` thành 33 đặc trưng số: MFCC (13 hệ số × mean/std), zero-crossing rate, spectral centroid/rolloff/bandwidth, RMS energy, độ dài. Thiết kế cho âm thanh hô hấp (ho, thở) nhưng dùng được với mọi loại âm thanh ngắn.

```python
from health_core import audio

dac_trung = audio.extract_features("mau_001.wav")
bang = audio.extract_features_batch(Path("data/audio").glob("*.wav"))
```

Cần `pip install health-core[audio]`.

### 4. Vòng lặp phản hồi chuyên gia (`health_core.feedback`)

Ghi lại mỗi lần bác sĩ không đồng ý với mô hình (kèm lý do chuyên môn), rồi retrain với trọng số cao hơn để kiến thức chuyên môn không bị "loãng" giữa hàng nghìn mẫu nền.

```python
from health_core import PhysicianFeedbackLoop

loop = PhysicianFeedbackLoop("phan_hoi.json", feature_names=FEATURES)
loop.record_disagreement(
    case_input=ca,
    ai_prediction="Trung bình", ai_confidence=0.72,
    physician_label="Cao",
    physician_reason="Bệnh nhân có tiền sử COPD nặng chưa khai báo.",
)

if loop.should_retrain(every=30):
    model = loop.retrain(model, X_train, y_train)

print(loop.report())    # phân biệt rõ "bỏ sót" vs "báo động giả"
```

Bắt buộc phải có lý do khi ghi bất đồng — một nhãn không kèm lý do thì không dùng được để cải thiện gì cả. File ghi kiểu atomic nên mất điện giữa chừng không làm hỏng lịch sử.

### 5. Đánh giá theo chuẩn AI y tế (`health_core.evaluation`)

Accuracy là chỉ số gây hiểu lầm nhất trong y khoa: một mô hình luôn nói "Thấp" trên tập có 50% ca thấp vẫn đạt accuracy 50%, trong khi bỏ sót 100% ca nguy hiểm. Module này sắp xếp chỉ số theo đúng thứ tự ưu tiên — Recall nhóm nguy cơ cao → tỉ lệ bỏ sót → ECE → F1 macro → accuracy (chỉ tham khảo).

```python
from health_core import compare_models, evaluate_textbook_cases

bang = compare_models({"Rule": rule, "LR": lr, "RF": rf}, X_test, y_test)
print(bang.to_markdown(index=False))

df = evaluate_textbook_cases(model, CAC_CA_LAM_SANG, FEATURE_NAMES)
# phân loại rõ "over_alert" (an toàn hơn) vs "under_alert" (bỏ sót — nguy hiểm)
```

`evaluate_textbook_cases()` dùng để kiểm thử mô hình trên bộ ca lâm sàng do chuyên gia soạn — đây là *clinical validation*, khác với đánh giá thống kê trên tập test ngẫu nhiên.

## Triết lý thiết kế

- **Sai số bất đối xứng.** Bỏ sót một ca nặng nguy hiểm hơn nhiều so với một báo động giả. Mọi mặc định trong thư viện đều lệch về phía cẩn thận.
- **Mô hình phải biết khi nào nó không nên tin chính nó.** Gặp ca lạ thì từ chối dự đoán thay vì đoán bừa một cách tự tin.
- **Xác suất phải là xác suất thật**, không phải con số trang trí.
- **Không nói quá về khả năng giải thích.** `top_features()` ghi rõ trong docstring rằng nó là importance trung bình, không phải lý do cho từng ca.

## Phát triển

```bash
git clone https://github.com/dungaka/health-core
cd health-core
pip install -e ".[dev,all]"
pytest -q
```

## Đăng lên PyPI

```bash
pip install build twine
python -m build                       # tạo dist/*.whl và dist/*.tar.gz
python -m twine check dist/*          # kiểm tra metadata hợp lệ

# Đăng thử lên TestPyPI trước — tên gói trên PyPI thật KHÔNG xóa lại được
python -m twine upload --repository testpypi dist/*
pip install -i https://test.pypi.org/simple/ health-core   # thử cài lại

# Đăng thật
python -m twine upload dist/*
```

Cần tài khoản tại [pypi.org](https://pypi.org) và một API token (Account settings → API tokens). Khi twine hỏi, nhập `__token__` làm username và dán token làm password.

Mỗi lần đăng lại phải **tăng `version`** trong `pyproject.toml` — PyPI không cho ghi đè một phiên bản đã tồn tại.

## Tài liệu tham khảo

1. Van Calster et al. (2019). *Calibration: the Achilles heel of predictive analytics.* BMC Medicine 17:230.
2. Yang et al. (2024). *Generalized Out-of-Distribution Detection: A Survey.* IJCV.
3. Collins et al. (2024). *TRIPOD+AI statement.* BMJ.
4. Lai et al. (2023). *Human-AI Collaboration in Healthcare.* Nature Medicine 29(8).

## Giấy phép

MIT — xem [LICENSE](LICENSE), bao gồm cả tuyên bố miễn trừ trách nhiệm y tế.
