Spaces:
Sleeping
Sleeping
| """Quick eval on first 15 subjects only — for proof/demo purposes.""" | |
| import sys, warnings | |
| warnings.filterwarnings("ignore") | |
| from pathlib import Path | |
| sys.path.insert(0, str(Path(__file__).parents[1])) | |
| import numpy as np | |
| from app.services.prediction import ScreeningPredictor | |
| from app.services.image_quality import ImageQualityService | |
| from app.ml.archive_model import _build_subject_catalog, ANEMIA_HB_THRESHOLD | |
| from sklearn.metrics import ( | |
| accuracy_score, f1_score, recall_score, | |
| precision_score, roc_auc_score, mean_absolute_error, | |
| confusion_matrix | |
| ) | |
| predictor = ScreeningPredictor() | |
| quality_svc = ImageQualityService() | |
| print("Model:", predictor.archive_model.get("version")) | |
| print("Threshold:", predictor.archive_model.get("calibration", {}).get("blend_threshold")) | |
| print() | |
| subjects = _build_subject_catalog(Path(__file__).parents[2] / "archive" / "dataset anemia") | |
| print(f"Total subjects in dataset: {len(subjects)}") | |
| anemic = sum(1 for s in subjects if s["label"] == 1) | |
| normal = sum(1 for s in subjects if s["label"] == 0) | |
| print(f" Anemic (Hb < {ANEMIA_HB_THRESHOLD}): {anemic}") | |
| print(f" Normal (Hb >= {ANEMIA_HB_THRESHOLD}): {normal}") | |
| print(f" Hb range: {min(s['hb'] for s in subjects):.1f} - {max(s['hb'] for s in subjects):.1f} g/dL") | |
| print(f" Hb mean: {np.mean([s['hb'] for s in subjects]):.2f} g/dL") | |
| print(f" Hb std: {np.std([s['hb'] for s in subjects]):.2f} g/dL") | |
| print() | |
| # Quick eval on first 15 subjects | |
| results = [] | |
| blocked = 0 | |
| errors = 0 | |
| for s in subjects[:15]: | |
| country = s["subject_id"].split("-")[0] | |
| num = s["subject_number"] | |
| jpg_path = Path(__file__).parents[2] / "archive" / "dataset anemia" / country / num | |
| jpgs = list(jpg_path.glob("*.jpg")) | |
| if not jpgs: | |
| continue | |
| with open(jpgs[0], "rb") as f: | |
| img_bytes = f.read() | |
| try: | |
| quality, rgb = quality_svc.evaluate(img_bytes) | |
| if not quality.passed: | |
| blocked += 1 | |
| continue | |
| pred = predictor.predict(rgb, quality, symptom_score=0.0) | |
| results.append({ | |
| "subject": s["subject_id"], | |
| "hb_true": s["hb"], | |
| "hb_pred": pred.predicted_hemoglobin, | |
| "risk": pred.anemia_risk, | |
| "label_true": int(s["hb"] < ANEMIA_HB_THRESHOLD), | |
| "label_pred": 1 if pred.screening_label == "anemia_likely" else 0, | |
| "label": pred.screening_label, | |
| "uncertainty": pred.uncertainty, | |
| "confidence": pred.confidence, | |
| }) | |
| except Exception as e: | |
| errors += 1 | |
| print(f" Error {s['subject_id']}: {e}") | |
| print(f"Processed: {len(results)}, Blocked by quality: {blocked}, Errors: {errors}") | |
| print() | |
| if results: | |
| lt = [r["label_true"] for r in results] | |
| lp = [r["label_pred"] for r in results] | |
| risks = [r["risk"] for r in results] | |
| hb_t = [r["hb_true"] for r in results if r["hb_pred"]] | |
| hb_p = [r["hb_pred"] for r in results if r["hb_pred"]] | |
| print("=== SAMPLE METRICS (15 subjects) ===") | |
| print(f"Accuracy: {accuracy_score(lt, lp):.3f}") | |
| print(f"Recall: {recall_score(lt, lp, zero_division=0):.3f} ← most important (catch anemia)") | |
| print(f"Precision: {precision_score(lt, lp, zero_division=0):.3f}") | |
| print(f"F1: {f1_score(lt, lp, zero_division=0):.3f}") | |
| if len(set(lt)) > 1: | |
| print(f"AUC: {roc_auc_score(lt, risks):.3f}") | |
| if hb_p: | |
| print(f"Hb MAE: {mean_absolute_error(hb_t, hb_p):.2f} g/dL") | |
| cm = confusion_matrix(lt, lp) | |
| print() | |
| print("Confusion Matrix:") | |
| print(" Pred Normal Pred Anemic") | |
| if cm.shape == (2,2): | |
| print(f" True Normal {cm[0][0]:3d} {cm[0][1]:3d}") | |
| print(f" True Anemic {cm[1][0]:3d} {cm[1][1]:3d}") | |
| tn, fp, fn, tp = cm.ravel() | |
| print(f"\n True Positives (caught anemia): {tp}") | |
| print(f" False Negatives (missed anemia): {fn}") | |
| print(f" False Positives (false alarm): {fp}") | |
| print(f" True Negatives (correct clear): {tn}") | |
| print() | |
| print("=== SAMPLE PREDICTIONS ===") | |
| print(f"{'Subject':<15} {'Hb True':>8} {'Hb Pred':>8} {'Risk':>6} {'Uncert':>7} {'Label':<20} {'Correct'}") | |
| print("-" * 80) | |
| for r in results: | |
| correct = "OK" if r["label_true"] == r["label_pred"] else "WRONG" | |
| hbp = f"{r['hb_pred']:.1f}" if r["hb_pred"] else "hidden" | |
| print(f"{r['subject']:<15} {r['hb_true']:>8.1f} {hbp:>8} {r['risk']:>6.3f} {r['uncertainty']:>7.3f} {r['label']:<20} {correct}") | |