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", 'Visit'],
["Dealing with Stress", 'Visit'],
["Emotional Wellness Toolkit", 'Visit'],
["Relaxation Video", 'Watch'],
],
"anger": [
["Emotional Wellness Toolkit", 'Visit'],
["Stress Management Tips", 'Visit'],
["Dealing with Anger", 'Visit'],
["Relaxation Video", 'Watch'],
],
"fear": [
["Mindfulness Practices", 'Visit'],
["Coping with Anxiety", 'Visit'],
["Emotional Wellness Toolkit", 'Visit'],
["Relaxation Video", 'Watch'],
],
"sadness": [
["Emotional Wellness Toolkit", 'Visit'],
["Dealing with Anxiety", 'Visit'],
["Relaxation Video", 'Watch'],
],
"surprise": [
["Managing Stress", 'Visit'],
["Coping Strategies", 'Visit'],
["Relaxation Video", 'Watch'],
],
}
return suggestions.get(emotion_key, [["No specific suggestions available.", ""]])
def get_health_professionals_and_map(location, query):
"""Search nearby healthcare professionals using Google Maps API."""
try:
if not location or not query:
return ["Please provide both location and query."], ""
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:
professionals.append(f"{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 ["No professionals found for the given location."], ""
except Exception as e:
return [f"An error occurred: {e}"], ""
# 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: linear-gradient(135deg, #0d0d0d, #ff5722);
color: white;
}
h1 {
text-align: center;
color: white;
font-size: 36px;
font-weight: bold;
}
textarea {
width: 100%;
height: 150px;
background-color: #333333;
color: white;
border: 1px solid #ff5722;
border-radius: 5px;
font-size: 16px;
padding: 10px;
}
button {
background-color: #ff5722;
color: white;
font-size: 16px;
padding: 10px 20px;
border-radius: 5px;
border: none;
cursor: pointer;
}
button:hover {
background-color: #e64a19;
}
"""
# Gradio Interface Setup
with gr.Blocks(css=custom_css) as app:
gr.Markdown("# 🌟 Mental Health Chatbot App")
with gr.Row():
chatbot_output = gr.Chatbot(label="Chat History", elem_id="chatbox")
user_input = gr.Textbox(label="Your Message", placeholder="Type something...", interactive=True)
gr.Markdown("### Sentiment, Emotion, and Suggestions")
sentiment_output = gr.Textbox(label="Sentiment Analysis")
emotion_output = gr.Textbox(label="Emotion Detected")
suggestions_output = gr.DataFrame(headers=["Title", "Link"], label="Suggestions")
gr.Markdown("### Locate Health Professionals (Optional)")
location_input = gr.Textbox(label="Your Location")
query_input = gr.Textbox(label="Query (e.g., therapist, clinic)", placeholder="Type something...", interactive=True)
professionals_output = gr.DataFrame(headers=["Professional", "Address"], label="Nearby Professionals")
map_output = gr.HTML(label="Map of Professionals")
submit_button = gr.Button(value="Submit", elem_id="submit-btn")
submit_button.click(
app_function,
inputs=[user_input, location_input, query_input, chatbot_output],
outputs=[chatbot_output, sentiment_output, emotion_output, suggestions_output, professionals_output, map_output]
)
# Run the App
app.launch(share=True)