Alinadi98 commited on
Commit
af9f72d
·
verified ·
1 Parent(s): b3e9322

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +284 -59
app.py CHANGED
@@ -1,64 +1,289 @@
1
  import gradio as gr
 
 
 
 
2
  from huggingface_hub import InferenceClient
3
 
4
- """
5
- For more information on `huggingface_hub` Inference API support, please check the docs: https://huggingface.co/docs/huggingface_hub/v0.22.2/en/guides/inference
6
- """
7
- client = InferenceClient("HuggingFaceH4/zephyr-7b-beta")
8
-
9
-
10
- def respond(
11
- message,
12
- history: list[tuple[str, str]],
13
- system_message,
14
- max_tokens,
15
- temperature,
16
- top_p,
17
- ):
18
- messages = [{"role": "system", "content": system_message}]
19
-
20
- for val in history:
21
- if val[0]:
22
- messages.append({"role": "user", "content": val[0]})
23
- if val[1]:
24
- messages.append({"role": "assistant", "content": val[1]})
25
-
26
- messages.append({"role": "user", "content": message})
27
-
28
- response = ""
29
-
30
- for message in client.chat_completion(
31
- messages,
32
- max_tokens=max_tokens,
33
- stream=True,
34
- temperature=temperature,
35
- top_p=top_p,
36
- ):
37
- token = message.choices[0].delta.content
38
-
39
- response += token
40
- yield response
41
-
42
-
43
- """
44
- For information on how to customize the ChatInterface, peruse the gradio docs: https://www.gradio.app/docs/chatinterface
45
- """
46
- demo = gr.ChatInterface(
47
- respond,
48
- additional_inputs=[
49
- gr.Textbox(value="You are a friendly Chatbot.", label="System message"),
50
- gr.Slider(minimum=1, maximum=2048, value=512, step=1, label="Max new tokens"),
51
- gr.Slider(minimum=0.1, maximum=4.0, value=0.7, step=0.1, label="Temperature"),
52
- gr.Slider(
53
- minimum=0.1,
54
- maximum=1.0,
55
- value=0.95,
56
- step=0.05,
57
- label="Top-p (nucleus sampling)",
58
- ),
59
- ],
60
- )
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
61
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
62
 
63
- if __name__ == "__main__":
64
- demo.launch()
 
1
  import gradio as gr
2
+ import pandas as pd
3
+ import numpy as np
4
+ import matplotlib.pyplot as plt
5
+ import seaborn as sns
6
  from huggingface_hub import InferenceClient
7
 
