Spaces:
Sleeping
Sleeping
import gradio as gr | |
import nltk | |
import numpy as np | |
import tflearn | |
import random | |
import json | |
import pickle | |
import torch | |
from nltk.tokenize import word_tokenize | |
from nltk.stem.lancaster import LancasterStemmer | |
from transformers import AutoTokenizer, AutoModelForSequenceClassification, pipeline | |
import requests | |
import re | |
from bs4 import BeautifulSoup | |
import time | |
import pandas as pd | |
from selenium import webdriver | |
from selenium.webdriver.chrome.options import Options | |
import chromedriver_autoinstaller | |
import os | |
import geocoder # Use geocoder to get latitude/longitude from city | |
# Ensure necessary NLTK resources are downloaded | |
nltk.download('punkt') | |
# Initialize the stemmer | |
stemmer = LancasterStemmer() | |
# Load intents.json | |
try: | |
with open("intents.json") as file: | |
data = json.load(file) | |
except FileNotFoundError: | |
raise FileNotFoundError("Error: 'intents.json' file not found. Ensure it exists in the current directory.") | |
# Load preprocessed data from pickle | |
try: | |
with open("data.pickle", "rb") as f: | |
words, labels, training, output = pickle.load(f) | |
except FileNotFoundError: | |
raise FileNotFoundError("Error: 'data.pickle' file not found. Ensure it exists and matches the model.") | |
# Build the model structure | |
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) | |
# Load the trained model | |
model = tflearn.DNN(net) | |
try: | |
model.load("MentalHealthChatBotmodel.tflearn") | |
except FileNotFoundError: | |
raise FileNotFoundError("Error: Trained model file 'MentalHealthChatBotmodel.tflearn' not found.") | |
# Function to process user input into a bag-of-words format | |
def bag_of_words(s, words): | |
bag = [0 for _ in range(len(words))] | |
s_words = word_tokenize(s) | |
s_words = [stemmer.stem(word.lower()) for word in s_words if word.lower() in words] | |
for se in s_words: | |
for i, w in enumerate(words): | |
if w == se: | |
bag[i] = 1 | |
return np.array(bag) | |
# Chat function | |
def chat(message, history, state): | |
history = history or [] | |
message = message.lower() | |
try: | |
# Predict the tag | |
results = model.predict([bag_of_words(message, words)]) | |
results_index = np.argmax(results) | |
tag = labels[results_index] | |
# Match tag with intent and choose a random response | |
for tg in data["intents"]: | |
if tg['tag'] == tag: | |
responses = tg['responses'] | |
response = random.choice(responses) | |
break | |
else: | |
response = "I'm sorry, I didn't understand that. Could you please rephrase?" | |
# Add emoticons to the response | |
emoticon_dict = { | |
"joy": "π", | |
"anger": "π‘", | |
"fear": "π¨", | |
"sadness": "π", | |
"surprise": "π²", | |
"neutral": "π" | |
} | |
# Add the emotion-related emoticon to the response | |
for tg in data["intents"]: | |
if tg['tag'] == tag: | |
emotion = tg.get('emotion', 'neutral') # Default to neutral if no emotion is defined | |
response = f"{response} {emoticon_dict.get(emotion, 'π')}" | |
break | |
history.append((message, response)) | |
# Transition to the next feature (sentiment analysis) | |
state['step'] = 2 # Move to sentiment analysis | |
except Exception as e: | |
response = f"An error occurred: {str(e)}" | |
return history, history, state | |
# Load pre-trained model and tokenizer for sentiment analysis | |
tokenizer = AutoTokenizer.from_pretrained("cardiffnlp/twitter-roberta-base-sentiment") | |
sentiment_model = AutoModelForSequenceClassification.from_pretrained("cardiffnlp/twitter-roberta-base-sentiment") | |
# Function for sentiment analysis | |
def analyze_sentiment(text, state): | |
inputs = tokenizer(text, return_tensors="pt") | |
with torch.no_grad(): | |
outputs = sentiment_model(**inputs) | |
predicted_class = torch.argmax(outputs.logits, dim=1).item() | |
sentiment = ["Negative", "Neutral", "Positive"][predicted_class] | |
# Add emoticon to sentiment | |
sentiment_emojis = { | |
"Negative": "π", | |
"Neutral": "π", | |
"Positive": "π" | |
} | |
sentiment_with_emoji = f"{sentiment} {sentiment_emojis.get(sentiment, 'π')}" | |
# Transition to emotion detection | |
state['step'] = 3 # Move to emotion detection and suggestions | |
return sentiment_with_emoji, state | |
# Load pre-trained model and tokenizer for emotion detection | |
emotion_tokenizer = AutoTokenizer.from_pretrained("j-hartmann/emotion-english-distilroberta-base") | |
emotion_model = AutoModelForSequenceClassification.from_pretrained("j-hartmann/emotion-english-distilroberta-base") | |
# Function for emotion detection and suggestions | |
def detect_emotion(text, state): | |
pipe = pipeline("text-classification", model=emotion_model, tokenizer=emotion_tokenizer) | |
result = pipe(text) | |
emotion = result[0]['label'] | |
# Provide suggestions based on detected emotion | |
suggestions = provide_suggestions(emotion) | |
# Transition to wellness professional search | |
state['step'] = 4 # Move to wellness professional search | |
return emotion, suggestions, state | |
# Suggestions based on detected emotion | |
def provide_suggestions(emotion): | |
resources = { | |
'joy': { | |
'message': "You're feeling happy! Keep up the great mood! π", | |
'articles': [ | |
"[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)" | |
], | |
'videos': "[Watch Relaxation Video](https://youtu.be/m1vaUGtyo-A)" | |
}, | |
'anger': { | |
'message': "You're feeling angry. It's okay to feel this way. Let's try to calm down. π‘", | |
'articles': [ | |
"[Emotional Wellness Toolkit](https://www.nih.gov/health-information/emotional-wellness-toolkit)", | |
"[Stress Management Tips](https://www.health.harvard.edu/health-a-to-z)" | |
], | |
'videos': "[Watch Anger Management Video](https://youtu.be/MIc299Flibs)" | |
}, | |
'fear': { | |
'message': "You're feeling fearful. Take a moment to breathe and relax. π¨", | |
'articles': [ | |
"[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)" | |
], | |
'videos': "[Watch Coping Video](https://youtu.be/yGKKz185M5o)" | |
}, | |
'sadness': { | |
'message': "You're feeling sad. It's okay to take a break. π", | |
'articles': [ | |
"[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)" | |
], | |
'videos': "[Watch Sadness Relief Video](https://youtu.be/-e-4Kx5px_I)" | |
}, | |
'surprise': { | |
'message': "You're feeling surprised. It's okay to feel neutral! π²", | |
'articles': [ | |
"[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)" | |
], | |
'videos': "[Watch Stress Relief Video](https://youtu.be/m1vaUGtyo-A)" | |
} | |
} | |
return resources.get(emotion, {'message': "Stay calm. π", 'articles': [], 'videos': []}) | |
# Function to find wellness professionals | |
def find_wellness_professionals(location, state): | |
# Geocode the location to get latitude and longitude | |
g = geocoder.osm(location) # Using OpenStreetMap's geocoding service | |
if g.ok: | |
location_coords = f"{g.lat},{g.lng}" | |
else: | |
return "Sorry, could not retrieve coordinates for the location. Please try again.", state | |
query = "therapist OR counselor OR mental health professional OR marriage and family therapist OR psychotherapist OR psychiatrist OR psychologist in " + location | |
api_key = "GOOGLE_API_KEY" # Replace with your own API key | |
radius = 50000 # 50 km radius | |
google_places_data = get_all_places(query, location_coords, radius, api_key) | |
if google_places_data: | |
df = pd.DataFrame(google_places_data, columns=[ | |
"Name", "Address", "Phone", "Rating", "Business Status", | |
"User Ratings Total", "Website", "Types", "Latitude", "Longitude", | |
"Opening Hours", "Reviews", "Email" | |
]) | |
# Display results in Gradio interface | |
if not df.empty: | |
df_html = df.to_html(classes="table table-striped", index=False) | |
return f"Found wellness professionals in your area: \n{df_html}", state | |
else: | |
return "No wellness professionals found for your location. Try another search.", state | |
else: | |
return "Sorry, there was an issue fetching data. Please try again later.", state | |
# Function to fetch places data using Google Places API | |
def get_all_places(query, location, radius, api_key): | |
url = f"https://maps.googleapis.com/maps/api/place/textsearch/json?query={query}&location={location}&radius={radius}&key={api_key}" | |
response = requests.get(url) | |
if response.status_code == 200: | |
results = response.json().get("results", []) | |
places = [] | |
for place in results: | |
name = place.get("name") | |
address = place.get("formatted_address") | |
phone = place.get("formatted_phone_number", "Not available") | |
rating = place.get("rating", "Not rated") | |
business_status = place.get("business_status", "N/A") | |
user_ratings_total = place.get("user_ratings_total", "N/A") | |
website = place.get("website", "Not available") | |
types = place.get("types", []) | |
lat, lng = place.get("geometry", {}).get("location", {}).values() | |
opening_hours = place.get("opening_hours", {}).get("weekday_text", []) | |
reviews = place.get("reviews", []) | |
email = "Not available" # Assume email is not included in the API response | |
# Adding the place data to the list | |
places.append([name, address, phone, rating, business_status, user_ratings_total, | |
website, types, lat, lng, opening_hours, reviews, email]) | |
return places | |
else: | |
return [] | |
# Gradio interface setup | |
def gradio_interface(): | |
with gr.Blocks() as demo: | |
# Set title and description | |
gr.Markdown("<h1 style='text-align: center;'>Mental Health Support Chatbot π€</h1>") | |
gr.Markdown("<p style='text-align: center;'>Get emotional well-being suggestions and find wellness professionals nearby.</p>") | |
# State to manage step transitions | |
state = gr.State({"step": 1}) | |
# Chat interface | |
with gr.Row(): | |
chatbot = gr.Chatbot(label="Chatbot") | |
user_input = gr.Textbox(placeholder="Type your message here...", label="Your Message") | |
send_button = gr.Button("Send") | |
# Output for emotion, sentiment, suggestions | |
with gr.Row(): | |
sentiment_output = gr.Textbox(label="Sentiment Analysis") | |
emotion_output = gr.Textbox(label="Emotion Detection") | |
suggestions_output = gr.Textbox(label="Suggestions") | |
# Input for location for wellness professionals | |
with gr.Row(): | |
location_input = gr.Textbox(label="Your Location (City/Region)", placeholder="Enter your city...") | |
search_button = gr.Button("Search Wellness Professionals") | |
# Button actions | |
send_button.click(chat, inputs=[user_input, chatbot, state], outputs=[chatbot, chatbot, state]) | |
user_input.submit(chat, inputs=[user_input, chatbot, state], outputs=[chatbot, chatbot, state]) | |
send_button.click(analyze_sentiment, inputs=[user_input, state], outputs=[sentiment_output, state]) | |
user_input.submit(analyze_sentiment, inputs=[user_input, state], outputs=[sentiment_output, state]) | |
send_button.click(detect_emotion, inputs=[user_input, state], outputs=[emotion_output, suggestions_output, state]) | |
user_input.submit(detect_emotion, inputs=[user_input, state], outputs=[emotion_output, suggestions_output, state]) | |
search_button.click(find_wellness_professionals, inputs=[location_input, state], outputs=[suggestions_output, state]) | |
demo.launch(debug=True) | |
# Run the Gradio interface | |
if __name__ == "__main__": | |
gradio_interface() | |