Dina-Raslan commited on
Commit
a2a3a9e
Β·
verified Β·
1 Parent(s): a2637a2

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +29 -6
app.py CHANGED
@@ -21,6 +21,7 @@ from sklearn.preprocessing import LabelEncoder
21
  from sklearn.impute import SimpleImputer
22
  from huggingface_hub import hf_hub_download
23
  import joblib
 
24
 
25
  # ── Device ────────────────────────────────────────────────────────────────────
26
  device = torch.device("cpu")
@@ -143,6 +144,10 @@ gb_path = hf_hub_download(repo_id=REPO_ID, filename="gb_clinical_model_joblib.pk
143
  gb_model = joblib.load(gb_path)
144
  print("GB clinical model loaded")
145
 
 
 
 
 
146
  print("All models ready.")
147
 
148
  # ΨͺΨ­Ω‚Ω‚ Ω…Ω† Ψ§Ψ³Ω…Ψ§Ψ‘ Ψ§Ω„Ψ£ΨΉΩ…Ψ―Ψ© في Ψ§Ω„Ω€ scaler
@@ -243,6 +248,24 @@ def prepare_clinical_features(
243
  scaled = clinical_scaler.transform(X)
244
  return scaled
245
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
246
  # ── Grad-CAM++ ────────────────────────────────────────────────────────────────
247
  class GradCAMPlusPlus:
248
  def __init__(self, model, target_layer):
@@ -478,6 +501,9 @@ def predict_ckd_risk(
478
  # 5. GB clinical prediction
479
  clinical_prob = gb_model.predict_proba(clinical_feat)[0, 1]
480
 
 
 
 
481
  # 6. Fusion model prediction
482
  retinal_tensor = torch.tensor(retinal_feat_pca, dtype=torch.float32)
483
  clinical_tensor = torch.tensor(clinical_feat, dtype=torch.float32)
@@ -542,7 +568,6 @@ def predict_ckd_risk(
542
  WBC Count (wbcc): {wbcc} cells/cumm
543
  RBC Count (rbcc): {rbcc} millions/cumm
544
  Blood Pressure (bp): {bp} mmHg
545
-
546
  URINE TESTS
547
  Specific Gravity (sg):{sg}
548
  Albumin (al): {al}
@@ -551,7 +576,6 @@ def predict_ckd_risk(
551
  Pus Cells (pc): {pc}
552
  Pus Cell Clumps (pcc):{pcc}
553
  Bacteria (ba): {ba}
554
-
555
  PATIENT INFO
556
  Age: {age} years
557
  Hypertension (htn): {htn}
@@ -566,6 +590,9 @@ def predict_ckd_risk(
566
  Clinical Score: {clinical_prob:.4f}
567
  Fusion Score: {fusion_prob:.4f}
568
  Risk Level: {risk_label}
 
 
 
569
  β•šβ•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•
570
  """
571
 
@@ -723,9 +750,7 @@ with gr.Blocks(title="CKD-MultiVision") as demo:
723
  with gr.TabItem("About"):
724
  gr.Markdown("""
725
  ## About CKD-MultiVision
726
-
727
  **Input Fields (24 total β€” matching UCI CKD Dataset):**
728
-
729
  | # | Field | Source | Description |
730
  |---|-------|--------|-------------|
731
  | 1 | age | Manual | Patient age in years |
@@ -752,12 +777,10 @@ with gr.Blocks(title="CKD-MultiVision") as demo:
752
  | 22 | appet | Manual | Appetite |
753
  | 23 | pe | Manual | Pedal edema |
754
  | 24 | ane | Manual | Anemia |
755
-
756
  **Pipeline:**
757
  - Retinal Image β†’ EfficientNet-B3 β†’ Feature Vector (1536) β†’ PCA (64 dim)
758
  - Clinical Values (24) β†’ StandardScaler β†’ Gradient Boosting + Fusion Model
759
  - Cross-Modal Attention Fusion β†’ Final Risk Level
760
-
761
  *Research prototype β€” not for clinical use.*
762
  """)
763
 
 
21
  from sklearn.impute import SimpleImputer
22
  from huggingface_hub import hf_hub_download
23
  import joblib
24
+ import shap
25
 
26
  # ── Device ────────────────────────────────────────────────────────────────────
27
  device = torch.device("cpu")
 
144
  gb_model = joblib.load(gb_path)
145
  print("GB clinical model loaded")
146
 
147
+ # SHAP explainer for the clinical model (created once, reused for every request)
148
+ shap_explainer = shap.TreeExplainer(gb_model)
149
+ print("SHAP explainer ready")
150
+
151
  print("All models ready.")
152
 
153
  # ΨͺΨ­Ω‚Ω‚ Ω…Ω† Ψ§Ψ³Ω…Ψ§Ψ‘ Ψ§Ω„Ψ£ΨΉΩ…Ψ―Ψ© في Ψ§Ω„Ω€ scaler
 
248
  scaled = clinical_scaler.transform(X)
249
  return scaled
250
 
251
+ def get_top_shap_features(clinical_feat, top_n=6):
252
+ """
253
+ Compute SHAP values for the clinical (GB) model's prediction and
254
+ return the top_n features ranked by absolute impact.
255
+ clinical_feat must be the scaled numpy array in ALL_COLS order.
256
+ Returns a list of (feature_name, shap_value) tuples.
257
+ """
258
+ shap_values = shap_explainer.shap_values(clinical_feat)
259
+
260
+ # Some SHAP/model versions return a list per class, others a single array
261
+ if isinstance(shap_values, list):
262
+ shap_row = shap_values[1][0] # class "CKD" (positive class)
263
+ else:
264
+ shap_row = shap_values[0]
265
+
266
+ top_idx = np.argsort(np.abs(shap_row))[::-1][:top_n]
267
+ return [(ALL_COLS[i], float(shap_row[i])) for i in top_idx]
268
+
269
  # ── Grad-CAM++ ────────────────────────────────────────────────────────────────
270
  class GradCAMPlusPlus:
271
  def __init__(self, model, target_layer):
 
501
  # 5. GB clinical prediction
502
  clinical_prob = gb_model.predict_proba(clinical_feat)[0, 1]
503
 
504
+ # 5.b Top-6 SHAP features driving the clinical prediction
505
+ top_shap_features = get_top_shap_features(clinical_feat, top_n=6)
506
+
507
  # 6. Fusion model prediction
508
  retinal_tensor = torch.tensor(retinal_feat_pca, dtype=torch.float32)
509
  clinical_tensor = torch.tensor(clinical_feat, dtype=torch.float32)
 
568
  WBC Count (wbcc): {wbcc} cells/cumm
569
  RBC Count (rbcc): {rbcc} millions/cumm
570
  Blood Pressure (bp): {bp} mmHg
 
571
  URINE TESTS
572
  Specific Gravity (sg):{sg}
573
  Albumin (al): {al}
 
576
  Pus Cells (pc): {pc}
577
  Pus Cell Clumps (pcc):{pcc}
578
  Bacteria (ba): {ba}
 
579
  PATIENT INFO
580
  Age: {age} years
581
  Hypertension (htn): {htn}
 
590
  Clinical Score: {clinical_prob:.4f}
591
  Fusion Score: {fusion_prob:.4f}
592
  Risk Level: {risk_label}
593
+ ╠══════════════════════════════════════╣
594
+ TOP 6 CLINICAL FEATURES (SHAP)
595
+ {chr(10).join(f" {i+1}. {name:<8s} {'+' if val >= 0 else ''}{val:.4f}" for i, (name, val) in enumerate(top_shap_features))}
596
  β•šβ•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•
597
  """
598
 
 
750
  with gr.TabItem("About"):
751
  gr.Markdown("""
752
  ## About CKD-MultiVision
 
753
  **Input Fields (24 total β€” matching UCI CKD Dataset):**
 
754
  | # | Field | Source | Description |
755
  |---|-------|--------|-------------|
756
  | 1 | age | Manual | Patient age in years |
 
777
  | 22 | appet | Manual | Appetite |
778
  | 23 | pe | Manual | Pedal edema |
779
  | 24 | ane | Manual | Anemia |
 
780
  **Pipeline:**
781
  - Retinal Image β†’ EfficientNet-B3 β†’ Feature Vector (1536) β†’ PCA (64 dim)
782
  - Clinical Values (24) β†’ StandardScaler β†’ Gradient Boosting + Fusion Model
783
  - Cross-Modal Attention Fusion β†’ Final Risk Level
 
784
  *Research prototype β€” not for clinical use.*
785
  """)
786