8
+ # WHOQOL-BREF questions (Same as before)
9
+ questions = [
10
+ {"id": "Q1", "text": "How would you rate your quality of life?", "domain": "Overall QOL", "scores": ["Very poor", "Poor", "Neither poor nor good", "Good", "Very good"]},
11
+ {"id": "Q2", "text": "How satisfied are you with your health?", "domain": "Overall Health", "scores": ["Very dissatisfied", "Dissatisfied", "Neither satisfied nor dissatisfied", "Satisfied", "Very satisfied"]},
12
+ {"id": "Q3", "text": "To what extent do you feel that physical pain prevents you from doing what you need to do?", "domain": "Physical", "scores": ["Not at all", "A little", "A moderate amount", "Very much", "An extreme amount"], "reverse": True},
13
+ {"id": "Q4", "text": "How much do you need any medical treatment to function in your daily life?", "domain": "Physical", "scores": ["Not at all", "A little", "A moderate amount", "Very much", "An extreme amount"], "reverse": True},
14
+ {"id": "Q5", "text": "How much do you enjoy life?", "domain": "Psychological", "scores": ["Not at all", "A little", "A moderate amount", "Very much", "An extreme amount"]},
15
+ {"id": "Q6", "text": "To what extent do you feel your life to be meaningful?", "domain": "Psychological", "scores": ["Not at all", "A little", "A moderate amount", "Very much", "An extreme amount"]},
16
+ {"id": "Q7", "text": "How well are you able to concentrate?", "domain": "Psychological", "scores": ["Not at all", "A little", "A moderate amount", "Very much", "Extremely"]},
17
+ {"id": "Q8", "text": "How safe do you feel in your daily life?", "domain": "Environment", "scores": ["Not at all", "A little", "A moderate amount", "Very much", "Extremely"]},
18
+ {"id": "Q9", "text": "How healthy is your physical environment?", "domain": "Environment", "scores": ["Not at all", "A little", "A moderate amount", "Very much", "Extremely"]},
19
+ {"id": "Q10", "text": "Do you have enough energy for everyday life?", "domain": "Physical", "scores": ["Not at all", "A little", "Moderately", "Mostly", "Completely"]},
20
+ {"id": "Q11", "text": "Are you able to accept your bodily appearance?", "domain": "Psychological", "scores": ["Not at all", "A little", "Moderately", "Mostly", "Completely"]},
21
+ {"id": "Q12", "text": "Have you enough money to meet your needs?", "domain": "Environment", "scores": ["Not at all", "A little", "Moderately", "Mostly", "Completely"]},
22
+ {"id": "Q13", "text": "How available to you is the information that you need in your day-to-day life?", "domain": "Environment", "scores": ["Not at all", "A little", "Moderately", "Mostly", "Completely"]},
23
+ {"id": "Q14", "text": "To what extent do you have the opportunity for leisure activities?", "domain": "Environment", "scores": ["Not at all", "A little", "Moderately", "Mostly", "Completely"]},
24
+ {"id": "Q15", "text": "How well are you able to get around?", "domain": "Physical", "scores": ["Very poor", "Poor", "Neither poor nor good", "Good", "Very good"]},
25
+ {"id": "Q16", "text": "How satisfied are you with your sleep?", "domain": "Physical", "scores": ["Very dissatisfied", "Dissatisfied", "Neither satisfied nor dissatisfied", "Satisfied", "Very satisfied"]},
26
+ {"id": "Q17", "text": "How satisfied are you with your ability to perform your daily living activities?", "domain": "Physical", "scores": ["Very dissatisfied", "Dissatisfied", "Neither satisfied nor dissatisfied", "Satisfied", "Very satisfied"]},
27
+ {"id": "Q18", "text": "How satisfied are you with your capacity for work?", "domain": "Physical", "scores": ["Very dissatisfied", "Dissatisfied", "Neither satisfied nor dissatisfied", "Satisfied", "Very satisfied"]},
28
+ {"id": "Q19", "text": "How satisfied are you with yourself?", "domain": "Psychological", "scores": ["Very dissatisfied", "Dissatisfied", "Neither satisfied nor dissatisfied", "Satisfied", "Very satisfied"]},
29
+ {"id": "Q20", "text": "How satisfied are you with your personal relationships?", "domain": "Social", "scores": ["Very dissatisfied", "Dissatisfied", "Neither satisfied nor dissatisfied", "Satisfied", "Very satisfied"]},
30
+ {"id": "Q21", "text": "How satisfied are you with your sex life?", "domain": "Social", "scores": ["Very dissatisfied", "Dissatisfied", "Neither satisfied nor dissatisfied", "Satisfied", "Very satisfied"]},
31
+ {"id": "Q22", "text": "How satisfied are you with the support you get from your friends?", "domain": "Social", "scores": ["Very dissatisfied", "Dissatisfied", "Neither satisfied nor dissatisfied", "Satisfied", "Very satisfied"]},
32
+ {"id": "Q23", "text": "How satisfied are you with the conditions of your living place?", "domain": "Environment", "scores": ["Very dissatisfied", "Dissatisfied", "Neither satisfied nor dissatisfied", "Satisfied", "Very satisfied"]},
33
+ {"id": "Q24", "text": "How satisfied are you with your access to health services?", "domain": "Environment", "scores": ["Very dissatisfied", "Dissatisfied", "Neither satisfied nor dissatisfied", "Satisfied", "Very satisfied"]},
34
+ {"id": "Q25", "text": "How satisfied are you with your transport?", "domain": "Environment", "scores": ["Very dissatisfied", "Dissatisfied", "Neither satisfied nor dissatisfied", "Satisfied", "Very satisfied"]},
35
+ {"id": "Q26", "text": "How often do you have negative feelings such as blue mood, despair, anxiety, depression?", "domain": "Psychological", "scores": ["Never", "Seldom", "Quite often", "Very often", "Always"], "reverse": True}
36
+ ]
37
+
38
+ # Domain compositions and transformation formula (Same as before)
39
+ domain_info = {
40
+ "Physical": {
41
+ "questions": ["Q3", "Q4", "Q10", "Q15", "Q16", "Q17", "Q18"],
42
+ "transform": lambda raw: (raw - 7) * (100/28)
43
+ },
44
+ "Psychological": {
45
+ "questions": ["Q5", "Q6", "Q7", "Q11", "Q19", "Q26"],
46
+ "transform": lambda raw: (raw - 6) * (100/24)
47
+ },
48
+ "Social": {
49
+ "questions": ["Q20", "Q21", "Q22"],
50
+ "transform": lambda raw: (raw - 3) * (100/12)
51
+ },
52
+ "Environment": {
53
+ "questions": ["Q8", "Q9", "Q12", "Q13", "Q14", "Q23", "Q24", "Q25"],
54
+ "transform": lambda raw: (raw - 8) * (100/32)
55
+ },
56
+ "Overall QOL": {
57
+ "questions": ["Q1"],
58
+ "transform": lambda raw: (raw - 1) * (100/4)
59
+ },
60
+ "Overall Health": {
61
+ "questions": ["Q2"],
62
+ "transform": lambda raw: (raw - 1) * (100/4)
63
+ }
64
+ }
65
+
66
+ # Map domain names to full names for display (Same as before)
67
+ domain_full_names = {
68
+ "Physical": "Physical Health",
69
+ "Psychological": "Psychological Well-being",
70
+ "Social": "Social Relationships",
71
+ "Environment": "Environment",
72
+ "Overall QOL": "Overall Quality of Life",
73
+ "Overall Health": "Overall Health Satisfaction"
74
+ }
75
+
76
+ # Define interpretation ranges and interventions (Same as before)
77
+ interpretation_ranges = {
78
+ "Physical Health": {
79
+ "high_range": 70,
80
+ "medium_range": (50, 69),
81
+ "low_range": 49,
82
+ "high_inference": "Good physical well-being, minimal limitations, good energy and mobility.",
83
+ "medium_inference": "Mild to moderate physical limitations, some pain, or reduced energy.",
84
+ "low_inference": "Significant physical health limitations, pain, fatigue, poor mobility.",
85
+ "high_intervention": "Maintain a healthy lifestyle, regular exercise, balanced nutrition.",
86
+ "medium_intervention": "Increase physical activity, improve sleep, manage minor pain.",
87
+ "low_intervention": "Medical intervention, physical therapy, chronic disease management."
88
+ },
89
+ "Psychological Health": {
90
+ "high_range": 75,
91
+ "medium_range": (50, 74),
92
+ "low_range": 49,
93
+ "high_inference": "Strong emotional resilience, positive self-esteem, low anxiety or stress.",
94
+ "medium_inference": "Moderate psychological health, occasional stress, some mood fluctuations.",
95
+ "low_inference": "High emotional distress, anxiety, depression, low self-worth.",
96
+ "high_intervention": "Continue positive mental health practices, social engagement.",
97
+ "medium_intervention": "Use stress reduction techniques, engage in self-care routines.",
98
+ "low_intervention": "Psychological counseling, cognitive behavioral therapy, medication if needed."
99
+ },
100
+ "Social Relationships": {
101
+ "high_range": 70,
102
+ "medium_range": (50, 69),
103
+ "low_range": 49,
104
+ "high_inference": "Strong social connections, good interpersonal support, high satisfaction.",
105
+ "medium_inference": "Moderate social interactions, may experience loneliness or minor conflicts.",
106
+ "low_inference": "Weak social relationships, lack of support, loneliness, or isolation.",
107
+ "high_intervention": "Sustain social connections, participate in group/community activities.",
108
+ "medium_intervention": "Strengthen personal relationships, seek social support groups.",
109
+ "low_intervention": "Social integration programs, mental health support, relationship therapy."
110
+ },
111
+ "Environment": {
112
+ "high_range": 70,
113
+ "medium_range": (50, 69),
114
+ "low_range": 49,
115
+ "high_inference": "Safe and stable environment, access to resources and healthcare, financial security.",
116
+ "medium_inference": "Some dissatisfaction with living conditions, financial constraints, or safety concerns.",
117
+ "low_inference": "Unstable living conditions, financial stress, poor healthcare access, safety concerns.",
118
+ "high_intervention": "Maintain financial stability, ensure continuous access to healthcare.",
119
+ "medium_intervention": "Identify key environmental issues, seek financial or housing support.",
120
+ "low_intervention": "Government or NGO assistance for financial/housing needs, healthcare access."
121
+ }
122
+ }
123
+
124
+ # Initialize the InferenceClient
125
+ client = InferenceClient("HuggingFaceH4/zephyr-7b-beta") # Replace with a different model if desired
126
+
127
+
128
+ # Function to get interpretation from the LLM
129
+ def get_llm_interpretation(domain, score, interpretation_ranges):
130
+ if domain not in interpretation_ranges:
131
+ return "No interpretation available."
132
+
133
+ range_info = interpretation_ranges[domain]
134
+
135
+ if score >= range_info["high_range"]:
136
+ inference = range_info["high_inference"]
137
+ intervention = range_info["high_intervention"]
138
+ level = "High"
139
+ elif range_info["medium_range"][0] <= score <= range_info["medium_range"][1]:
140
+ inference = range_info["medium_inference"]
141
+ intervention = range_info["medium_intervention"]
142
+ level = "Medium"
143
+ else:
144
+ inference = range_info["low_inference"]
145
+ intervention = range_info["low_intervention"]
146
+ level = "Low"
147
+
148
+ prompt = f"""
149
+ Based on the WHOQOL-BREF assessment results for {domain}, the score is {score}, which is categorized as {level}.
150
+ The inference is: {inference}
151
+ Suggested intervention: {intervention}
152
+
153
+ Provide a more detailed and personalized interpretation, including potential causes and specific recommendations.
154
+
155
+ Response should be concise, empathetic, and helpful.
156
+ """
157
+
158
+ try:
159
+ # Call the InferenceClient
160
+ interpretation = client.text_generation(prompt, max_new_tokens=200) # Adjust max_new_tokens as needed
161
+ return interpretation
162
+ except Exception as e:
163
+ return f"Error getting interpretation from LLM: {e}"
164
+
165
+
166
+ # Function to calculate domain scores (Same as before)
167
+ def calculate_scores(responses):
168
+ domain_scores = {}
169
+
170
+ for domain, info in domain_info.items():
171
+ domain_questions = info["questions"]
172
+ total_score = 0
173
+
174
+ for q_id in domain_questions:
175
+ q_index = next((i for i, q in enumerate(questions) if q["id"] == q_id), None)
176
+ if q_index is not None and responses.get(q_id) is not None:
177
+ if questions[q_index].get("reverse", False):
178
+ total_score += 6 - responses[q_id]
179
+ else:
180
+ total_score += responses[q_id]
181
+
182
+ transformed_score = info["transform"](total_score)
183
+ domain_scores[domain] = round(transformed_score, 2)
184
+
185
+ return domain_scores
186
+
187
+
188
+ # Function to interpret the score range
189
+ def interpret_score(domain, score):
190
+ if domain not in interpretation_ranges:
191
+ return "Unknown", "No interpretation available."
192
 
