File size: 3,815 Bytes
fa64d6b | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 | # explainer.py
# ECG Condition Classifier - Clinical Explanation Generator
CONDITION_MAP = {
"NORM": {
"summary": "Normal Sinus Rhythm",
"urgency": "Routine",
"description": "The ECG shows a normal sinus rhythm with regular rate and rhythm, normal P waves, QRS complexes, and T waves. No significant ST changes or conduction abnormalities detected.",
"recommendation": "No immediate cardiac intervention required. Continue routine follow-up as clinically indicated.",
},
"AFIB": {
"summary": "Atrial Fibrillation",
"urgency": "Elevated",
"description": "The ECG pattern is consistent with Atrial Fibrillation. Characteristic findings include an irregularly irregular rhythm, absence of distinct P waves, and variable R-R intervals. AFib is associated with increased risk of stroke and heart failure.",
"recommendation": "Clinical evaluation recommended. Rate/rhythm management and stroke risk assessment advised.",
},
"MI": {
"summary": "Myocardial Infarction",
"urgency": "URGENT",
"description": "The ECG pattern is consistent with Myocardial Infarction. Findings may include ST-segment elevation or depression and pathological Q waves suggesting myocardial injury or ischemia.",
"recommendation": "⚠️ IMMEDIATE clinical review strongly recommended. Activate emergency cardiac protocols if STEMI suspected.",
},
"STTC": {
"summary": "ST/T-Wave Change",
"urgency": "Moderate",
"description": "Non-specific ST-segment and/or T-wave changes detected. These findings can represent myocardial ischemia, electrolyte abnormalities, medication effects, or normal variants. Clinical context is essential for interpretation.",
"recommendation": "Clinical correlation advised. Serial ECGs and lab results may be warranted.",
},
"CD": {
"summary": "Conduction Disturbance",
"urgency": "Moderate",
"description": "The ECG shows features consistent with a conduction disturbance, such as bundle branch block or AV conduction delay. These findings alter the normal electrical pathway through the ventricles.",
"recommendation": "Cardiology consultation recommended to evaluate hemodynamic significance and underlying etiology.",
},
}
DISCLAIMER = "⚠️ DISCLAIMER: For educational and research purposes only. Does not constitute medical advice. Always consult a qualified healthcare provider."
def match_condition(label):
label_upper = (label or "").upper()
for key, val in CONDITION_MAP.items():
if key in label_upper:
return {**val, "key": key}
return {
"key": "UNKNOWN",
"summary": "Unrecognized Pattern",
"urgency": "Unknown",
"description": "The model returned a label that could not be mapped to a known cardiac condition. This may indicate an unusual ECG pattern or a label category outside the standard NORM/AFIB/MI/STTC/CD set.",
"recommendation": "Manual review by a qualified cardiologist is recommended.",
}
def generate_explanation(label, confidence):
condition = match_condition(label)
urgency = condition["urgency"]
text = (
f"Condition: {condition['summary']}\n"
f"Raw Model Label: {label}\n"
f"Confidence: {confidence:.1f}%\n"
f"Urgency: {urgency}\n\n"
f"{condition['description']}\n\n"
f"Recommendation: {condition['recommendation']}\n\n"
f"{DISCLAIMER}"
)
return text, urgency
def format_top3(results):
lines = ["Top Predictions:"]
for i, r in enumerate(results[:3], 1):
score = r["score"] * 100
bar = "█" * int(score / 5)
lines.append(f" {i}. {r['label']}: {score:.1f}% {bar}")
return "\n".join(lines)
|