Spaces:
Sleeping
Sleeping
import os | |
import gradio as gr | |
import nltk | |
import numpy as np | |
import tflearn | |
import random | |
import json | |
import pickle | |
from nltk.tokenize import word_tokenize | |
from nltk.stem.lancaster import LancasterStemmer | |
from transformers import AutoTokenizer, AutoModelForSequenceClassification, pipeline | |
import googlemaps | |
import folium | |
import torch | |
# Suppress TensorFlow warnings | |
os.environ["CUDA_VISIBLE_DEVICES"] = "-1" | |
os.environ["TF_CPP_MIN_LOG_LEVEL"] = "3" | |
# Download necessary NLTK resources | |
nltk.download("punkt") | |
stemmer = LancasterStemmer() | |
# Load intents and chatbot training data | |
with open("intents.json") as file: | |
intents_data = json.load(file) | |
with open("data.pickle", "rb") as f: | |
words, labels, training, output = pickle.load(f) | |
# Build the chatbot model | |
net = tflearn.input_data(shape=[None, len(training[0])]) | |
net = tflearn.fully_connected(net, 8) | |
net = tflearn.fully_connected(net, 8) | |
net = tflearn.fully_connected(net, len(output[0]), activation="softmax") | |
net = tflearn.regression(net) | |
chatbot_model = tflearn.DNN(net) | |
chatbot_model.load("MentalHealthChatBotmodel.tflearn") | |
# Hugging Face sentiment and emotion models | |
tokenizer_sentiment = AutoTokenizer.from_pretrained("cardiffnlp/twitter-roberta-base-sentiment") | |
model_sentiment = AutoModelForSequenceClassification.from_pretrained("cardiffnlp/twitter-roberta-base-sentiment") | |
tokenizer_emotion = AutoTokenizer.from_pretrained("j-hartmann/emotion-english-distilroberta-base") | |
model_emotion = AutoModelForSequenceClassification.from_pretrained("j-hartmann/emotion-english-distilroberta-base") | |
# Google Maps API Client | |
gmaps = googlemaps.Client(key=os.getenv("GOOGLE_API_KEY")) | |
# Helper Functions | |
def bag_of_words(s, words): | |
"""Convert user input to bag-of-words vector.""" | |
bag = [0] * len(words) | |
s_words = word_tokenize(s) | |
s_words = [stemmer.stem(word.lower()) for word in s_words if word.isalnum()] | |
for se in s_words: | |
for i, w in enumerate(words): | |
if w == se: | |
bag[i] = 1 | |
return np.array(bag) | |
def generate_chatbot_response(message, history): | |
"""Generate chatbot response and maintain conversation history.""" | |
history = history or [] | |
try: | |
result = chatbot_model.predict([bag_of_words(message, words)]) | |
tag = labels[np.argmax(result)] | |
response = "I'm sorry, I didn't understand that. π€" | |
for intent in intents_data["intents"]: | |
if intent["tag"] == tag: | |
response = random.choice(intent["responses"]) | |
break | |
except Exception as e: | |
response = f"Error: {e}" | |
history.append((message, response)) | |
return history, response | |
def analyze_sentiment(user_input): | |
"""Analyze sentiment and map to emojis.""" | |
inputs = tokenizer_sentiment(user_input, return_tensors="pt") | |
with torch.no_grad(): | |
outputs = model_sentiment(**inputs) | |
sentiment_class = torch.argmax(outputs.logits, dim=1).item() | |
sentiment_map = ["Negative π", "Neutral π", "Positive π"] | |
return f"Sentiment: {sentiment_map[sentiment_class]}" | |
def detect_emotion(user_input): | |
"""Detect emotions based on input.""" | |
pipe = pipeline("text-classification", model=model_emotion, tokenizer=tokenizer_emotion) | |
result = pipe(user_input) | |
emotion = result[0]["label"].lower().strip() | |
emotion_map = { | |
"joy": "Joy π", | |
"anger": "Anger π ", | |
"sadness": "Sadness π’", | |
"fear": "Fear π¨", | |
"surprise": "Surprise π²", | |
"neutral": "Neutral π", | |
} | |
return emotion_map.get(emotion, "Unknown π€"), emotion | |
def generate_suggestions(emotion): | |
"""Return relevant suggestions based on detected emotions.""" | |
emotion_key = emotion.lower() | |
suggestions = { | |
"joy": [ | |
["Relaxation Techniques", "https://www.helpguide.org/mental-health/meditation/mindful-breathing-meditation"], | |
["Dealing with Stress", "https://www.helpguide.org/mental-health/anxiety/tips-for-dealing-with-anxiety"], | |
["Emotional Wellness Toolkit", "https://www.nih.gov/health-information/emotional-wellness-toolkit"], | |
["Relaxation Video", "https://youtu.be/m1vaUGtyo-A"], | |
], | |
"anger": [ | |
["Emotional Wellness Toolkit", "https://www.nih.gov/health-information/emotional-wellness-toolkit"], | |
["Stress Management Tips", "https://www.health.harvard.edu/health-a-to-z"], | |
["Dealing with Anger", "https://www.helpguide.org/mental-health/anxiety/tips-for-dealing-with-anxiety"], | |
["Relaxation Video", "https://youtu.be/MIc299Flibs"], | |
], | |
"fear": [ | |
["Mindfulness Practices", "https://www.helpguide.org/mental-health/meditation/mindful-breathing-meditation"], | |
["Coping with Anxiety", "https://www.helpguide.org/mental-health/anxiety/tips-for-dealing-with-anxiety"], | |
["Emotional Wellness Toolkit", "https://www.nih.gov/health-information/emotional-wellness-toolkit"], | |
["Relaxation Video", "https://youtu.be/yGKKz185M5o"], | |
], | |
"sadness": [ | |
["Emotional Wellness Toolkit", "https://www.nih.gov/health-information/emotional-wellness-toolkit"], | |
["Dealing with Anxiety", "https://www.helpguide.org/mental-health/anxiety/tips-for-dealing-with-anxiety"], | |
["Relaxation Video", "https://youtu.be/-e-4Kx5px_I"], | |
], | |
"surprise": [ | |
["Managing Stress", "https://www.health.harvard.edu/health-a-to-z"], | |
["Coping Strategies", "https://www.helpguide.org/mental-health/anxiety/tips-for-dealing-with-anxiety"], | |
["Relaxation Video", "https://youtu.be/m1vaUGtyo-A"], | |
], | |
} | |
# Format the output to include HTML anchor tags | |
formatted_suggestions = [ | |
[title, f'<a href="{link}" target="_blank">{link}</a>'] for title, link in suggestions.get(emotion_key, [["No specific suggestions available.", "#"]]) | |
] | |
return formatted_suggestions | |
def get_health_professionals_and_map(location, query): | |
"""Search nearby healthcare professionals using Google Maps API.""" | |
try: | |
if not location or not query: | |
return [], "" # Return empty list if inputs are missing | |
geo_location = gmaps.geocode(location) | |
if geo_location: | |
lat, lng = geo_location[0]["geometry"]["location"].values() | |
places_result = gmaps.places_nearby(location=(lat, lng), radius=10000, keyword=query)["results"] | |
professionals = [] | |
map_ = folium.Map(location=(lat, lng), zoom_start=13) | |
for place in places_result: | |
# Use a list of values to append each professional | |
professionals.append([place['name'], place.get('vicinity', 'No address provided')]) | |
folium.Marker( | |
location=[place["geometry"]["location"]["lat"], place["geometry"]["location"]["lng"]], | |
popup=f"{place['name']}" | |
).add_to(map_) | |
return professionals, map_._repr_html_() | |
return [], "" # Return empty list if no professionals found | |
except Exception as e: | |
return [], "" # Return empty list on exception | |
# Main Application Logic | |
def app_function(user_input, location, query, history): | |
chatbot_history, _ = generate_chatbot_response(user_input, history) | |
sentiment_result = analyze_sentiment(user_input) | |
emotion_result, cleaned_emotion = detect_emotion(user_input) | |
suggestions = generate_suggestions(cleaned_emotion) | |
professionals, map_html = get_health_professionals_and_map(location, query) | |
return chatbot_history, sentiment_result, emotion_result, suggestions, professionals, map_html | |
# CSS Styling | |
custom_css = """ | |
body { | |
font-family: 'Roboto', sans-serif; | |
background-color: #3c6487; /* Set the background color */ | |
color: white; | |
} | |
h1 { | |
background: #ffffff; | |
color: #000000; | |
border-radius: 8px; | |
padding: 10px; | |
font-weight: bold; | |
text-align: center; | |
font-size: 2.5rem; | |
} | |
textarea, input { | |
background: transparent; | |
color: black; | |
border: 2px solid orange; | |
padding: 8px; | |
font-size: 1rem; | |
caret-color: black; | |
outline: none; | |
border-radius: 8px; | |
} | |
textarea:focus, input:focus { | |
background: transparent; | |
color: black; | |
border: 2px solid orange; | |
outline: none; | |
} | |
textarea:hover, input:hover { | |
background: transparent; | |
color: black; | |
border: 2px solid orange; | |
} | |
.df-container { | |
background: white; | |
color: black; | |
border: 2px solid orange; | |
border-radius: 10px; | |
padding: 10px; | |
font-size: 14px; | |
max-height: 400px; | |
height: auto; | |
overflow-y: auto; | |
} | |
#suggestions-title { | |
text-align: center !important; /* Ensure the centering is applied */ | |
font-weight: bold !important; /* Ensure bold is applied */ | |
color: white !important; /* Ensure color is applied */ | |
font-size: 4.2rem !important; /* Ensure font size is applied */ | |
margin-bottom: 20px !important; /* Ensure margin is applied */ | |
} | |
/* Style for the submit button */ | |
.gr-button { | |
background-color: #ae1c93; /* Set the background color to #ae1c93 */ | |
box-shadow: 0 4px 6px rgba(0, 0, 0, 0.1), 0 2px 4px rgba(0, 0, 0, 0.06); | |
transition: background-color 0.3s ease; | |
} | |
.gr-button:hover { | |
background-color: #8f167b; | |
} | |
.gr-button:active { | |
background-color: #7f156b; | |
} | |
""" | |
# Gradio Application | |
with gr.Blocks(css=custom_css) as app: | |
gr.HTML("<h1>π Well-Being Companion</h1>") | |
with gr.Row(): | |
user_input = gr.Textbox(label="Please Enter Your Message Here") | |
location = gr.Textbox(label="Please Enter Your Current Location Here") | |
query = gr.Textbox(label="Please Enter Which Health Professional You Want To Search Nearby") | |
submit = gr.Button(value="Submit", variant="primary") | |
chatbot = gr.Chatbot(label="Chat History") | |
sentiment = gr.Textbox(label="Detected Sentiment") | |
emotion = gr.Textbox(label="Detected Emotion") | |
# Adding Suggestions Title with Styled Markdown (Centered and Bold) | |
gr.Markdown("Suggestions", elem_id="suggestions-title") | |
suggestions = gr.DataFrame(headers=["Title", "Link"]) # Table for suggestions | |
professionals = gr.DataFrame(label="Nearby Health Professionals", headers=["Name", "Address"]) # Changed to DataFrame | |
map_html = gr.HTML(label="Interactive Map") | |
submit.click( | |
app_function, | |
inputs=[user_input, location, query, chatbot], | |
outputs=[chatbot, sentiment, emotion, suggestions, professionals, map_html], | |
) | |
app.launch() |