DreamStream-1 commited on
Commit
6599671
Β·
verified Β·
1 Parent(s): d352c28

Create app.py

Browse files
Files changed (1) hide show
  1. app.py +373 -0
app.py ADDED
@@ -0,0 +1,373 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import os
2
+ import gradio as gr
3
+ import nltk
4
+ import numpy as np
5
+ import tflearn
6
+ import random
7
+ import json
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 googlemaps
13
+ import folium
14
+ import torch
15
+ import pandas as pd
16
+ from sklearn.tree import DecisionTreeClassifier
17
+ from sklearn.ensemble import RandomForestClassifier
18
+ from sklearn.naive_bayes import GaussianNB
19
+ from sklearn.metrics import accuracy_score
20
+ from sklearn.preprocessing import LabelEncoder
21
+
22
+ # Suppress TensorFlow warnings
23
+ os.environ["CUDA_VISIBLE_DEVICES"] = "-1" # No GPU available, use CPU only
24
+ os.environ["TF_CPP_MIN_LOG_LEVEL"] = "3" # Suppress TensorFlow logging
25
+
26
+ # Download necessary NLTK resources
27
+ nltk.download("punkt")
28
+ stemmer = LancasterStemmer()
29
+
30
+ # Load intents and chatbot training data
31
+ with open("intents.json") as file:
32
+ intents_data = json.load(file)
33
+
34
+ with open("data.pickle", "rb") as f:
35
+ words, labels, training, output = pickle.load(f)
36
+
37
+ # Build the chatbot model
38
+ net = tflearn.input_data(shape=[None, len(training[0])])
39
+ net = tflearn.fully_connected(net, 8)
40
+ net = tflearn.fully_connected(net, 8)
41
+ net = tflearn.fully_connected(net, len(output[0]), activation="softmax")
42
+ net = tflearn.regression(net)
43
+ chatbot_model = tflearn.DNN(net)
44
+ chatbot_model.load("MentalHealthChatBotmodel.tflearn")
45
+
46
+ # Hugging Face sentiment and emotion models
47
+ tokenizer_sentiment = AutoTokenizer.from_pretrained("cardiffnlp/twitter-roberta-base-sentiment")
48
+ model_sentiment = AutoModelForSequenceClassification.from_pretrained("cardiffnlp/twitter-roberta-base-sentiment")
49
+ tokenizer_emotion = AutoTokenizer.from_pretrained("j-hartmann/emotion-english-distilroberta-base")
50
+ model_emotion = AutoModelForSequenceClassification.from_pretrained("j-hartmann/emotion-english-distilroberta-base")
51
+
52
+ # Google Maps API Client
53
+ gmaps = googlemaps.Client(key=os.getenv("GOOGLE_API_KEY"))
54
+
55
+ # Disease Prediction Code
56
+ def load_data():
57
+ try:
58
+ df = pd.read_csv("Training.csv")
59
+ tr = pd.read_csv("Testing.csv")
60
+ except FileNotFoundError:
61
+ raise RuntimeError("Data files not found. Please ensure `Training.csv` and `Testing.csv` are uploaded correctly.")
62
+
63
+ # Encode diseases
64
+ disease_dict = {
65
+ 'Fungal infection': 0, 'Allergy': 1, 'GERD': 2, 'Chronic cholestasis': 3, 'Drug Reaction': 4,
66
+ 'Peptic ulcer diseae': 5, 'AIDS': 6, 'Diabetes ': 7, 'Gastroenteritis': 8, 'Bronchial Asthma': 9,
67
+ 'Hypertension ': 10, 'Migraine': 11, 'Cervical spondylosis': 12, 'Paralysis (brain hemorrhage)': 13,
68
+ 'Jaundice': 14, 'Malaria': 15, 'Chicken pox': 16, 'Dengue': 17, 'Typhoid': 18, 'hepatitis A': 19,
69
+ 'Hepatitis B': 20, 'Hepatitis C': 21, 'Hepatitis D': 22, 'Hepatitis E': 23, 'Alcoholic hepatitis': 24,
70
+ 'Tuberculosis': 25, 'Common Cold': 26, 'Pneumonia': 27, 'Dimorphic hemmorhoids(piles)': 28,
71
+ 'Heart attack': 29, 'Varicose veins': 30, 'Hypothyroidism': 31, 'Hyperthyroidism': 32,
72
+ 'Hypoglycemia': 33, 'Osteoarthritist': 34, 'Arthritis': 35,
73
+ '(vertigo) Paroymsal Positional Vertigo': 36, 'Acne': 37, 'Urinary tract infection': 38,
74
+ 'Psoriasis': 39, 'Impetigo': 40
75
+ }
76
+
77
+ # Replace prognosis values with numerical categories
78
+ df.replace({'prognosis': disease_dict}, inplace=True)
79
+
80
+ # Check unique values in prognosis for debugging
81
+ print("Unique values in prognosis after mapping:", df['prognosis'].unique())
82
+
83
+ # Ensure prognosis is purely numerical after mapping
84
+ if df['prognosis'].dtype == 'object': # Check for unmapped entries
85
+ raise ValueError(f"The prognosis contains unmapped values: {df['prognosis'].unique()}")
86
+
87
+ df['prognosis'] = df['prognosis'].astype(int) # Convert to integer
88
+
89
+ df = df.infer_objects() # Remove 'copy' argument
90
+
91
+ # Similar process for the testing data
92
+ tr.replace({'prognosis': disease_dict}, inplace=True)
93
+
94
+ # Ensure it is also numerical
95
+ if tr['prognosis'].dtype == 'object':
96
+ raise ValueError(f"Testing data prognosis contains unmapped values: {tr['prognosis'].unique()}")
97
+
98
+ tr['prognosis'] = tr['prognosis'].astype(int) # Convert to integer if necessary
99
+ tr = tr.infer_objects() # Remove 'copy' argument
100
+
101
+ return df, tr, disease_dict
102
+
103
+ df, tr, disease_dict = load_data()
104
+ l1 = list(df.columns[:-1]) # All columns except prognosis
105
+ X = df[l1]
106
+ y = df['prognosis']
107
+ X_test = tr[l1]
108
+ y_test = tr['prognosis']
109
+
110
+ # Encode the target variable with LabelEncoder if still in string format
111
+ le = LabelEncoder()
112
+ y_encoded = le.fit_transform(y) # Needs to be string labels, assuming df['prognosis'] has no numerical labels
113
+
114
+ def train_models():
115
+ models = {
116
+ "Decision Tree": DecisionTreeClassifier(),
117
+ "Random Forest": RandomForestClassifier(),
118
+ "Naive Bayes": GaussianNB()
119
+ }
120
+ trained_models = {}
121
+ for model_name, model_obj in models.items():
122
+ model_obj.fit(X, y_encoded) # Use encoded labels
123
+ acc = accuracy_score(y_test, model_obj.predict(X_test))
124
+ trained_models[model_name] = (model_obj, acc)
125
+ return trained_models
126
+
127
+ trained_models = train_models()
128
+
129
+ def predict_disease(model, symptoms):
130
+ input_test = np.zeros(len(l1))
131
+ for symptom in symptoms:
132
+ if symptom in l1:
133
+ input_test[l1.index(symptom)] = 1
134
+ prediction = model.predict([input_test])[0]
135
+ confidence = model.predict_proba([input_test])[0][prediction] if hasattr(model, 'predict_proba') else None
136
+ return {
137
+ "disease": list(disease_dict.keys())[list(disease_dict.values()).index(prediction)],
138
+ "confidence": confidence
139
+ }
140
+
141
+ def disease_prediction_interface(symptoms):
142
+ symptoms_selected = [s for s in symptoms if s != "None"]
143
+
144
+ if len(symptoms_selected) < 3:
145
+ return ["Please select at least 3 symptoms for accurate prediction."]
146
+
147
+ results = []
148
+ for model_name, (model, acc) in trained_models.items():
149
+ prediction_info = predict_disease(model, symptoms_selected)
150
+ predicted_disease = prediction_info["disease"]
151
+ confidence_score = prediction_info["confidence"]
152
+
153
+ result = f"{model_name} Prediction: Predicted Disease: **{predicted_disease}**"
154
+ if confidence_score is not None:
155
+ result += f" (Confidence: {confidence_score:.2f})"
156
+ result += f" (Accuracy: {acc * 100:.2f}%)"
157
+
158
+ results.append(result)
159
+
160
+ return results
161
+
162
+ # Helper Functions (for chatbot)
163
+ def bag_of_words(s, words):
164
+ bag = [0] * len(words)
165
+ s_words = word_tokenize(s)
166
+ s_words = [stemmer.stem(word.lower()) for word in s_words if word.isalnum()]
167
+ for se in s_words:
168
+ for i, w in enumerate(words):
169
+ if w == se:
170
+ bag[i] = 1
171
+ return np.array(bag)
172
+
173
+ def generate_chatbot_response(message, history):
174
+ history = history or []
175
+ try:
176
+ result = chatbot_model.predict([bag_of_words(message, words)])
177
+ tag = labels[np.argmax(result)]
178
+ response = next((random.choice(intent["responses"]) for intent in intents_data["intents"] if intent["tag"] == tag), "I'm sorry, I didn't understand that. πŸ€”")
179
+ except Exception as e:
180
+ response = f"Error: {e}"
181
+ history.append((message, response))
182
+ return history, response
183
+
184
+ def analyze_sentiment(user_input):
185
+ inputs = tokenizer_sentiment(user_input, return_tensors="pt")
186
+ with torch.no_grad():
187
+ outputs = model_sentiment(**inputs)
188
+ sentiment_class = torch.argmax(outputs.logits, dim=1).item()
189
+ sentiment_map = ["Negative πŸ˜”", "Neutral 😐", "Positive 😊"]
190
+ return f"Sentiment: {sentiment_map[sentiment_class]}"
191
+
192
+ def detect_emotion(user_input):
193
+ pipe = pipeline("text-classification", model=model_emotion, tokenizer=tokenizer_emotion)
194
+ result = pipe(user_input)
195
+ emotion = result[0]["label"].lower().strip()
196
+ emotion_map = {
197
+ "joy": "Joy 😊",
198
+ "anger": "Anger 😠",
199
+ "sadness": "Sadness 😒",
200
+ "fear": "Fear 😨",
201
+ "surprise": "Surprise 😲",
202
+ "neutral": "Neutral 😐",
203
+ }
204
+ return emotion_map.get(emotion, "Unknown πŸ€”"), emotion
205
+
206
+ def generate_suggestions(emotion):
207
+ emotion_key = emotion.lower()
208
+ suggestions = {
209
+ # Define suggestions based on the detected emotion
210
+ }
211
+
212
+ formatted_suggestions = [
213
+ [title, f'<a href="{link}" target="_blank">{link}</a>'] for title, link in suggestions.get(emotion_key, [["No specific suggestions available.", "#"]])
214
+ ]
215
+ return formatted_suggestions
216
+
217
+ def get_health_professionals_and_map(location, query):
218
+ """Search nearby healthcare professionals using Google Maps API."""
219
+ try:
220
+ if not location or not query:
221
+ return [], "" # Return empty list if inputs are missing
222
+
223
+ geo_location = gmaps.geocode(location)
224
+ if geo_location:
225
+ lat, lng = geo_location[0]["geometry"]["location"].values()
226
+ places_result = gmaps.places_nearby(location=(lat, lng), radius=10000, keyword=query)["results"]
227
+ professionals = []
228
+ map_ = folium.Map(location=(lat, lng), zoom_start=13)
229
+ for place in places_result:
230
+ professionals.append([place['name'], place.get('vicinity', 'No address provided')])
231
+ folium.Marker(
232
+ location=[place["geometry"]["location"]["lat"], place["geometry"]["location"]["lng"]],
233
+ popup=f"{place['name']}"
234
+ ).add_to(map_)
235
+ return professionals, map_._repr_html_()
236
+
237
+ return [], "" # Return empty list if no professionals found
238
+ except Exception as e:
239
+ return [], "" # Return empty list on exception
240
+
241
+ # Main Application Logic
242
+ def app_function(user_input, location, query, symptoms, history):
243
+ chatbot_history, _ = generate_chatbot_response(user_input, history)
244
+ sentiment_result = analyze_sentiment(user_input)
245
+ emotion_result, cleaned_emotion = detect_emotion(user_input)
246
+ suggestions = generate_suggestions(cleaned_emotion)
247
+ professionals, map_html = get_health_professionals_and_map(location, query)
248
+ disease_results = disease_prediction_interface(symptoms)
249
+
250
+ return (
251
+ chatbot_history,
252
+ sentiment_result,
253
+ emotion_result,
254
+ suggestions,
255
+ professionals,
256
+ map_html,
257
+ disease_results
258
+ )
259
+
260
+ # CSS Styling
261
+ custom_css = """
262
+ body {
263
+ font-family: 'Roboto', sans-serif;
264
+ background-color: #3c6487; /* Set the background color */
265
+ color: white;
266
+ }
267
+
268
+ h1 {
269
+ background: #ffffff;
270
+ color: #000000;
271
+ border-radius: 8px;
272
+ padding: 10px;
273
+ font-weight: bold;
274
+ text-align: center;
275
+ font-size: 2.5rem;
276
+ }
277
+
278
+ textarea, input {
279
+ background: transparent;
280
+ color: black;
281
+ border: 2px solid orange;
282
+ padding: 8px;
283
+ font-size: 1rem;
284
+ caret-color: black;
285
+ outline: none;
286
+ border-radius: 8px;
287
+ }
288
+
289
+ textarea:focus, input:focus {
290
+ background: transparent;
291
+ color: black;
292
+ border: 2px solid orange;
293
+ outline: none;
294
+ }
295
+
296
+ textarea:hover, input:hover {
297
+ background: transparent;
298
+ color: black;
299
+ border: 2px solid orange;
300
+ }
301
+
302
+ .df-container {
303
+ background: white;
304
+ color: black;
305
+ border: 2px solid orange;
306
+ border-radius: 10px;
307
+ padding: 10px;
308
+ font-size: 14px;
309
+ max-height: 400px;
310
+ height: auto;
311
+ overflow-y: auto;
312
+ }
313
+
314
+ #suggestions-title {
315
+ text-align: center !important; /* Ensure the centering is applied */
316
+ font-weight: bold !important; /* Ensure bold is applied */
317
+ color: white !important; /* Ensure color is applied */
318
+ font-size: 4.2rem !important; /* Ensure font size is applied */
319
+ margin-bottom: 20px !important; /* Ensure margin is applied */
320
+ }
321
+
322
+ /* Style for the submit button */
323
+ .gr-button {
324
+ background-color: #ae1c93; /* Set the background color to #ae1c93 */
325
+ box-shadow: 0 4px 6px rgba(0, 0, 0, 0.1), 0 2px 4px rgba(0, 0, 0, 0.06);
326
+ transition: background-color 0.3s ease;
327
+ }
328
+
329
+ .gr-button:hover {
330
+ background-color: #8f167b;
331
+ }
332
+
333
+ .gr-button:active {
334
+ background-color: #7f156b;
335
+ }
336
+ """
337
+
338
+ # Gradio Application
339
+ with gr.Blocks(css=custom_css) as app:
340
+ gr.HTML("<h1>🌟 Well-Being Companion</h1>")
341
+
342
+ with gr.Row():
343
+ user_input = gr.Textbox(label="Please Enter Your Message Here")
344
+ location = gr.Textbox(label="Your Current Location Here")
345
+ query = gr.Textbox(label="Search Health Professionals Nearby")
346
+
347
+ with gr.Row():
348
+ symptom1 = gr.Dropdown(choices=["None"] + l1, label="Symptom 1")
349
+ symptom2 = gr.Dropdown(choices=["None"] + l1, label="Symptom 2")
350
+ symptom3 = gr.Dropdown(choices=["None"] + l1, label="Symptom 3")
351
+ symptom4 = gr.Dropdown(choices=["None"] + l1, label="Symptom 4")
352
+ symptom5 = gr.Dropdown(choices=["None"] + l1, label="Symptom 5")
353
+
354
+ submit = gr.Button(value="Submit", variant="primary")
355
+
356
+ chatbot = gr.Chatbot(label="Chat History")
357
+ sentiment = gr.Textbox(label="Detected Sentiment")
358
+ emotion = gr.Textbox(label="Detected Emotion")
359
+
360
+ gr.Markdown("Suggestions", elem_id="suggestions-title")
361
+
362
+ suggestions = gr.DataFrame(headers=["Title", "Link"]) # Suggestions DataFrame
363
+ professionals = gr.DataFrame(label="Nearby Health Professionals", headers=["Name", "Address"]) # Professionals DataFrame
364
+ map_html = gr.HTML(label="Interactive Map")
365
+ disease_predictions = gr.Textbox(label="Disease Predictions") # For Disease Prediction Results
366
+
367
+ submit.click(
368
+ app_function,
369
+ inputs=[user_input, location, query, [symptom1, symptom2, symptom3, symptom4, symptom5], chatbot],
370
+ outputs=[chatbot, sentiment, emotion, suggestions, professionals, map_html, disease_predictions],
371
+ )
372
+
373
+ app.launch()