Update app.py
Browse files
app.py
CHANGED
@@ -1,132 +1,19 @@
|
|
1 |
-
import os
|
2 |
import gradio as gr
|
3 |
-
import nltk
|
4 |
-
import numpy as np
|
5 |
-
import json
|
6 |
-
import tflearn
|
7 |
-
import random
|
8 |
-
import pickle
|
9 |
-
from nltk.tokenize import word_tokenize
|
10 |
-
from nltk.stem.lancaster import LancasterStemmer
|
11 |
-
from transformers import AutoTokenizer, AutoModelForSequenceClassification, pipeline
|
12 |
-
import torch
|
13 |
import pandas as pd
|
|
|
14 |
from sklearn.tree import DecisionTreeClassifier
|
15 |
from sklearn.ensemble import RandomForestClassifier
|
16 |
from sklearn.naive_bayes import GaussianNB
|
17 |
from sklearn.metrics import accuracy_score
|
18 |
-
import googlemaps
|
19 |
-
import folium
|
20 |
-
|
21 |
-
# Suppress TensorFlow warnings
|
22 |
-
os.environ["CUDA_VISIBLE_DEVICES"] = "-1"
|
23 |
-
os.environ["TF_CPP_MIN_LOG_LEVEL"] = "3"
|
24 |
-
|
25 |
-
# NLTK Setup
|
26 |
-
nltk.download("punkt")
|
27 |
-
stemmer = LancasterStemmer()
|
28 |
-
|
29 |
-
# Load chatbot and disease prediction data
|
30 |
-
with open("intents.json") as file:
|
31 |
-
intents_data = json.load(file)
|
32 |
-
|
33 |
-
with open("data.pickle", "rb") as f:
|
34 |
-
words, labels, training, output = pickle.load(f)
|
35 |
-
|
36 |
-
# Chatbot model setup
|
37 |
-
net = tflearn.input_data(shape=[None, len(training[0])])
|
38 |
-
net = tflearn.fully_connected(net, 8)
|
39 |
-
net = tflearn.fully_connected(net, 8)
|
40 |
-
net = tflearn.fully_connected(net, len(output[0]), activation="softmax")
|
41 |
-
net = tflearn.regression(net)
|
42 |
-
chatbot_model = tflearn.DNN(net)
|
43 |
-
chatbot_model.load("MentalHealthChatBotmodel.tflearn")
|
44 |
-
|
45 |
-
# Hugging Face models for Well-Being Companion
|
46 |
-
tokenizer_sentiment = AutoTokenizer.from_pretrained("cardiffnlp/twitter-roberta-base-sentiment")
|
47 |
-
model_sentiment = AutoModelForSequenceClassification.from_pretrained("cardiffnlp/twitter-roberta-base-sentiment")
|
48 |
-
tokenizer_emotion = AutoTokenizer.from_pretrained("j-hartmann/emotion-english-distilroberta-base")
|
49 |
-
model_emotion = AutoModelForSequenceClassification.from_pretrained("j-hartmann/emotion-english-distilroberta-base")
|
50 |
-
|
51 |
-
# Google Maps API Client
|
52 |
-
gmaps = googlemaps.Client(key=os.getenv("GOOGLE_API_KEY"))
|
53 |
-
|
54 |
-
# Functions: Chatbot, Sentiment, Emotion, and Suggestions
|
55 |
-
def bag_of_words(s, words):
|
56 |
-
bag = [0] * len(words)
|
57 |
-
s_words = word_tokenize(s)
|
58 |
-
s_words = [stemmer.stem(word.lower()) for word in s_words if word.isalnum()]
|
59 |
-
for se in s_words:
|
60 |
-
for i, w in enumerate(words):
|
61 |
-
if w == se:
|
62 |
-
bag[i] = 1
|
63 |
-
return np.array(bag)
|
64 |
|
65 |
-
|
66 |
-
"""Generate chatbot response and maintain conversation history."""
|
67 |
-
history = history or []
|
68 |
-
result = chatbot_model.predict([bag_of_words(message, words)])
|
69 |
-
tag = labels[np.argmax(result)]
|
70 |
-
response = next((r for intent in intents_data["intents"] if intent["tag"] == tag for r in intent["responses"]), "I'm sorry, I didn't understand that. 🤔")
|
71 |
-
history.append((message, response))
|
72 |
-
return history, response
|
73 |
-
|
74 |
-
def analyze_sentiment(user_input):
|
75 |
-
inputs = tokenizer_sentiment(user_input, return_tensors="pt")
|
76 |
-
outputs = model_sentiment(**inputs)
|
77 |
-
sentiment_class = torch.argmax(outputs.logits, dim=1).item()
|
78 |
-
sentiment_map = ["Negative 😔", "Neutral 😐", "Positive 😊"]
|
79 |
-
return f"Sentiment: {sentiment_map[sentiment_class]}"
|
80 |
-
|
81 |
-
def detect_emotion(user_input):
|
82 |
-
pipe = pipeline("text-classification", model=model_emotion, tokenizer=tokenizer_emotion)
|
83 |
-
result = pipe(user_input)
|
84 |
-
emotion = result[0]["label"].lower().strip()
|
85 |
-
emotion_map = {
|
86 |
-
"joy": "Joy 😊", "anger": "Anger 😠", "sadness": "Sadness 😢", "fear": "Fear 😨",
|
87 |
-
"surprise": "Surprise 😲", "neutral": "Neutral 😐"
|
88 |
-
}
|
89 |
-
return emotion_map.get(emotion, "Unknown 🤔")
|
90 |
-
|
91 |
-
def generate_suggestions(emotion):
|
92 |
-
suggestions = {
|
93 |
-
"joy": [["Relaxation Techniques", "https://helpguide.org"], ["Dealing with Stress", "https://helpguide.org"]],
|
94 |
-
"anger": [["Stress Management", "https://health.harvard.edu"], ["Anger Management", "https://helpguide.org"]],
|
95 |
-
"fear": [["Mindfulness", "https://helpguide.org"], ["Coping with Anxiety", "https://helpguide.org"]],
|
96 |
-
"sadness": [["Emotional Wellness", "https://nih.gov"], ["Relaxation Video", "https://youtu.be/-e-4Kx5px_I"]],
|
97 |
-
"surprise": [["Managing Stress", "https://helpguide.org"], ["Coping Strategies", "https://helpguide.org"]]
|
98 |
-
}
|
99 |
-
return suggestions.get(emotion, [["No suggestions available.", "#"]])
|
100 |
-
|
101 |
-
def get_health_professionals_and_map(location, query):
|
102 |
-
try:
|
103 |
-
geo_location = gmaps.geocode(location)
|
104 |
-
if geo_location:
|
105 |
-
lat, lng = geo_location[0]["geometry"]["location"].values()
|
106 |
-
places_result = gmaps.places_nearby(location=(lat, lng), radius=10000, keyword=query)["results"]
|
107 |
-
professionals = [[place['name'], place.get('vicinity', 'No address')] for place in places_result]
|
108 |
-
map_ = folium.Map(location=(lat, lng), zoom_start=13)
|
109 |
-
for place in places_result:
|
110 |
-
folium.Marker([place["geometry"]["location"]["lat"], place["geometry"]["location"]["lng"]],
|
111 |
-
popup=place['name']).add_to(map_)
|
112 |
-
return professionals, map_._repr_html_()
|
113 |
-
return [], ""
|
114 |
-
except Exception as e:
|
115 |
-
return [], ""
|
116 |
-
|
117 |
-
def app_function(user_input, location, query, history):
|
118 |
-
chatbot_history, chatbot_response = generate_chatbot_response(user_input, history)
|
119 |
-
sentiment = analyze_sentiment(user_input)
|
120 |
-
emotion = detect_emotion(user_input)
|
121 |
-
suggestions = generate_suggestions(emotion)
|
122 |
-
professionals, map_html = get_health_professionals_and_map(location, query)
|
123 |
-
return chatbot_history, sentiment, emotion, suggestions, professionals, map_html
|
124 |
-
|
125 |
-
# Chronic Disease Prediction (Placeholder function; keep similar)
|
126 |
def load_data():
|
127 |
df = pd.read_csv("Training.csv")
|
128 |
tr = pd.read_csv("Testing.csv")
|
129 |
-
|
|
|
|
|
|
|
130 |
'Peptic ulcer diseae': 5, 'AIDS': 6, 'Diabetes ': 7, 'Gastroenteritis': 8, 'Bronchial Asthma': 9,
|
131 |
'Hypertension ': 10, 'Migraine': 11, 'Cervical spondylosis': 12, 'Paralysis (brain hemorrhage)': 13,
|
132 |
'Jaundice': 14, 'Malaria': 15, 'Chicken pox': 16, 'Dengue': 17, 'Typhoid': 18, 'hepatitis A': 19,
|
@@ -136,17 +23,30 @@ def load_data():
|
|
136 |
'Hypoglycemia': 33, 'Osteoarthristis': 34, 'Arthritis': 35,
|
137 |
'(vertigo) Paroymsal Positional Vertigo': 36, 'Acne': 37, 'Urinary tract infection': 38,
|
138 |
'Psoriasis': 39, 'Impetigo': 40
|
139 |
-
}
|
|
|
140 |
df.replace({'prognosis': disease_dict}, inplace=True)
|
|
|
|
|
|
|
|
|
|
|
141 |
return df, tr, disease_dict
|
142 |
|
143 |
-
|
144 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
145 |
X = df[l1]
|
146 |
y = df['prognosis']
|
147 |
X_test = tr[l1]
|
148 |
y_test = tr['prognosis']
|
149 |
|
|
|
150 |
def train_models():
|
151 |
models = {
|
152 |
"Decision Tree": DecisionTreeClassifier(),
|
@@ -162,123 +62,49 @@ def train_models():
|
|
162 |
|
163 |
trained_models = train_models()
|
164 |
|
165 |
-
|
166 |
-
|
167 |
-
|
168 |
-
|
169 |
-
|
170 |
-
|
171 |
-
|
172 |
-
|
173 |
-
|
174 |
-
|
175 |
-
|
176 |
-
|
177 |
-
'Migraine': ["Neurologist", "Family Doctor"],
|
178 |
-
'Cervical spondylosis': ["Orthopedist", "Family Doctor"],
|
179 |
-
'Paralysis (brain hemorrhage)': ["Neurologist", "Family Doctor"],
|
180 |
-
'Jaundice': ["Hepatologist", "Family Doctor"],
|
181 |
-
'Malaria': ["Infectious Disease Specialist", "Family Doctor"],
|
182 |
-
'Chicken pox': ["Pediatrician", "Family Doctor"],
|
183 |
-
'Dengue': ["Infectious Disease Specialist", "Family Doctor"],
|
184 |
-
'Typhoid': ["Infectious Disease Specialist", "Family Doctor"],
|
185 |
-
'hepatitis A': ["Hepatologist", "Family Doctor"],
|
186 |
-
'Hepatitis B': ["Hepatologist", "Family Doctor"],
|
187 |
-
'Hepatitis C': ["Hepatologist", "Family Doctor"],
|
188 |
-
'Hepatitis D': ["Hepatologist", "Family Doctor"],
|
189 |
-
'Hepatitis E': ["Hepatologist", "Family Doctor"],
|
190 |
-
'Alcoholic hepatitis': ["Hepatologist", "Family Doctor"],
|
191 |
-
'Tuberculosis': ["Pulmonologist", "Family Doctor"],
|
192 |
-
'Common Cold': ["General Practitioner"],
|
193 |
-
'Pneumonia': ["Pulmonologist", "Family Doctor"],
|
194 |
-
'Dimorphic hemorrhoids(piles)': ["Gastroenterologist", "Family Doctor"],
|
195 |
-
'Heart attack': ["Cardiologist"],
|
196 |
-
'Varicose veins': ["Vascular Surgeon", "Family Doctor"],
|
197 |
-
'Hypothyroidism': ["Endocrinologist", "Family Doctor"],
|
198 |
-
'Hyperthyroidism': ["Endocrinologist", "Family Doctor"],
|
199 |
-
'Hypoglycemia': ["Endocrinologist", "Family Doctor"],
|
200 |
-
'Osteoarthritis': ["Orthopedist", "Family Doctor"],
|
201 |
-
'Arthritis': ["Rheumatologist", "Family Doctor"],
|
202 |
-
'(vertigo) Paroxysmal Positional Vertigo': ["Neurologist", "Family Doctor"],
|
203 |
-
'Acne': ["Cosmetic Dermatologist", "Family Doctor"],
|
204 |
-
'Urinary tract infection': ["Urologist", "Family Doctor"],
|
205 |
-
'Psoriasis': ["Dermatologist", "Family Doctor"],
|
206 |
-
'Impetigo': ["Dermatologist", "Family Doctor"]
|
207 |
-
}
|
208 |
-
def disease_predictor(symptoms):
|
209 |
-
results = []
|
210 |
|
211 |
-
for
|
212 |
-
disease = predict_disease(model, symptoms)
|
213 |
-
pro = disease_to_professional.get(disease, ["No Recommendations Available"])
|
214 |
-
|
215 |
-
# Convert the list of recommended professionals into a string without commas
|
216 |
-
pro_str = " and ".join(pro) if isinstance(pro, list) else pro
|
217 |
-
|
218 |
-
results.append(f"Model: {model_name}\nPredicted Disease: {disease}\nRecommended Professionals: {pro_str}\n")
|
219 |
|
220 |
-
|
221 |
-
|
222 |
-
|
223 |
|
224 |
-
|
225 |
-
|
226 |
-
|
|
|
|
|
|
|
227 |
|
228 |
-
|
229 |
-
|
230 |
-
|
231 |
-
|
232 |
-
|
233 |
-
|
234 |
-
|
235 |
-
|
236 |
-
|
237 |
-
|
238 |
-
|
239 |
-
|
240 |
-
|
241 |
-
|
242 |
-
|
243 |
-
|
244 |
-
|
245 |
-
# Get nearby health professionals
|
246 |
-
nearby_professionals, map_html = get_health_professionals_and_map(location, query)
|
247 |
-
|
248 |
-
return {
|
249 |
-
"Chatbot History": chatbot_history,
|
250 |
-
"Response": response,
|
251 |
-
"Sentiment": sentiment_result,
|
252 |
-
"Emotion": emotion_result,
|
253 |
-
"Suggestions": suggestions,
|
254 |
-
"Predicted Disease": predicted_disease,
|
255 |
-
"Recommended Professionals": professionals,
|
256 |
-
"Prediction Accuracy": f"{acc * 100:.2f}%",
|
257 |
-
"Nearby Professionals": nearby_professionals,
|
258 |
-
"Map": map_html,
|
259 |
-
}
|
260 |
-
|
261 |
-
# Gradio App Configuration
|
262 |
-
interface_inputs = [
|
263 |
-
gr.Textbox(label="User Input"),
|
264 |
-
gr.Textbox(label="Symptoms (comma-separated)"),
|
265 |
-
gr.Textbox(label="Location"),
|
266 |
-
gr.Textbox(label="Query (e.g., 'doctor')"),
|
267 |
-
gr.State([]), # For chatbot history
|
268 |
-
gr.Radio(["Decision Tree", "Random Forest", "Naive Bayes"], label="Prediction Model", value="Decision Tree")
|
269 |
-
]
|
270 |
-
|
271 |
-
interface_outputs = [
|
272 |
-
gr.JSON(label="Results")
|
273 |
-
]
|
274 |
-
|
275 |
-
app = gr.Interface(
|
276 |
-
fn=interface,
|
277 |
-
inputs=interface_inputs,
|
278 |
-
outputs=interface_outputs,
|
279 |
-
title="Mental Health & Chronic Disease Assistant",
|
280 |
-
description="Chatbot, sentiment analysis, emotion detection, disease prediction, and professional locator."
|
281 |
)
|
282 |
|
283 |
-
|
284 |
-
|
|
|
|
|
1 |
import gradio as gr
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
2 |
import pandas as pd
|
3 |
+
import numpy as np
|
4 |
from sklearn.tree import DecisionTreeClassifier
|
5 |
from sklearn.ensemble import RandomForestClassifier
|
6 |
from sklearn.naive_bayes import GaussianNB
|
7 |
from sklearn.metrics import accuracy_score
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
8 |
|
9 |
+
# Load datasets
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
10 |
def load_data():
|
11 |
df = pd.read_csv("Training.csv")
|
12 |
tr = pd.read_csv("Testing.csv")
|
13 |
+
|
14 |
+
# Encode diseases
|
15 |
+
disease_dict = {
|
16 |
+
'Fungal infection': 0, 'Allergy': 1, 'GERD': 2, 'Chronic cholestasis': 3, 'Drug Reaction': 4,
|
17 |
'Peptic ulcer diseae': 5, 'AIDS': 6, 'Diabetes ': 7, 'Gastroenteritis': 8, 'Bronchial Asthma': 9,
|
18 |
'Hypertension ': 10, 'Migraine': 11, 'Cervical spondylosis': 12, 'Paralysis (brain hemorrhage)': 13,
|
19 |
'Jaundice': 14, 'Malaria': 15, 'Chicken pox': 16, 'Dengue': 17, 'Typhoid': 18, 'hepatitis A': 19,
|
|
|
23 |
'Hypoglycemia': 33, 'Osteoarthristis': 34, 'Arthritis': 35,
|
24 |
'(vertigo) Paroymsal Positional Vertigo': 36, 'Acne': 37, 'Urinary tract infection': 38,
|
25 |
'Psoriasis': 39, 'Impetigo': 40
|
26 |
+
}
|
27 |
+
|
28 |
df.replace({'prognosis': disease_dict}, inplace=True)
|
29 |
+
df = df.infer_objects(copy=False)
|
30 |
+
|
31 |
+
tr.replace({'prognosis': disease_dict}, inplace=True)
|
32 |
+
tr = tr.infer_objects(copy=False)
|
33 |
+
|
34 |
return df, tr, disease_dict
|
35 |
|
36 |
+
try:
|
37 |
+
df, tr, disease_dict = load_data()
|
38 |
+
except FileNotFoundError as e:
|
39 |
+
raise RuntimeError("Data files not found. Please ensure `Training.csv` and `Testing.csv` are available.")
|
40 |
+
except Exception as e:
|
41 |
+
raise RuntimeError(f"An error occurred while loading data: {e}")
|
42 |
+
|
43 |
+
l1 = list(df.columns[:-1])
|
44 |
X = df[l1]
|
45 |
y = df['prognosis']
|
46 |
X_test = tr[l1]
|
47 |
y_test = tr['prognosis']
|
48 |
|
49 |
+
# Trained models
|
50 |
def train_models():
|
51 |
models = {
|
52 |
"Decision Tree": DecisionTreeClassifier(),
|
|
|
62 |
|
63 |
trained_models = train_models()
|
64 |
|
65 |
+
def predict_disease(model, symptoms):
|
66 |
+
input_test = np.zeros(len(l1))
|
67 |
+
for symptom in symptoms:
|
68 |
+
if symptom in l1:
|
69 |
+
input_test[l1.index(symptom)] = 1
|
70 |
+
prediction = model.predict([input_test])[0]
|
71 |
+
return list(disease_dict.keys())[list(disease_dict.values()).index(prediction)]
|
72 |
+
|
73 |
+
# Gradio Interface
|
74 |
+
def app_function(name, symptom1, symptom2, symptom3, symptom4, symptom5):
|
75 |
+
if not name.strip():
|
76 |
+
return "Please enter the patient's name."
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
77 |
|
78 |
+
symptoms_selected = [s for s in [symptom1, symptom2, symptom3, symptom4, symptom5] if s != "None"]
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
79 |
|
80 |
+
if len(symptoms_selected) < 3:
|
81 |
+
return "Please select at least 3 symptoms for accurate prediction."
|
|
|
82 |
|
83 |
+
results = []
|
84 |
+
for model_name, (model, acc) in trained_models.items():
|
85 |
+
prediction = predict_disease(model, symptoms_selected)
|
86 |
+
result = f"{model_name} Prediction: Predicted Disease: **{prediction}**"
|
87 |
+
result += f" (Accuracy: {acc * 100:.2f}%)"
|
88 |
+
results.append(result)
|
89 |
|
90 |
+
return "\n\n".join(results)
|
91 |
+
|
92 |
+
# Gradio Interface Setup
|
93 |
+
iface = gr.Interface(
|
94 |
+
fn=app_function,
|
95 |
+
inputs=[
|
96 |
+
gr.Textbox(label="Name of Patient"),
|
97 |
+
gr.Dropdown(["None"] + l1, label="Symptom 1"),
|
98 |
+
gr.Dropdown(["None"] + l1, label="Symptom 2"),
|
99 |
+
gr.Dropdown(["None"] + l1, label="Symptom 3"),
|
100 |
+
gr.Dropdown(["None"] + l1, label="Symptom 4"),
|
101 |
+
gr.Dropdown(["None"] + l1, label="Symptom 5"),
|
102 |
+
],
|
103 |
+
outputs=gr.Textbox(label="Prediction"),
|
104 |
+
title="Disease Predictor Using Machine Learning",
|
105 |
+
description="For accurate results, please select at least 3 symptoms.",
|
106 |
+
article="**Caution:** This system is designed for informational purposes only. Please visit a healthcare provider for any medical concerns."
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
107 |
)
|
108 |
|
109 |
+
# Launch the Gradio application
|
110 |
+
iface.launch()
|