File size: 8,383 Bytes
0ff826a
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
984c670
0ff826a
 
 
 
 
 
 
 
 
670abf6
 
 
 
 
 
 
 
0ff826a
670abf6
 
0ff826a
670abf6
 
0ff826a
670abf6
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
0ff826a
670abf6
 
 
 
 
 
0ff826a
 
 
 
 
 
 
 
 
 
 
 
a594887
0ff826a
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
e99824c
0ff826a
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
e99824c
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
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
import gradio as gr
import joblib
import numpy as np
import pandas as pd
import warnings
warnings.filterwarnings("ignore")
import os

# โ”€โ”€ Load model โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€
MODEL_PATH = "Random_Forest.pth"
model = joblib.load(MODEL_PATH)

# โ”€โ”€ Feature order must match training data โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€
FEATURE_ORDER = [
    "Sex", "Age", "Haemoglobin", "Hematocrit", "Lymphocytes",
    "MCH", "MCHC", "MCV", "Monocytes", "MPV", "PCT", "PDW",
    "Platelet Count", "Polymorphs", "RBC Count", "RDW SD",
    "WBC Count", "Eosinophils", "Creatinine", "Urea", "GFR "
]

# โ”€โ”€ Prediction function โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€
def predict_ckd(
    sex, age, haemoglobin, hematocrit, lymphocytes,
    mch, mchc, mcv, monocytes, mpv, pct, pdw,
    platelet_count, polymorphs, rbc_count, rdw_sd,
    wbc_count, eosinophils, creatinine, urea, gfr
):
    try:
        values = [
            sex, age, haemoglobin, hematocrit, lymphocytes,
            mch, mchc, mcv, monocytes, mpv, pct, pdw,
            platelet_count, polymorphs, rbc_count, rdw_sd,
            wbc_count, eosinophils, creatinine, urea, gfr
        ]
        features = pd.DataFrame([values], columns=FEATURE_ORDER)

        pred = model.predict(features)[0]
        proba = model.predict_proba(features)[0]

        ckd_prob    = round(float(proba[1]) * 100, 2)
        no_ckd_prob = round(float(proba[0]) * 100, 2)

        if pred == 1:
            label   = "โš ๏ธ CKD Detected"
            details = (
                f"**Prediction: Chronic Kidney Disease (CKD)**\n\n"
                f"- CKD Probability: **{ckd_prob}%**\n"
                f"- No CKD Probability: {no_ckd_prob}%\n\n"
                f"> โš ๏ธ This result suggests the presence of Chronic Kidney Disease. "
                f"Please consult a qualified nephrologist for clinical evaluation."
            )
        else:
            label   = "โœ… No CKD Detected"
            details = (
                f"**Prediction: No Chronic Kidney Disease**\n\n"
                f"- No CKD Probability: **{no_ckd_prob}%**\n"
                f"- CKD Probability: {ckd_prob}%\n\n"
                f"> โœ… Based on the provided blood parameters, no CKD pattern was detected. "
                f"Regular health check-ups are still recommended."
            )

        return label, details

    except Exception as e:
        import traceback
        err = traceback.format_exc()
        return "โŒ Prediction Error", f"```\n{err}\n```"

# โ”€โ”€ UI โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€
DESCRIPTION = """
## Chronic Kidney Disease (CKD) Prediction System
**Research Project โ€” PAF-IAST, HEC-Funded**

This tool uses a **Random Forest classifier** trained on routine blood test parameters 
to assist in early screening of Chronic Kidney Disease.  

> **Disclaimer:** This application is intended for **research purposes only** and does 
> not constitute medical advice. Clinical decisions must always be made by a licensed physician.

**Project Owner:** Dr. Muhammad Rizwan
"""

ARTICLE = """
### About the Model
The prediction model was developed as part of an HEC-funded research project at PAF-IAST. 
The Random Forest classifier was selected after a comprehensive comparison of 8 machine learning 
algorithms, including XGBoost, CatBoost, Gradient Boosting, and Logistic Regression. 
Explainability was ensured using SHAP (SHapley Additive exPlanations) and LIME analyses. 
Top predictive features include **Creatinine**, **GFR**, and **Urea** levels.
"""

