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 description
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
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
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:
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.
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ả.
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 35 đặ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.
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.
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).
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
git clone https://github.com/dungaka/health-core
cd health-core
pip install -e ".[dev,all]"
pytest -q
Đăng lên PyPI
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 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
- Van Calster et al. (2019). Calibration: the Achilles heel of predictive analytics. BMC Medicine 17:230.
- Yang et al. (2024). Generalized Out-of-Distribution Detection: A Survey. IJCV.
- Collins et al. (2024). TRIPOD+AI statement. BMJ.
- Lai et al. (2023). Human-AI Collaboration in Healthcare. Nature Medicine 29(8).
Giấy phép
MIT — xem LICENSE, bao gồm cả tuyên bố miễn trừ trách nhiệm y tế.
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 health_core-0.1.1.tar.gz.
File metadata
- Download URL: health_core-0.1.1.tar.gz
- Upload date:
- Size: 32.6 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.12.0
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
a722913e88534c1a4ea6d60e8e296f2f33ef4b4353d240ef0d110c08064d4edc
|
|
| MD5 |
1c9e021f7275c6c8c1c37c09084f14b3
|
|
| BLAKE2b-256 |
57acd526c46a92091b88ccfc59e2ead2259e17e7d1804a220ce17225c30743d1
|
File details
Details for the file health_core-0.1.1-py3-none-any.whl.
File metadata
- Download URL: health_core-0.1.1-py3-none-any.whl
- Upload date:
- Size: 35.1 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.12.0
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
d64e6c33817b7acfbb05459a544472a37811cd9be23e9fc0407ad2002b0455eb
|
|
| MD5 |
a56641387cf8f92e7dc36f2904dad517
|
|
| BLAKE2b-256 |
3300cbe48d1eeb25bdd1cd973a11b62623cd82045b330030bee93164918cd95b
|