193
+ range_info = interpretation_ranges[domain]
194
+ high_range = range_info["high_range"]
195
+ medium_range = range_info["medium_range"]
196
+ low_range = range_info["low_range"]
197
+
198
+ if score >= high_range:
199
+ return (
200
+ "High",
201
+ f"{range_info['high_inference']} {range_info['high_intervention']}"
202
+ )
203
+ elif range_info["medium_range"][0] <= score <= range_info["medium_range"][1]:
204
+ return (
205
+ "Medium",
206
+ f"{range_info['medium_inference']} {range_info['medium_intervention']}"
207
+ )
208
+ else:
209
+ return (
210
+ "Low",
211
+ f"{range_info['low_inference']} {range_info['low_intervention']}"
212
+ )
213
+
214
+ # Define the Gradio interface
215
+ def whoqol_assessment(*responses): # *args to take variable number of responses
216
+
217
+ # Map responses to question IDs
218
+ responses_dict = {q["id"]: int(r) for q, r in zip(questions, responses)} # responses from gradio are strings, need convert to int
219
+
220
+ # Calculate scores
221
+ scores = calculate_scores(responses_dict)
222
+
223
+ if scores is None:
224
+ return "Please answer all questions." # Error message if not all questions are answered
225
+
226
+ # Prepare data for radar chart
227
+ main_domains = ["Physical", "Psychological", "Social", "Environment"]
228
+ main_scores = [scores[domain] for domain in main_domains]
229
+
230
+ # Create radar chart (using Matplotlib)
231
+ fig, ax = plt.subplots(figsize=(6, 6), subplot_kw=dict(polar=True))
232
+
233
+ # Angle for each domain
234
+ angles = np.linspace(0, 2 * np.pi, len(main_domains), endpoint=False).tolist()
235
+ angles += angles[:1] # Close the loop
236
+
237
+ # Add scores (with loop closure)
238
+ values = main_scores + [main_scores[0]]
239
+
240
+ # Plot and fill the radar chart
241
+ ax.plot(angles, values, 'o-', linewidth=2, color='blue')
242
+ ax.fill(angles, values, color='blue', alpha=0.25)
243
+
244
+ # Add labels
245
+ domain_labels = [domain_full_names[domain] for domain in main_domains]
246
+ ax.set_xticks(angles[:-1])
247
+ ax.set_xticklabels(domain_labels, fontsize=10)
248
+
249
+ # Set y-axis limits
250
+ ax.set_ylim(0, 100)
251
+ ax.set_yticks([0, 25, 50, 75, 100])
252
+ ax.set_yticklabels(['0', '25', '50', '75', '100'], fontsize=8) # Smaller font
253
+
254
+ # Add grid lines
255
+ ax.grid(True, linestyle='-', alpha=0.7)
256
+
257
+ # Add title
258
+ ax.set_title('WHOQOL-BREF Domain Scores', size=12, y=1.1) # Smaller Title
259
+
260
+ # Detailed Interpretations and store them in text
261
+ interpretations_text = ""
262
+ for domain in ["Physical", "Psychological", "Social", "Environment", "Overall QOL", "Overall Health"]:
263
+ score = scores[domain]
264
+ llm_interpretation = get_llm_interpretation(domain_full_names[domain], score, interpretation_ranges)
265
+ interpretations_text += f"**{domain_full_names[domain]}**: {llm_interpretation}\n\n"
266
+
267
+ return fig, interpretations_text
268
+
269
+
270
+ # Create Gradio inputs
271
+ inputs = []
272
+ for q in questions:
273
+ inputs.append(gr.Radio(choices=q["scores"], label=q["text"])) # Use Radio instead of Checkbox
274
+
275
+ # Create Gradio outputs
276
+ radar_chart_output = gr.Plot()
277
+ interpretations_output = gr.Markdown() # markdown, because I used "**" in text. This format allow to view text in bold format.
278
+
279
+ # Create Gradio interface
280
+ iface = gr.Interface(
281
+ fn=whoqol_assessment,
282
+ inputs=inputs,
283
+ outputs=[radar_chart_output, interpretations_output],
284
+ title="WHOQOL-BREF Quality of Life Assessment",
285
+ description="Complete the questionnaire to receive your quality of life assessment across different domains.",
286
+ )
287
 
288
+ # Launch the Gradio interface
289
+ iface.launch()