with gr.Blocks(
    title="CKD Prediction | PAF-IAST",
    theme=gr.themes.Soft(primary_hue="blue", secondary_hue="indigo"),
    css="""
    .result-box { border-radius: 10px; padding: 10px; }
    footer { display: none !important; }
    """
) as demo:

    gr.Markdown(DESCRIPTION)

    with gr.Row():
        # โ”€โ”€ Column 1: Demographic + CBC โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€
        with gr.Column():
            gr.Markdown("### ๐Ÿ‘ค Demographic")
            sex = gr.Radio(
                choices=[("Male", 1), ("Female", 0)],
                label="Sex", value=1
            )
            age = gr.Slider(minimum=1, maximum=100, step=1, value=49, label="Age (years)")

            gr.Markdown("### ๐Ÿฉธ Complete Blood Count")
            haemoglobin   = gr.Number(value=11.0, label="Haemoglobin (g/dL)")
            hematocrit    = gr.Number(value=32.0, label="Hematocrit (%)")
            rbc_count     = gr.Number(value=3.7,  label="RBC Count (millions/ยตL)")
            wbc_count     = gr.Number(value=7.2,  label="WBC Count (ร—10ยณ/ยตL)")
            platelet_count = gr.Number(value=200, label="Platelet Count (ร—10ยณ/ยตL)")

        # โ”€โ”€ Column 2: Red Cell Indices + Differential โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€
        with gr.Column():
            gr.Markdown("### ๐Ÿ“Š Red Cell Indices")
            mch    = gr.Number(value=29.2, label="MCH (pg)")
            mchc   = gr.Number(value=35.0, label="MCHC (g/dL)")
            mcv    = gr.Number(value=85.0, label="MCV (fL)")
            rdw_sd = gr.Number(value=15.7, label="RDW-SD (fL)")
            mpv    = gr.Number(value=8.7,  label="MPV (fL)")
            pct    = gr.Number(value=0.17, label="PCT (%)")
            pdw    = gr.Number(value=37.0, label="PDW (%)")

            gr.Markdown("### ๐Ÿ”ฌ Differential Count (%)")
            lymphocytes  = gr.Number(value=22, label="Lymphocytes (%)")
            monocytes    = gr.Number(value=4,  label="Monocytes (%)")
            polymorphs   = gr.Number(value=71, label="Polymorphs (%)")
            eosinophils  = gr.Number(value=2,  label="Eosinophils (%)")

        # โ”€โ”€ Column 3: Kidney Function โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€
        with gr.Column():
            gr.Markdown("### ๐Ÿซ˜ Kidney Function Tests")
            creatinine = gr.Number(value=7.0,   label="Creatinine (mg/dL)")
            urea       = gr.Number(value=112.0, label="Blood Urea (mg/dL)")
            gfr        = gr.Number(value=7.2,   label="GFR (mL/min/1.73mยฒ)")

            gr.Markdown("### ๐Ÿ” Prediction")
            predict_btn = gr.Button("๐Ÿ”ฎ Predict", variant="primary", size="lg")

            result_label   = gr.Textbox(label="Result", interactive=False, lines=1)
            result_details = gr.Markdown(label="Details")

    gr.Markdown(ARTICLE)

    # โ”€โ”€ Example inputs โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€
    gr.Examples(
        examples=[
            # CKD positive (high creatinine, low GFR)
            [1, 49, 9.3, 25.0, 12, 28.0, 36.0, 78.0, 5, 10.9, 0.08, 41.8,
             76, 71, 3.5, 16.2, 5.5, 3, 13.2, 112, 4.06],
            # No CKD (normal values)
            [0, 36, 13.4, 40.0, 25, 31.0, 34.0, 90.0, 4, 8.5, 0.17, 36.0,
             274, 68, 4.4, 12.9, 7.5, 2, 0.80, 37, 105.01],
        ],
        inputs=[
            sex, age, haemoglobin, hematocrit, lymphocytes,
            mch, mchc, mcv, monocytes, mpv, pct, pdw,
            platelet_count, polymorphs, rbc_count, rdw_sd,
            wbc_count, eosinophils, creatinine, urea, gfr
        ],
        label="Sample Inputs (click to auto-fill)"
    )

    predict_btn.click(
        fn=predict_ckd,
        inputs=[
            sex, age, haemoglobin, hematocrit, lymphocytes,
            mch, mchc, mcv, monocytes, mpv, pct, pdw,
            platelet_count, polymorphs, rbc_count, rdw_sd,
            wbc_count, eosinophils, creatinine, urea, gfr
        ],
        outputs=[result_label, result_details]
    )

if __name__ == "__main__":
    demo.launch()