Spaces:
Sleeping
Sleeping
ASledziewska
commited on
Commit
•
5038c7a
1
Parent(s):
39b8eba
add files
Browse files- app.py +145 -0
- bm25_retreive_question.py +138 -0
- llm_response_generator.py +152 -0
- mental_health_model.pkl +3 -0
- q_learning_chatbot.py +82 -0
- requirements.txt +11 -0
- xgb_mental_health.py +77 -0
app.py
ADDED
@@ -0,0 +1,145 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
|
2 |
+
import os
|
3 |
+
import pandas as pd
|
4 |
+
import streamlit as st
|
5 |
+
from q_learning_chatbot import QLearningChatbot
|
6 |
+
from xgb_mental_health import MentalHealthClassifier
|
7 |
+
from bm25_retreive_question import QuestionRetriever
|
8 |
+
from llm_response_generator import LLLResponseGenerator
|
9 |
+
|
10 |
+
# Streamlit UI
|
11 |
+
st.title("FOMO Fix - RL-based Mental Health Assistant")
|
12 |
+
|
13 |
+
# Define states and actions
|
14 |
+
states = ['Negative', 'Moderately Negative', 'Neutral', 'Moderately Positive', 'Positive']
|
15 |
+
actions = ['encouragement', 'empathy']
|
16 |
+
|
17 |
+
# Initialize Q-learning chatbot and mental health classifier
|
18 |
+
chatbot = QLearningChatbot(states, actions)
|
19 |
+
|
20 |
+
# Initialize MentalHealthClassifier
|
21 |
+
data_path = "data.csv"
|
22 |
+
tokenizer_model_name = "nlptown/bert-base-multilingual-uncased-sentiment"
|
23 |
+
mental_classifier_model_path = 'mental_health_model.pkl'
|
24 |
+
mental_classifier = MentalHealthClassifier(data_path, mental_classifier_model_path)
|
25 |
+
|
26 |
+
|
27 |
+
# Function to display Q-table
|
28 |
+
def display_q_table(q_values, states, actions):
|
29 |
+
q_table_dict = {'State': states}
|
30 |
+
for i, action in enumerate(actions):
|
31 |
+
q_table_dict[action] = q_values[:, i]
|
32 |
+
|
33 |
+
q_table_df = pd.DataFrame(q_table_dict)
|
34 |
+
return q_table_df
|
35 |
+
|
36 |
+
|
37 |
+
# Initialize memory
|
38 |
+
if 'entered_text' not in st.session_state:
|
39 |
+
st.session_state.entered_text = []
|
40 |
+
if 'entered_mood' not in st.session_state:
|
41 |
+
st.session_state.entered_mood = []
|
42 |
+
|
43 |
+
# Collect user input
|
44 |
+
user_message = st.text_input("Type your message here:")
|
45 |
+
|
46 |
+
# Take user input
|
47 |
+
if user_message:
|
48 |
+
st.session_state.entered_text.append(user_message)
|
49 |
+
|
50 |
+
# Detect mental condition
|
51 |
+
mental_classifier.initialize_tokenizer(tokenizer_model_name)
|
52 |
+
mental_classifier.preprocess_data()
|
53 |
+
predicted_mental_category = mental_classifier.predict_category(user_message)
|
54 |
+
print("Predicted mental health condition:", predicted_mental_category)
|
55 |
+
# st.subheader("🛑 " + f"{predicted_mental_category.capitalize()}")
|
56 |
+
|
57 |
+
# Retrieve question
|
58 |
+
retriever = QuestionRetriever()
|
59 |
+
question = retriever.get_response(user_message, predicted_mental_category)
|
60 |
+
# st.write(question)
|
61 |
+
|
62 |
+
# Detect sentiment
|
63 |
+
user_sentiment = chatbot.detect_sentiment(user_message)
|
64 |
+
# Update mood history / moode_trend
|
65 |
+
chatbot.update_mood_history()
|
66 |
+
mood_trend = chatbot.check_mood_trend()
|
67 |
+
|
68 |
+
# Define rewards
|
69 |
+
if user_sentiment in ["Positive", "Moderately Positive"]:
|
70 |
+
if mood_trend == "increased":
|
71 |
+
reward = +0.8
|
72 |
+
else: # decresed
|
73 |
+
reward = -0.3
|
74 |
+
|
75 |
+
else:
|
76 |
+
if mood_trend == "increased":
|
77 |
+
reward = +1
|
78 |
+
else:
|
79 |
+
reward = -1
|
80 |
+
|
81 |
+
print(f"mood_trend - sentiment - reward: {mood_trend} - {user_sentiment} - 🛑{reward}🛑 -- (a)")
|
82 |
+
|
83 |
+
# Update Q-values
|
84 |
+
chatbot.update_q_values(user_sentiment, chatbot.actions[0], reward, user_sentiment)
|
85 |
+
|
86 |
+
# Get recommended action based on the updated Q-values
|
87 |
+
ai_tone = chatbot.get_action(user_sentiment)
|
88 |
+
print(ai_tone)
|
89 |
+
|
90 |
+
|
91 |
+
|
92 |
+
#--------------
|
93 |
+
# LLM Response Generator
|
94 |
+
HUGGINGFACEHUB_API_TOKEN = os.getenv('HUGGINGFACEHUB_API_TOKEN')
|
95 |
+
|
96 |
+
llm_model = LLLResponseGenerator()
|
97 |
+
temperature = 0.1
|
98 |
+
max_length = 128
|
99 |
+
template = """INSTRUCTIONS: {context}
|
100 |
+
|
101 |
+
Respond to the user with a tone of {ai_tone}.
|
102 |
+
|
103 |
+
Question asked to the user: {question}
|
104 |
+
|
105 |
+
Response by the user: {user_text}
|
106 |
+
Response;
|
107 |
+
"""
|
108 |
+
context = "You are a mental health supporting non-medical assistant. Provide some advice and ask a relevant question back to the user."
|
109 |
+
|
110 |
+
|
111 |
+
llm_response = llm_model.llm_inference(
|
112 |
+
model_type="huggingface",
|
113 |
+
question=question,
|
114 |
+
prompt_template=template,
|
115 |
+
context=context,
|
116 |
+
ai_tone=ai_tone,
|
117 |
+
questionnaire=predicted_mental_category,
|
118 |
+
user_text=user_message,
|
119 |
+
temperature=temperature,
|
120 |
+
max_length=max_length,
|
121 |
+
)
|
122 |
+
|
123 |
+
|
124 |
+
st.write(f"{llm_response}")
|
125 |
+
st.write(f"{question}")
|
126 |
+
|
127 |
+
st.subheader("Behind the Scence - What AI is doing:")
|
128 |
+
st.write(f"- User Tone: {user_sentiment}, Possibly {predicted_mental_category.capitalize()}")
|
129 |
+
st.write(f"- AI Tone: {ai_tone.capitalize()}")
|
130 |
+
# st.write(f"Question: {question}")
|
131 |
+
|
132 |
+
|
133 |
+
# Display results
|
134 |
+
# st.subheader(f"{user_sentiment.capitalize()}")
|
135 |
+
# st.write("->" + f"{ai_tone.capitalize()}")
|
136 |
+
# st.write(f"Mood {chatbot.check_mood_trend()}")
|
137 |
+
# st.write(f"{ai_tone.capitalize()}, {chatbot.check_mood_trend()}")
|
138 |
+
|
139 |
+
# Display Q-table
|
140 |
+
st.dataframe(display_q_table(chatbot.q_values, states, actions))
|
141 |
+
|
142 |
+
# Display mood history
|
143 |
+
# st.subheader("Mood History (Recent 5):")
|
144 |
+
# for mood_now in reversed(chatbot.mood_history[-5:]): #st.session_state.entered_mood[-5:], chatbot.mood_history[-5:]): #st.session_state.entered_text[-5:]
|
145 |
+
# st.write(f"{mood_now}")
|
bm25_retreive_question.py
ADDED
@@ -0,0 +1,138 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
from rank_bm25 import BM25Okapi
|
2 |
+
import nltk
|
3 |
+
from nltk.tokenize import word_tokenize
|
4 |
+
|
5 |
+
# Download NLTK data for tokenization
|
6 |
+
nltk.download('punkt')
|
7 |
+
|
8 |
+
class QuestionRetriever:
|
9 |
+
def __init__(self):
|
10 |
+
self.depression_questions = [
|
11 |
+
"How often have you felt persistently low in mood or sad for most of the day?",
|
12 |
+
"How often have you lost interest or pleasure in activities you used to enjoy?",
|
13 |
+
"How often have you experienced significant changes in appetite or weight (up or down)?",
|
14 |
+
"How often have you had trouble sleeping or sleeping too much?",
|
15 |
+
"How often have you felt restless or slowed down most of the time?",
|
16 |
+
"How often have you felt worthless or excessively guilty, even for minor things?",
|
17 |
+
"How often have you had difficulty thinking, concentrating, or making decisions?",
|
18 |
+
"How often have you had recurrent thoughts of death or suicide?",
|
19 |
+
"How often have you felt hopeless or like there's no point in life?",
|
20 |
+
"How often have you felt isolated or withdrawn from others due to your mood?",
|
21 |
+
"How often have you felt down, depressed, or hopeless?",
|
22 |
+
"How often have you had little interest or pleasure in doing things over the past two weeks?",
|
23 |
+
"Have you experienced changes in your appetite or weight due to feeling depressed in the last two weeks?",
|
24 |
+
"How often have you had trouble falling asleep, staying asleep, or sleeping too much because of feeling depressed?",
|
25 |
+
"Have you felt tired or had little energy most days over the past two weeks due to depression?",
|
26 |
+
"How often have you felt bad about yourself or that you are a failure or have let yourself or your family down in the last two weeks?",
|
27 |
+
"Have you had trouble concentrating on things like reading, watching TV, or engaging in conversations due to feeling depressed?",
|
28 |
+
"How often have you thought that you would be better off dead or hurting yourself in some way over the past two weeks?",
|
29 |
+
"Do you feel restless or slowed down physically most days because of feeling depressed in the last two weeks?",
|
30 |
+
"How often have you found it difficult to make decisions or felt indecisive due to feeling depressed recently?",
|
31 |
+
"How often do you feel sad or hopeless?",
|
32 |
+
"Do you have trouble getting out of bed or motivating yourself to do things?",
|
33 |
+
"Have you experienced a loss of interest in activities or hobbies?",
|
34 |
+
"Do you feel like you're not good enough or that you've failed at things?",
|
35 |
+
"Have you noticed any changes in your appetite or sleep patterns?",
|
36 |
+
"Do you feel like you're isolated from others or that you don't have any support?",
|
37 |
+
"Have you experienced any thoughts of self-harm or suicide?",
|
38 |
+
"Do you feel like you're stuck in a rut or that you can't see a way out of your current situation?",
|
39 |
+
"Have you noticed any physical symptoms like fatigue or loss of energy?",
|
40 |
+
"Have you considered seeking professional help for your depression?"
|
41 |
+
]
|
42 |
+
|
43 |
+
self.adhd_questions = [
|
44 |
+
"How often do you find yourself having trouble focusing on tasks or activities?",
|
45 |
+
"How often do you easily get sidetracked by noises, movements, or unrelated thoughts?",
|
46 |
+
"How often do you have difficulty finishing tasks or following through on instructions?",
|
47 |
+
"How often do you feel restless or fidgety, often unable to sit still for long periods?",
|
48 |
+
"How often do you talk excessively or blurt out things before thinking?",
|
49 |
+
"How often do you struggle with waiting for your turn or interrupting others frequently?",
|
50 |
+
"How often do you lose things you need for work or school (keys, phone, etc.)?",
|
51 |
+
"How often are you forgetful or disorganized?",
|
52 |
+
"How often do you have difficulty planning ahead or organizing tasks?",
|
53 |
+
"How often do you have difficulty controlling strong emotions or impulsive behaviors?",
|
54 |
+
"How often have you found it difficult to pay attention to details or make careless mistakes in your work or activities due to ADHD symptoms?",
|
55 |
+
"How often have you had trouble staying focused on tasks or activities like work, school, or hobbies because of ADHD symptoms in the last two weeks?",
|
56 |
+
"Have you experienced difficulties in organizing tasks and activities, such as messy workspaces or missed deadlines, because of ADHD recently?",
|
57 |
+
"How often have you avoided or been reluctant to engage in tasks that require sustained mental effort due to ADHD symptoms over the past two weeks?",
|
58 |
+
"Have you been forgetful in daily activities, such as missing appointments or losing items, because of ADHD symptoms in the last two weeks?",
|
59 |
+
"How often have you felt restless or fidgety in situations where it is inappropriate due to ADHD symptoms recently?",
|
60 |
+
"Do you find it challenging to engage in leisure activities quietly or feel driven by a motor due to ADHD most days?",
|
61 |
+
"How often have you interrupted others or blurted out answers before questions have been completed because of ADHD symptoms over the past two weeks?",
|
62 |
+
"Have you had difficulties waiting your turn or remaining seated in situations where it is expected due to ADHD symptoms recently?",
|
63 |
+
"How often have you felt impatient or had difficulty engaging in activities quietly due to ADHD symptoms in the last two weeks?",
|
64 |
+
"How often do you have trouble sitting still or staying focused?",
|
65 |
+
"Do you have trouble following instructions or completing tasks?",
|
66 |
+
"Have you noticed any difficulty with organization or time management?",
|
67 |
+
"Do you find yourself easily distracted or forgetful?",
|
68 |
+
"Have you experienced any impulsivity or difficulty with self-control?",
|
69 |
+
"Do you have trouble waiting your turn or behaving in line with social rules?",
|
70 |
+
"Have you noticed any changes in your mood or emotional state?",
|
71 |
+
"Do you have trouble with word retrieval or difficulty finding the right words?",
|
72 |
+
"Have you experienced any difficulty with reading or comprehension?",
|
73 |
+
"Have you considered seeking professional help for your ADHD?"
|
74 |
+
]
|
75 |
+
|
76 |
+
self.anxiety_questions = [
|
77 |
+
"How often have you been feeling excessive worry or nervousness, even about everyday things?",
|
78 |
+
"How often do you experience physical symptoms like racing heart, sweating, or shortness of breath when feeling anxious?",
|
79 |
+
"How often do you encounter certain situations or triggers that cause you significant anxiety?",
|
80 |
+
"How often do you find yourself avoiding places or activities due to anxiety?",
|
81 |
+
"How often have you had trouble sleeping or concentrating because of anxious thoughts?",
|
82 |
+
"How often do you feel a constant need to be in control or have things perfect to avoid anxiety?",
|
83 |
+
"How often do you have intrusive thoughts that are difficult to stop?",
|
84 |
+
"How often do you experience sudden feelings of intense fear or panic (panic attacks)?",
|
85 |
+
"How often has your anxiety significantly impacted your daily life or relationships?",
|
86 |
+
"How much does anxiety interfere with your daily life?",
|
87 |
+
"How often have you felt nervous, anxious, or on edge?",
|
88 |
+
"How often have you found it difficult to stop or control worrying thoughts in the last two weeks?",
|
89 |
+
"Have you experienced restlessness or felt keyed up or on edge due to anxiety in the past two weeks?",
|
90 |
+
"How often have you felt easily fatigued or had difficulty concentrating because of anxiety recently?",
|
91 |
+
"Have you noticed irritability or muscle tension as a result of feeling anxious over the past two weeks?",
|
92 |
+
"How often have you had trouble falling asleep, staying asleep, or restless sleep due to anxiety in the last two weeks?",
|
93 |
+
"Do you find yourself easily startled or feeling on edge most days because of anxiety?",
|
94 |
+
"How often have you experienced physical symptoms like sweating, trembling, or a racing heart due to anxiety recently?",
|
95 |
+
"Have you found it challenging to relax or felt restless most days because of anxiety in the past two weeks?",
|
96 |
+
"How often have you felt a sense of impending doom or danger because of anxiety over the past two weeks?",
|
97 |
+
"How often do you feel nervous or on edge?",
|
98 |
+
"Do you have trouble relaxing or controlling your worries?",
|
99 |
+
"Have you experienced a racing or irregular heartbeat?",
|
100 |
+
"Do you feel like you're constantly on guard or on high alert?",
|
101 |
+
"Have you noticed any physical symptoms like trembling or sweating?",
|
102 |
+
"Do you feel like you're having trouble concentrating or making decisions?",
|
103 |
+
"Have you experienced any feelings of detachment or disconnection from others?",
|
104 |
+
"Do you feel like you're having trouble sleeping or experiencing vivid dreams?",
|
105 |
+
"Have you noticed any changes in your appetite or eating habits?",
|
106 |
+
"Have you considered seeking professional help for your anxiety?"
|
107 |
+
]
|
108 |
+
|
109 |
+
def get_response(self, user_query, predicted_mental_category):
|
110 |
+
if predicted_mental_category == "depression":
|
111 |
+
knowledge_base = self.depression_questions
|
112 |
+
elif predicted_mental_category == "adhd":
|
113 |
+
knowledge_base = self.adhd_questions
|
114 |
+
elif predicted_mental_category == "anxiety":
|
115 |
+
knowledge_base = self.anxiety_questions
|
116 |
+
else:
|
117 |
+
print("Sorry, I didn't understand that.")
|
118 |
+
|
119 |
+
tokenized_docs = [word_tokenize(doc.lower()) for doc in knowledge_base] # Ensure lowercase for consistency
|
120 |
+
bm25 = BM25Okapi(tokenized_docs)
|
121 |
+
tokenized_query = word_tokenize(user_query.lower()) # Ensure lowercase for consistency
|
122 |
+
doc_scores = bm25.get_scores(tokenized_query)
|
123 |
+
|
124 |
+
# Get the index of the most relevant document
|
125 |
+
most_relevant_doc_index = doc_scores.argmax()
|
126 |
+
|
127 |
+
# Fetch the corresponding response from the knowledge base
|
128 |
+
response = knowledge_base[most_relevant_doc_index]
|
129 |
+
return response
|
130 |
+
|
131 |
+
if __name__ == "__main__":
|
132 |
+
knowledge_base = depression_questions
|
133 |
+
|
134 |
+
model = QuestionRetriever(knowledge_base)
|
135 |
+
user_input = input("User: ")
|
136 |
+
|
137 |
+
response = model.get_response(user_input)
|
138 |
+
print("Chatbot:", response)
|
llm_response_generator.py
ADDED
@@ -0,0 +1,152 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
import os
|
2 |
+
from langchain_community.llms import HuggingFaceHub
|
3 |
+
from langchain_community.llms import OpenAI
|
4 |
+
# from langchain.llms import HuggingFaceHub, OpenAI
|
5 |
+
from langchain.chains import LLMChain
|
6 |
+
from langchain.prompts import PromptTemplate
|
7 |
+
import warnings
|
8 |
+
|
9 |
+
warnings.filterwarnings("ignore")
|
10 |
+
|
11 |
+
class LLLResponseGenerator():
|
12 |
+
|
13 |
+
def __init__(self):
|
14 |
+
print("initialized")
|
15 |
+
|
16 |
+
|
17 |
+
def llm_inference(
|
18 |
+
self,
|
19 |
+
model_type: str,
|
20 |
+
question: str,
|
21 |
+
prompt_template: str,
|
22 |
+
context: str,
|
23 |
+
ai_tone: str,
|
24 |
+
questionnaire: str,
|
25 |
+
user_text: str,
|
26 |
+
openai_model_name: str = "",
|
27 |
+
hf_repo_id: str = "tiiuae/falcon-7b-instruct",
|
28 |
+
temperature: float = 0.1,
|
29 |
+
max_length: int = 128,
|
30 |
+
) -> str:
|
31 |
+
"""Call HuggingFace/OpenAI model for inference
|
32 |
+
|
33 |
+
Given a question, prompt_template, and other parameters, this function calls the relevant
|
34 |
+
API to fetch LLM inference results.
|
35 |
+
|
36 |
+
Args:
|
37 |
+
model_str: Denotes the LLM vendor's name. Can be either 'huggingface' or 'openai'
|
38 |
+
question: The question to be asked to the LLM.
|
39 |
+
prompt_template: The prompt template itself.
|
40 |
+
context: Instructions for the LLM.
|
41 |
+
ai_tone: Can be either empathy, encouragement or suggest medical help.
|
42 |
+
questionnaire: Can be either depression, anxiety or adhd.
|
43 |
+
user_text: Response given by the user.
|
44 |
+
hf_repo_id: The Huggingface model's repo_id
|
45 |
+
temperature: (Default: 1.0). Range: Float (0.0-100.0). The temperature of the sampling operation. 1 means regular sampling, 0 means always take the highest score, 100.0 is getting closer to uniform probability.
|
46 |
+
max_length: Integer to define the maximum length in tokens of the output summary.
|
47 |
+
|
48 |
+
Returns:
|
49 |
+
A Python string which contains the inference result.
|
50 |
+
|
51 |
+
HuggingFace repo_id examples:
|
52 |
+
- google/flan-t5-xxl
|
53 |
+
- tiiuae/falcon-7b-instruct
|
54 |
+
|
55 |
+
"""
|
56 |
+
prompt = PromptTemplate(
|
57 |
+
template=prompt_template,
|
58 |
+
input_variables=[
|
59 |
+
"context",
|
60 |
+
"ai_tone",
|
61 |
+
"questionnaire",
|
62 |
+
"question",
|
63 |
+
"user_text",
|
64 |
+
],
|
65 |
+
)
|
66 |
+
|
67 |
+
if model_type == "openai":
|
68 |
+
# https://api.python.langchain.com/en/stable/llms/langchain.llms.openai.OpenAI.html#langchain.llms.openai.OpenAI
|
69 |
+
llm = OpenAI(
|
70 |
+
model_name=openai_model_name, temperature=temperature, max_tokens=max_length
|
71 |
+
)
|
72 |
+
llm_chain = LLMChain(prompt=prompt, llm=llm)
|
73 |
+
return llm_chain.run(
|
74 |
+
context=context,
|
75 |
+
ai_tone=ai_tone,
|
76 |
+
questionnaire=questionnaire,
|
77 |
+
question=question,
|
78 |
+
user_text=user_text,
|
79 |
+
)
|
80 |
+
|
81 |
+
elif model_type == "huggingface":
|
82 |
+
# https://python.langchain.com/docs/integrations/llms/huggingface_hub
|
83 |
+
llm = HuggingFaceHub(
|
84 |
+
repo_id=hf_repo_id,
|
85 |
+
model_kwargs={"temperature": temperature, "max_length": max_length},
|
86 |
+
)
|
87 |
+
|
88 |
+
llm_chain = LLMChain(prompt=prompt, llm=llm)
|
89 |
+
response = llm_chain.run(
|
90 |
+
context=context,
|
91 |
+
ai_tone=ai_tone,
|
92 |
+
questionnaire=questionnaire,
|
93 |
+
question=question,
|
94 |
+
user_text=user_text,
|
95 |
+
)
|
96 |
+
|
97 |
+
# Extracting only the response part from the output
|
98 |
+
response_start_index = response.find("Response;")
|
99 |
+
return response[response_start_index + len("Response;"):].strip()
|
100 |
+
|
101 |
+
else:
|
102 |
+
print(
|
103 |
+
"Please use the correct value of model_type parameter: It can have a value of either openai or huggingface"
|
104 |
+
)
|
105 |
+
|
106 |
+
|
107 |
+
if __name__ == "__main__":
|
108 |
+
# Please ensure you have a .env file available with 'HUGGINGFACEHUB_API_TOKEN' and 'OPENAI_API_KEY' values.
|
109 |
+
HUGGINGFACEHUB_API_TOKEN = os.getenv('HUGGINGFACEHUB_API_TOKEN')
|
110 |
+
|
111 |
+
context = "You are a mental health supporting non-medical assistant. DO NOT PROVIDE any medical advice with conviction."
|
112 |
+
|
113 |
+
ai_tone = "EMPATHY"
|
114 |
+
questionnaire = "ADHD"
|
115 |
+
question = (
|
116 |
+
"How often do you find yourself having trouble focusing on tasks or activities?"
|
117 |
+
)
|
118 |
+
user_text = "I feel distracted all the time, and I am never able to finish"
|
119 |
+
|
120 |
+
# The user may have signs of {questionnaire}.
|
121 |
+
template = """INSTRUCTIONS: {context}
|
122 |
+
|
123 |
+
Respond to the user with a tone of {ai_tone}.
|
124 |
+
|
125 |
+
Question asked to the user: {question}
|
126 |
+
|
127 |
+
Response by the user: {user_text}
|
128 |
+
|
129 |
+
Provide some advice and ask a relevant question back to the user.
|
130 |
+
|
131 |
+
Response;
|
132 |
+
"""
|
133 |
+
|
134 |
+
temperature = 0.1
|
135 |
+
max_length = 128
|
136 |
+
|
137 |
+
model = LLLResponseGenerator()
|
138 |
+
|
139 |
+
|
140 |
+
llm_response = model.llm_inference(
|
141 |
+
model_type="huggingface",
|
142 |
+
question=question,
|
143 |
+
prompt_template=template,
|
144 |
+
context=context,
|
145 |
+
ai_tone=ai_tone,
|
146 |
+
questionnaire=questionnaire,
|
147 |
+
user_text=user_text,
|
148 |
+
temperature=temperature,
|
149 |
+
max_length=max_length,
|
150 |
+
)
|
151 |
+
|
152 |
+
print(llm_response)
|
mental_health_model.pkl
ADDED
@@ -0,0 +1,3 @@
|
|
|
|
|
|
|
|
|
1 |
+
version https://git-lfs.github.com/spec/v1
|
2 |
+
oid sha256:4b5f0ccc2395bdc10566011fb24594c84da14ed0a9e9d38365f09d63e9692515
|
3 |
+
size 601587
|
q_learning_chatbot.py
ADDED
@@ -0,0 +1,82 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
import os
|
2 |
+
import numpy as np
|
3 |
+
import pandas as pd
|
4 |
+
from xgb_mental_health import MentalHealthClassifier
|
5 |
+
import pickle
|
6 |
+
import streamlit as st
|
7 |
+
from transformers import AutoTokenizer, AutoModelForSequenceClassification
|
8 |
+
from torch.nn.functional import softmax
|
9 |
+
import torch
|
10 |
+
|
11 |
+
|
12 |
+
|
13 |
+
class QLearningChatbot:
|
14 |
+
def __init__(self, states, actions, learning_rate=0.1, discount_factor=0.9):
|
15 |
+
self.states = states
|
16 |
+
self.actions = actions
|
17 |
+
self.learning_rate = learning_rate
|
18 |
+
self.discount_factor = discount_factor
|
19 |
+
self.q_values = np.random.rand(len(states), len(actions))
|
20 |
+
self.mood = "Neutral"
|
21 |
+
self.mood_history = []
|
22 |
+
self.mood_history_int = []
|
23 |
+
self.tokenizer = AutoTokenizer.from_pretrained("nlptown/bert-base-multilingual-uncased-sentiment")
|
24 |
+
self.bert_sentiment_model_path = "bert_sentiment.pkl"
|
25 |
+
self.bert_sentiment_model = self.load_model() if os.path.exists(self.bert_sentiment_model_path) else AutoModelForSequenceClassification.from_pretrained("nlptown/bert-base-multilingual-uncased-sentiment")
|
26 |
+
|
27 |
+
|
28 |
+
def detect_sentiment(self, input_text):
|
29 |
+
# Encode the text
|
30 |
+
encoded_input = self.tokenizer(input_text, return_tensors='pt', truncation=True, max_length=512)
|
31 |
+
|
32 |
+
# Perform inference
|
33 |
+
with torch.no_grad():
|
34 |
+
output = self.bert_sentiment_model(**encoded_input)
|
35 |
+
|
36 |
+
# Process the output (softmax to get probabilities)
|
37 |
+
scores = softmax(output.logits, dim=1)
|
38 |
+
|
39 |
+
# Map scores to sentiment labels
|
40 |
+
labels = ['Negative', 'Moderately Negative', 'Neutral', 'Moderately Positive', 'Positive']
|
41 |
+
scores = scores.numpy().flatten()
|
42 |
+
scores_dict = {label: score for label, score in zip(labels, scores)}
|
43 |
+
highest_sentiment = max(scores_dict, key=scores_dict.get)
|
44 |
+
self.mood = highest_sentiment
|
45 |
+
return highest_sentiment
|
46 |
+
|
47 |
+
def get_action(self, current_state):
|
48 |
+
current_state_index = self.states.index(current_state)
|
49 |
+
# print(np.argmax(self.q_values[current_state_index, :]))
|
50 |
+
return self.actions[np.argmax(self.q_values[current_state_index, :])]
|
51 |
+
|
52 |
+
def update_q_values(self, current_state, action, reward, next_state):
|
53 |
+
# print(f"state-reward: {current_state} - {reward} -- (b)")
|
54 |
+
current_state_index = self.states.index(current_state)
|
55 |
+
action_index = self.actions.index(action)
|
56 |
+
next_state_index = self.states.index(next_state)
|
57 |
+
|
58 |
+
current_q_value = self.q_values[current_state_index, action_index]
|
59 |
+
max_next_q_value = np.max(self.q_values[next_state_index, :])
|
60 |
+
|
61 |
+
new_q_value = current_q_value + self.learning_rate * (reward + self.discount_factor * max_next_q_value - current_q_value)
|
62 |
+
self.q_values[current_state_index, action_index] = new_q_value
|
63 |
+
|
64 |
+
def update_mood_history(self):
|
65 |
+
st.session_state.entered_mood.append(self.mood)
|
66 |
+
self.mood_history = st.session_state.entered_mood
|
67 |
+
return self.mood_history
|
68 |
+
|
69 |
+
def check_mood_trend(self):
|
70 |
+
mood_dict = {'Negative': 1, 'Moderately Negative': 2, 'Neutral': 3, 'Moderately Positive': 4, 'Positive': 5}
|
71 |
+
|
72 |
+
if len(self.mood_history) >= 2:
|
73 |
+
self.mood_history_int = [mood_dict.get(x) for x in self.mood_history]
|
74 |
+
recent_moods = self.mood_history_int[-2:]
|
75 |
+
if recent_moods[-1] > recent_moods[-2]:
|
76 |
+
return 'increased'
|
77 |
+
elif recent_moods[-1] < recent_moods[-2]:
|
78 |
+
return 'decreased'
|
79 |
+
else:
|
80 |
+
return 'unchanged'
|
81 |
+
else:
|
82 |
+
return 'unchanged'
|
requirements.txt
ADDED
@@ -0,0 +1,11 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
streamlit
|
2 |
+
numpy
|
3 |
+
pandas
|
4 |
+
textblob
|
5 |
+
xgboost
|
6 |
+
transformers
|
7 |
+
scikit-learn
|
8 |
+
torch
|
9 |
+
rank_bm25
|
10 |
+
langchain_community
|
11 |
+
langchain
|
xgb_mental_health.py
ADDED
@@ -0,0 +1,77 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
import os.path
|
2 |
+
import pickle
|
3 |
+
import pandas as pd
|
4 |
+
from transformers import AutoTokenizer
|
5 |
+
from sklearn.model_selection import train_test_split
|
6 |
+
from sklearn.feature_extraction.text import CountVectorizer
|
7 |
+
from xgboost import XGBClassifier
|
8 |
+
from sklearn.preprocessing import LabelEncoder
|
9 |
+
|
10 |
+
class MentalHealthClassifier:
|
11 |
+
def __init__(self, data_path, model_path):
|
12 |
+
self.data = pd.read_csv(data_path, skip_blank_lines=True)
|
13 |
+
self.data['category'] = ['anxiety' if x == 'axienty' else x for x in self.data['category']]
|
14 |
+
self.data.dropna(subset=['text'], inplace=True)
|
15 |
+
self.data.dropna(subset=['clean_text'], inplace=True)
|
16 |
+
self.data_selected = self.data[['clean_text', 'category']]
|
17 |
+
self.df = pd.DataFrame(self.data_selected)
|
18 |
+
self.label_encoder = LabelEncoder()
|
19 |
+
self.df['category_encoded'] = self.label_encoder.fit_transform(self.df['category'])
|
20 |
+
self.tokenizer = None
|
21 |
+
self.vectorizer = CountVectorizer()
|
22 |
+
self.model_path = model_path
|
23 |
+
self.model = self.load_model() if os.path.exists(model_path) else XGBClassifier()
|
24 |
+
|
25 |
+
def preprocess_data(self):
|
26 |
+
tokenized_texts = [self.tokenizer.tokenize(text, padding=True, truncation=True) for text in self.df['clean_text']]
|
27 |
+
X = self.vectorizer.fit_transform([' '.join(tokens) for tokens in tokenized_texts]).toarray()
|
28 |
+
return X, self.df['category_encoded']
|
29 |
+
|
30 |
+
def train_model(self, X, y):
|
31 |
+
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.2, random_state=42)
|
32 |
+
self.model.fit(X_train, y_train)
|
33 |
+
y_pred = self.model.predict(X_test)
|
34 |
+
return y_test, y_pred
|
35 |
+
|
36 |
+
def predict_category(self, input_text):
|
37 |
+
if self.tokenizer is None:
|
38 |
+
raise ValueError("Tokenizer not initialized. Call 'initialize_tokenizer' first.")
|
39 |
+
tokenized_input = self.tokenizer.tokenize(input_text, padding=True, truncation=True)
|
40 |
+
input_feature_vector = self.vectorizer.transform([' '.join(tokenized_input)]).toarray()
|
41 |
+
predicted_category_encoded = self.model.predict(input_feature_vector)
|
42 |
+
predicted_category = self.label_encoder.inverse_transform(predicted_category_encoded)
|
43 |
+
return predicted_category[0]
|
44 |
+
|
45 |
+
def initialize_tokenizer(self, model_name):
|
46 |
+
self.model_name = model_name
|
47 |
+
self.tokenizer = AutoTokenizer.from_pretrained(self.model_name)
|
48 |
+
|
49 |
+
def save_model(self):
|
50 |
+
print("saving model...to pickle...")
|
51 |
+
with open(self.model_path, 'wb') as f:
|
52 |
+
pickle.dump(self.model, f)
|
53 |
+
|
54 |
+
def load_model(self):
|
55 |
+
print("loading model...from pickle...")
|
56 |
+
with open(self.model_path, 'rb') as f:
|
57 |
+
return pickle.load(f)
|
58 |
+
|
59 |
+
if __name__ == "__main__":
|
60 |
+
tokenizer_model_name = "nlptown/bert-base-multilingual-uncased-sentiment"
|
61 |
+
data_path = 'data.csv'
|
62 |
+
model_path = 'mental_health_model.pkl'
|
63 |
+
mental_classifier = MentalHealthClassifier(data_path, model_path)
|
64 |
+
|
65 |
+
if not os.path.exists(model_path):
|
66 |
+
mental_classifier.initialize_tokenizer(tokenizer_model_name)
|
67 |
+
X, y = mental_classifier.preprocess_data()
|
68 |
+
y_test, y_pred = mental_classifier.train_model(X, y)
|
69 |
+
mental_classifier.save_model()
|
70 |
+
else:
|
71 |
+
mental_classifier.load_model()
|
72 |
+
mental_classifier.initialize_tokenizer(tokenizer_model_name) # Ensure tokenizer is initialized if loading model from pickle
|
73 |
+
mental_classifier.preprocess_data()
|
74 |
+
|
75 |
+
# input_text = "I feel anxiety whenever i am doing nothing."
|
76 |
+
# predicted_category = mental_classifier.predict_category(input_text)
|
77 |
+
# print("Predicted mental health condition:", predicted_category)
|