| import gradio as gr |
| import pickle |
| import numpy as np |
| import pandas as pd |
| import os |
| from groq import Groq |
|
|
| |
| |
| |
|
|
| |
| with open('models/diabetes_model.pkl', 'rb') as f: |
| diabetes_model = pickle.load(f) |
| with open('models/diabetes_columns.pkl', 'rb') as f: |
| diabetes_columns = pickle.load(f) |
|
|
| |
| with open('models/ckd_model.pkl', 'rb') as f: |
| ckd_model = pickle.load(f) |
| with open('models/ckd_scaler.pkl', 'rb') as f: |
| ckd_scaler = pickle.load(f) |
|
|
| |
| with open('models/heart_model.pkl', 'rb') as f: |
| heart_model = pickle.load(f) |
| with open('models/heart_scaler.pkl', 'rb') as f: |
| heart_scaler = pickle.load(f) |
| with open('models/heart_columns.pkl', 'rb') as f: |
| heart_columns = pickle.load(f) |
| with open('models/heart_encoding_maps.pkl', 'rb') as f: |
| heart_encoding_maps = pickle.load(f) |
|
|
| CKD_COLUMNS = ['age', 'bp', 'sg', 'al', 'su', 'rbc', 'pc', 'pcc', 'ba', 'bgr', |
| 'bu', 'sc', 'sod', 'pot', 'hemo', 'pcv', 'wc', 'rc', |
| 'htn', 'dm', 'cad', 'appet', 'pe', 'ane'] |
|
|
| |
| |
| |
| |
| groq_client = Groq(api_key=os.environ.get("GROQ_API_KEY")) |
|
|
| SYSTEM_PROMPT = """You are a helpful medical information assistant embedded in a website |
| that predicts risk for Diabetes, Chronic Kidney Disease (CKD), and Heart Disease using |
| machine learning models. You can explain general medical information about these three |
| conditions, their symptoms, risk factors, and prevention, and explain how to use the site. |
| You are not a doctor and must never provide a diagnosis or replace professional medical advice. |
| If a user describes symptoms suggesting an emergency, advise them to seek immediate medical care. |
| Keep answers concise and clear.""" |
|
|
|
|
| def risk_label(prob): |
| if prob < 0.3: |
| return "Low risk" |
| elif prob < 0.6: |
| return "Moderate risk" |
| else: |
| return "High risk" |
|
|
|
|
| def result_markdown(prob): |
| return (f"## {risk_label(prob)}\n\n" |
| f"### Risk score: {prob*100:.1f}%\n\n" |
| f"*This is a preliminary indicator, not a medical diagnosis. " |
| f"If the risk is high, please consult a doctor.*") |
|
|
|
|
| |
| |
| |
| def predict_diabetes(gender, age, hypertension, heart_disease, smoking_history, bmi, hba1c, glucose): |
| row = { |
| 'age': age, |
| 'hypertension': 1 if hypertension == "Yes" else 0, |
| 'heart_disease': 1 if heart_disease == "Yes" else 0, |
| 'bmi': bmi, |
| 'HbA1c_level': hba1c, |
| 'blood_glucose_level': glucose, |
| 'gender_Male': 1 if gender == "Male" else 0, |
| 'smoking_history_ever': 1 if smoking_history == "Ever" else 0, |
| 'smoking_history_former': 1 if smoking_history == "Former" else 0, |
| 'smoking_history_never': 1 if smoking_history == "Never" else 0, |
| 'smoking_history_not current': 1 if smoking_history == "Not Current" else 0, |
| } |
| input_df = pd.DataFrame([row])[diabetes_columns] |
| prob = diabetes_model.predict_proba(input_df)[0][1] |
| return result_markdown(prob) |
|
|
|
|
| |
| |
| |
| def predict_ckd(age, bp, sg, al, su, rbc, pc, pcc, ba, bgr, bu, sc, sod, pot, |
| hemo, pcv, wc, rc, htn, dm, cad, appet, pe, ane): |
|
|
| binary_map_normal = {"Normal": 1, "Abnormal": 0} |
| binary_map_present = {"Present": 1, "Not present": 0} |
| binary_map_yesno = {"Yes": 1, "No": 0} |
| binary_map_appet = {"Good": 1, "Poor": 0} |
|
|
| row = { |
| 'age': age, 'bp': bp, 'sg': sg, 'al': al, 'su': su, |
| 'rbc': binary_map_normal[rbc], 'pc': binary_map_normal[pc], |
| 'pcc': binary_map_present[pcc], 'ba': binary_map_present[ba], |
| 'bgr': bgr, 'bu': bu, 'sc': sc, 'sod': sod, 'pot': pot, |
| 'hemo': hemo, 'pcv': pcv, 'wc': wc, 'rc': rc, |
| 'htn': binary_map_yesno[htn], 'dm': binary_map_yesno[dm], |
| 'cad': binary_map_yesno[cad], 'appet': binary_map_appet[appet], |
| 'pe': binary_map_yesno[pe], 'ane': binary_map_yesno[ane], |
| } |
| input_df = pd.DataFrame([row])[CKD_COLUMNS] |
| input_scaled = ckd_scaler.transform(input_df) |
| prob = ckd_model.predict_proba(input_scaled)[0][1] |
| return result_markdown(prob) |
|
|
|
|
| |
| |
| |
| def predict_heart(age, sex, cp, trestbps, chol, fbs, restecg, thalch, exang, oldpeak, slope, thal): |
| row = { |
| 'age': age, |
| 'sex': heart_encoding_maps['sex'][sex], |
| 'cp': heart_encoding_maps['cp'][cp], |
| 'trestbps': trestbps, |
| 'chol': chol, |
| 'fbs': heart_encoding_maps['fbs'][fbs], |
| 'restecg': heart_encoding_maps['restecg'][restecg], |
| 'thalch': thalch, |
| 'exang': heart_encoding_maps['exang'][exang], |
| 'oldpeak': oldpeak, |
| 'slope': heart_encoding_maps['slope'][slope], |
| 'thal': heart_encoding_maps['thal'][thal], |
| } |
| input_df = pd.DataFrame([row])[heart_columns] |
| input_scaled = heart_scaler.transform(input_df) |
| prob = heart_model.predict_proba(input_scaled)[0][1] |
| return result_markdown(prob) |
|
|
|
|
| |
| |
| |
| def chatbot_response(message, history): |
| messages = [{"role": "system", "content": SYSTEM_PROMPT}] |
|
|
| for turn in history: |
| if isinstance(turn, dict): |
| messages.append({"role": turn["role"], "content": turn["content"]}) |
| else: |
| user_msg, bot_msg = turn |
| messages.append({"role": "user", "content": user_msg}) |
| if bot_msg: |
| messages.append({"role": "assistant", "content": bot_msg}) |
|
|
| messages.append({"role": "user", "content": message}) |
|
|
| try: |
| completion = groq_client.chat.completions.create( |
| model="llama-3.3-70b-versatile", |
| messages=messages, |
| temperature=0.5, |
| max_tokens=500, |
| ) |
| return completion.choices[0].message.content |
| except Exception as e: |
| return f"Sorry, the assistant is temporarily unavailable. Error: {str(e)}" |
|
|
|
|
| |
| |
| |
| with gr.Blocks(title="Medical Diagnosis Assistant") as demo: |
| gr.Markdown("# Medical Diagnosis Assistant") |
| gr.Markdown("A tool that estimates risk for three conditions based on your health data. " |
| "This tool does not replace professional medical advice.") |
|
|
| with gr.Tabs(): |
| |
| with gr.Tab("Diabetes Check"): |
| with gr.Row(): |
| with gr.Column(): |
| d_gender = gr.Radio(["Male", "Female"], label="Gender", value="Male") |
| d_age = gr.Number(label="Age", value=30) |
| d_hyper = gr.Radio(["Yes", "No"], label="Hypertension", value="No") |
| d_heart = gr.Radio(["Yes", "No"], label="Heart Disease", value="No") |
| d_smoke = gr.Dropdown( |
| ["Never", "Former", "Ever", "Not Current", "Current"], |
| label="Smoking History", value="Never") |
| d_bmi = gr.Number(label="BMI", value=25.0) |
| d_hba1c = gr.Number(label="HbA1c Level", value=5.5) |
| d_glucose = gr.Number(label="Blood Glucose Level", value=100) |
| d_btn = gr.Button("Predict", variant="primary") |
| with gr.Column(): |
| d_output = gr.Markdown() |
| d_btn.click(predict_diabetes, |
| inputs=[d_gender, d_age, d_hyper, d_heart, d_smoke, d_bmi, d_hba1c, d_glucose], |
| outputs=d_output) |
|
|
| |
| with gr.Tab("CKD Check"): |
| with gr.Row(): |
| with gr.Column(): |
| c_age = gr.Number(label="Age", value=40) |
| c_bp = gr.Number(label="Blood Pressure", value=80) |
| c_sg = gr.Number(label="Specific Gravity", value=1.02) |
| c_al = gr.Number(label="Albumin", value=0) |
| c_su = gr.Number(label="Sugar", value=0) |
| c_rbc = gr.Radio(["Normal", "Abnormal"], label="Red Blood Cells", value="Normal") |
| c_pc = gr.Radio(["Normal", "Abnormal"], label="Pus Cell", value="Normal") |
| c_pcc = gr.Radio(["Present", "Not present"], label="Pus Cell Clumps", value="Not present") |
| c_ba = gr.Radio(["Present", "Not present"], label="Bacteria", value="Not present") |
| c_bgr = gr.Number(label="Blood Glucose Random", value=100) |
| c_bu = gr.Number(label="Blood Urea", value=30) |
| with gr.Column(): |
| c_sc = gr.Number(label="Serum Creatinine", value=1.0) |
| c_sod = gr.Number(label="Sodium", value=140) |
| c_pot = gr.Number(label="Potassium", value=4.5) |
| c_hemo = gr.Number(label="Hemoglobin", value=14.0) |
| c_pcv = gr.Number(label="Packed Cell Volume", value=40) |
| c_wc = gr.Number(label="White Blood Cell Count", value=8000) |
| c_rc = gr.Number(label="Red Blood Cell Count", value=5.0) |
| c_htn = gr.Radio(["Yes", "No"], label="Hypertension", value="No") |
| c_dm = gr.Radio(["Yes", "No"], label="Diabetes Mellitus", value="No") |
| c_cad = gr.Radio(["Yes", "No"], label="Coronary Artery Disease", value="No") |
| c_appet = gr.Radio(["Good", "Poor"], label="Appetite", value="Good") |
| c_pe = gr.Radio(["Yes", "No"], label="Pedal Edema", value="No") |
| c_ane = gr.Radio(["Yes", "No"], label="Anemia", value="No") |
| c_btn = gr.Button("Predict", variant="primary") |
| c_output = gr.Markdown() |
| c_btn.click(predict_ckd, |
| inputs=[c_age, c_bp, c_sg, c_al, c_su, c_rbc, c_pc, c_pcc, c_ba, c_bgr, |
| c_bu, c_sc, c_sod, c_pot, c_hemo, c_pcv, c_wc, c_rc, |
| c_htn, c_dm, c_cad, c_appet, c_pe, c_ane], |
| outputs=c_output) |
|
|
| |
| with gr.Tab("Heart Disease Check"): |
| gr.Markdown("This check relies on clinical test values (ECG, imaging). " |
| "If you do not have these results, consult your doctor.") |
| with gr.Row(): |
| with gr.Column(): |
| h_age = gr.Number(label="Age", value=45) |
| h_sex = gr.Radio(["Male", "Female"], label="Sex", value="Male") |
| h_cp = gr.Dropdown(["typical angina", "atypical angina", "non-anginal", "asymptomatic"], |
| label="Chest Pain Type", value="non-anginal") |
| h_trestbps = gr.Number(label="Resting Blood Pressure", value=120) |
| h_chol = gr.Number(label="Cholesterol", value=200) |
| h_fbs = gr.Radio(["True", "False"], label="Fasting Blood Sugar > 120", value="False") |
| with gr.Column(): |
| h_restecg = gr.Dropdown(["normal", "stt abnormality", "lv hypertrophy"], |
| label="Resting ECG Result", value="normal") |
| h_thalch = gr.Number(label="Max Heart Rate Achieved", value=150) |
| h_exang = gr.Radio(["True", "False"], label="Exercise Induced Angina", value="False") |
| h_oldpeak = gr.Number(label="ST Depression (oldpeak)", value=0.0) |
| h_slope = gr.Dropdown(["upsloping", "flat", "downsloping"], label="Slope of ST Segment", value="upsloping") |
| h_thal = gr.Dropdown(["normal", "fixed defect", "reversable defect"], label="Thalassemia", value="normal") |
| h_btn = gr.Button("Predict", variant="primary") |
| h_output = gr.Markdown() |
| h_btn.click(predict_heart, |
| inputs=[h_age, h_sex, h_cp, h_trestbps, h_chol, h_fbs, h_restecg, |
| h_thalch, h_exang, h_oldpeak, h_slope, h_thal], |
| outputs=h_output) |
|
|
| |
| with gr.Tab("Assistant"): |
| gr.ChatInterface( |
| fn=chatbot_response, |
| examples=["Tell me about diabetes", "Symptoms of heart disease", "How do I use this site"], |
| ) |
|
|
| demo.launch() |
|
|