Spaces:
Sleeping
Sleeping
Update app.py
Browse files
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 |
|