NandiniLokeshReddy's picture
updated app.py
65c2a51 verified
import gradio as gr
import xgboost as xgb
import pandas as pd
import numpy as np
from sklearn.model_selection import train_test_split
from sklearn.metrics import accuracy_score, confusion_matrix
import plotly.express as px
import plotly.graph_objects as go
import json
class DiabetesGame:
def __init__(self):
self.data = self.load_data()
self.model = self.train_model()
self.user_score = 0
self.total_attempts = 0
self.tips_database = {
"glucose": "Normal fasting blood glucose levels are less than 100 mg/dL. Levels between 100-125 mg/dL indicate prediabetes.",
"bmi": "A BMI between 18.5 and 24.9 is considered healthy. BMI over 30 indicates obesity, a risk factor for diabetes.",
"blood_pressure": "Normal blood pressure is usually below 120/80 mmHg. High blood pressure often co-occurs with diabetes.",
"age": "Type 2 diabetes risk increases with age, particularly after 45 years.",
"pregnancies": "Gestational diabetes during pregnancy increases future diabetes risk.",
"lifestyle": "Regular exercise and a balanced diet can significantly reduce diabetes risk.",
"family_history": "Having a parent or sibling with diabetes increases your risk.",
"general": "Early detection and lifestyle changes can prevent or delay type 2 diabetes."
}
def load_data(self):
return pd.read_csv('https://raw.githubusercontent.com/plotly/datasets/master/diabetes.csv')
def train_model(self):
X = self.data.drop(columns=['Outcome'])
y = self.data['Outcome']
X_train, _, y_train, _ = train_test_split(X, y, test_size=0.2, random_state=42)
model = xgb.XGBClassifier(
eval_metric='logloss',
max_depth=6,
learning_rate=0.1,
n_estimators=100,
random_state=42
)
model.fit(X_train, y_train)
return model
def create_radar_chart(self, values):
categories = ['Pregnancies', 'Glucose', 'Blood Pressure', 'Skin Thickness',
'Insulin', 'BMI', 'Diabetes Pedigree', 'Age']
# Normalize values for radar chart
max_values = [17, 200, 122, 99, 846, 67.1, 2.42, 81]
normalized_values = [v/m for v, m in zip(values, max_values)]
fig = go.Figure()
fig.add_trace(go.Scatterpolar(
r=normalized_values,
theta=categories,
fill='toself',
name='Patient Values'
))
fig.update_layout(
polar=dict(
radialaxis=dict(
visible=True,
range=[0, 1]
)),
showlegend=True,
title="Patient Risk Factors Radar Chart"
)
return fig
def create_feature_importance_plot(self):
importance_df = pd.DataFrame({
'Feature': ['Pregnancies', 'Glucose', 'Blood Pressure', 'Skin Thickness',
'Insulin', 'BMI', 'Diabetes Pedigree', 'Age'],
'Importance': self.model.feature_importances_
})
importance_df = importance_df.sort_values('Importance', ascending=True)
fig = px.bar(importance_df, x='Importance', y='Feature',
orientation='h',
title='Feature Importance in Diagnosis')
fig.update_layout(height=400)
return fig
def get_relevant_tips(self, values):
tips = []
# Add tips based on values
if values[1] > 140: # High glucose
tips.append(("⚠️ High Glucose", self.tips_database["glucose"]))
if values[5] > 30: # High BMI
tips.append(("⚠️ High BMI", self.tips_database["bmi"]))
if values[2] > 90: # High blood pressure
tips.append(("⚠️ High Blood Pressure", self.tips_database["blood_pressure"]))
# Always add a random general tip
general_tips = [self.tips_database["lifestyle"],
self.tips_database["family_history"],
self.tips_database["general"]]
tips.append(("πŸ’‘ Health Tip", np.random.choice(general_tips)))
return "\n\n".join([f"{title}\n{content}" for title, content in tips])
def predict_and_play(self, pregnancies, glucose, blood_pressure, skin_thickness,
insulin, bmi, diabetes_pedigree, age, user_diagnosis):
values = [pregnancies, glucose, blood_pressure, skin_thickness,
insulin, bmi, diabetes_pedigree, age]
# Make prediction
user_input = np.array(values).reshape(1, -1)
prediction = self.model.predict(user_input)[0]
probability = self.model.predict_proba(user_input)[0][1] * 100
# Update score
self.total_attempts += 1
correct = (user_diagnosis == "Yes" and prediction == 1) or \
(user_diagnosis == "No" and prediction == 0)
if correct:
self.user_score += 1
# Create visualizations
radar_chart = self.create_radar_chart(values)
importance_plot = self.create_feature_importance_plot()
# Generate result message
accuracy = (self.user_score / self.total_attempts) * 100 if self.total_attempts > 0 else 0
result = f"""{'πŸŽ‰ Correct!' if correct else '❌ Incorrect'}\n
Model Prediction: {'Diabetes Risk Detected' if prediction == 1 else 'No Significant Risk'}\n
Confidence: {probability:.1f}%\n
Your Score: {self.user_score}/{self.total_attempts} ({accuracy:.1f}% accuracy)
"""
# Get relevant tips
tips = self.get_relevant_tips(values)
return result, radar_chart, importance_plot, tips
# Initialize game
game = DiabetesGame()
# Create the interface
with gr.Blocks(theme=gr.themes.Soft()) as interface:
gr.Markdown("""
# πŸ₯ Interactive Diabetes Diagnosis Game
Test your medical diagnosis skills! Analyze patient data and try to predict diabetes risk.
Your score will be tracked as you play.
## How to Play:
1. Adjust the patient parameters using the sliders
2. Make your diagnosis (Yes/No for diabetes risk)
3. Submit to see if you matched the model's prediction
4. Learn from the visualizations and tips
""")
with gr.Row():
with gr.Column():
pregnancies = gr.Slider(0, 17, step=1, label="Pregnancies")
glucose = gr.Slider(0, 200, value=120, step=1, label="Glucose Level")
blood_pressure = gr.Slider(0, 122, value=70, step=1, label="Blood Pressure")
skin_thickness = gr.Slider(0, 99, value=20, step=1, label="Skin Thickness")
with gr.Column():
insulin = gr.Slider(0, 846, value=80, step=1, label="Insulin")
bmi = gr.Slider(0.0, 67.1, value=25.0, step=0.1, label="BMI")
diabetes_pedigree = gr.Slider(0.078, 2.42, value=0.5, step=0.001, label="Diabetes Pedigree")
age = gr.Slider(21, 81, value=30, step=1, label="Age")
diagnosis = gr.Radio(["Yes", "No"], label="Your Diagnosis", info="Do you think this patient has diabetes?")
submit_btn = gr.Button("Submit Diagnosis", variant="primary")
with gr.Row():
result_box = gr.Textbox(label="Game Result", lines=5)
tips_box = gr.Textbox(label="Health Tips & Information", lines=5)
with gr.Row():
radar_plot = gr.Plot(label="Patient Risk Factors")
importance_plot = gr.Plot(label="Feature Importance")
submit_btn.click(
fn=game.predict_and_play,
inputs=[pregnancies, glucose, blood_pressure, skin_thickness,
insulin, bmi, diabetes_pedigree, age, diagnosis],
outputs=[result_box, radar_plot, importance_plot, tips_box]
)
gr.Markdown("""
## πŸ“š About the Features
- **Pregnancies**: Number of times pregnant
- **Glucose**: Plasma glucose concentration (2 hours in an oral glucose tolerance test)
- **Blood Pressure**: Diastolic blood pressure (mm Hg)
- **Skin Thickness**: Triceps skin fold thickness (mm)
- **Insulin**: 2-Hour serum insulin (mu U/ml)
- **BMI**: Body mass index (weight in kg/(height in m)Β²)
- **Diabetes Pedigree**: A function scoring likelihood of diabetes based on family history
- **Age**: Age in years
""")
if __name__ == "__main__":
interface.launch()