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() | |