Spaces:
Sleeping
Sleeping
Update app.py
Browse files
app.py
CHANGED
@@ -1,30 +1,27 @@
|
|
1 |
import pandas as pd
|
2 |
import gradio as gr
|
3 |
-
from transformers import AutoTokenizer, AutoModelForSequenceClassification
|
4 |
from sentence_transformers import SentenceTransformer, util
|
5 |
from difflib import get_close_matches
|
6 |
import requests
|
7 |
import io
|
8 |
import torch
|
|
|
|
|
9 |
|
10 |
# GitHub Excel file URL
|
11 |
GITHUB_EXCEL_URL = "https://raw.githubusercontent.com/3Zzamt0o/HospitalData/main/Hospital%20Data%20(1).xlsx"
|
12 |
|
13 |
def load_hospital_data():
|
14 |
try:
|
15 |
-
# Fetch Excel file from GitHub
|
16 |
response = requests.get(GITHUB_EXCEL_URL)
|
17 |
-
response.raise_for_status()
|
18 |
-
|
19 |
-
# Read Excel file from the response content
|
20 |
excel_data = io.BytesIO(response.content)
|
21 |
df = pd.read_excel(excel_data)
|
22 |
-
|
23 |
print("Successfully loaded data from GitHub")
|
24 |
return df
|
25 |
except Exception as e:
|
26 |
print(f"Error loading data from GitHub: {e}")
|
27 |
-
# Fallback to default data if GitHub fetch fails
|
28 |
return pd.DataFrame({
|
29 |
'العيادات': ['عيادة الأسنان', 'عيادة الباطنة', 'عيادة العظام', 'عيادة الأطفال'],
|
30 |
'الدكتور': ['د. أحمد محمد', 'د. محمد علي', 'د. علي حسن', 'د. سارة أحمد'],
|
@@ -36,18 +33,18 @@ def load_hospital_data():
|
|
36 |
print("Loading hospital data...")
|
37 |
df = load_hospital_data()
|
38 |
|
39 |
-
# Q&A data for lab tests and equipment
|
40 |
data = {
|
41 |
"السؤال": [
|
42 |
-
"ما هي مواعيد معمل
|
43 |
-
"ما هي انواع التحاليل الموجوده و
|
44 |
-
"ماهي تحاليل صوره
|
45 |
-
"ما هي تحاليل وظائف
|
46 |
-
"ما هي تحاليل
|
47 |
-
"ما هي تحاليل
|
48 |
-
"هل يوجد حشو
|
49 |
-
"هل يوجد قياس
|
50 |
-
"هل يوجد قياس
|
51 |
],
|
52 |
"الجواب": [
|
53 |
"طول ايام الاسبوع من 9 صباحا الي 9 مسائا", "من 24 ساعه الي 48 ساعه",
|
@@ -65,23 +62,34 @@ data = {
|
|
65 |
|
66 |
qa_data = pd.DataFrame(data)
|
67 |
|
68 |
-
#
|
69 |
medical_kb = {
|
70 |
-
"الجفاف":
|
71 |
-
|
72 |
-
|
73 |
-
|
74 |
-
|
75 |
-
"
|
76 |
-
|
77 |
-
|
78 |
-
|
79 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
80 |
}
|
81 |
|
82 |
-
# Initialize models
|
83 |
-
print("Loading
|
84 |
try:
|
|
|
85 |
model_id = "aubmindlab/bert-base-arabertv2"
|
86 |
tokenizer = AutoTokenizer.from_pretrained(model_id)
|
87 |
model = AutoModelForSequenceClassification.from_pretrained(model_id)
|
@@ -91,14 +99,50 @@ except Exception as e:
|
|
91 |
tokenizer = None
|
92 |
model = None
|
93 |
|
94 |
-
print("Loading sentence transformer...")
|
95 |
try:
|
|
|
96 |
embedder = SentenceTransformer("sentence-transformers/all-MiniLM-L6-v2")
|
97 |
print("Sentence transformer loaded successfully")
|
98 |
except Exception as e:
|
99 |
print(f"Error loading sentence transformer: {e}")
|
100 |
embedder = None
|
101 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
102 |
# Prepare passages from hospital data
|
103 |
passages = []
|
104 |
for _, row in df.iterrows():
|
@@ -118,11 +162,123 @@ if embedder:
|
|
118 |
else:
|
119 |
corpus_embeddings = None
|
120 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
121 |
def check_lab_or_radiology(question):
|
122 |
-
|
|
|
123 |
if any(word in question for word in keywords):
|
124 |
try:
|
125 |
-
matches = get_close_matches(question, qa_data['السؤال'].tolist(), n=1, cutoff=0.
|
126 |
if matches:
|
127 |
matched_q = matches[0]
|
128 |
answer = qa_data[qa_data['السؤال'] == matched_q]['الجواب'].values[0]
|
@@ -132,39 +288,36 @@ def check_lab_or_radiology(question):
|
|
132 |
return None
|
133 |
|
134 |
def answer_question_from_excel(user_question, k=3):
|
135 |
-
|
136 |
-
# Check for exact symptom matches first
|
137 |
-
for symptom, advice in medical_kb.items():
|
138 |
-
if symptom in user_question:
|
139 |
-
return f"🩺 **الرد:** {advice}\n\n⚠️ **ملاحظة هامة:** هذه النصائح عامة، يرجى استشارة الطبيب للتشخيص الدقيق."
|
140 |
|
141 |
-
# Check
|
142 |
-
|
143 |
-
|
144 |
-
|
145 |
-
|
146 |
-
|
147 |
-
|
148 |
-
|
149 |
-
# Then check in qa_data for lab tests and equipment
|
150 |
qa_answer = check_lab_or_radiology(user_question)
|
151 |
if qa_answer:
|
152 |
return f"💡 **الرد:** {qa_answer}"
|
153 |
|
154 |
-
#
|
155 |
clinic_mapping = {
|
156 |
-
"عيادة الباطنة": ["باطنة", "الباطنة", "باطنه"],
|
157 |
-
"عيادة الجلدية": ["جلد", "جلدية", "الجلدية"],
|
158 |
-
"عيادة المسالك": ["مسالك", "المسالك", "مسالك بولية"],
|
159 |
-
"عيادة النساء": ["نسا", "نساء", "توليد", "ولادة"],
|
160 |
-
"عيادة الأنف والأذن": ["انف", "اذن", "حنجرة", "الأنف", "الأذن"],
|
161 |
-
"عيادة الرمد": ["رمد", "الرمد", "عيون", "العيون"],
|
162 |
-
"عيادة الأسنان": ["اسنان", "الاسنان", "الأسنان", "سنان"],
|
163 |
-
"الحضانة": ["حضان", "حضانة", "الحضانة", "حضانات"],
|
164 |
"المعمل": ["معمل", "المعمل", "تحاليل", "مختبر"],
|
165 |
-
"عيادة الأطفال": ["اطفال", "الاطفال", "الأطفال"],
|
166 |
-
"عيادة الجهاز الهضمي": ["هضم", "هضمي", "الجهاز الهضمي"],
|
167 |
-
"عيادة التخاطب": ["تخاطب", "التخاطب", "نطق"]
|
|
|
|
|
|
|
168 |
}
|
169 |
|
170 |
# Check for specific clinic mentions
|
@@ -178,21 +331,13 @@ def answer_question_from_excel(user_question, k=3):
|
|
178 |
if target_clinic:
|
179 |
clinic_info = [p for p in passages if target_clinic in p]
|
180 |
if clinic_info:
|
181 |
-
return f"🏥
|
182 |
|
183 |
# For questions about doctors or clinics
|
184 |
-
if any(word in user_question for word in ["عيادة", "عيادات", "دكتور", "دكاترة", "دكتورة", "مواعيد"]):
|
185 |
-
|
186 |
-
for clinic_type in ["الأسنان", "الباطنة", "الجلدية", "المسالك", "النساء", "الأنف", "الرمد", "الحضانة", "المعمل", "الأطفال", "الجهاز", "التخاطب"]:
|
187 |
-
if clinic_type in user_question:
|
188 |
-
clinic_info = [p for p in passages if clinic_type in p]
|
189 |
-
if clinic_info:
|
190 |
-
return f"🏥 **الرد:** \n" + "\n".join(clinic_info)
|
191 |
-
|
192 |
-
# If no specific clinic type mentioned, return all clinic information
|
193 |
-
return f"💡 **الرد:** \n" + "\n".join([p for p in passages if 'عيادة' in p])
|
194 |
|
195 |
-
#
|
196 |
if embedder and corpus_embeddings is not None:
|
197 |
try:
|
198 |
question_embedding = embedder.encode(user_question, convert_to_tensor=True)
|
@@ -205,34 +350,35 @@ def answer_question_from_excel(user_question, k=3):
|
|
205 |
except Exception as e:
|
206 |
print(f"Error in semantic search: {e}")
|
207 |
|
208 |
-
# If
|
209 |
-
|
210 |
-
|
211 |
-
|
212 |
-
|
213 |
-
|
214 |
-
if answer:
|
215 |
-
return f"💡 **الرد:** {answer}"
|
216 |
-
return answer_question_from_excel(user_question)
|
217 |
-
except Exception as e:
|
218 |
-
return f"⚠️ خطأ: {str(e)}"
|
219 |
|
220 |
def ask_question(question):
|
221 |
-
"""
|
222 |
-
Function to handle question answering with error handling
|
223 |
-
"""
|
224 |
try:
|
225 |
if not question or question.strip() == "":
|
226 |
return "❌ خطأ: السؤال مطلوب"
|
227 |
|
228 |
-
|
229 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
230 |
except Exception as e:
|
231 |
return f"❌ خطأ: {str(e)}"
|
232 |
|
233 |
-
#
|
234 |
with gr.Blocks(
|
235 |
-
title="نظام الأسئلة والأجوبة الطبي",
|
236 |
theme=gr.themes.Soft(),
|
237 |
css="""
|
238 |
.gradio-container {
|
@@ -244,24 +390,41 @@ with gr.Blocks(
|
|
244 |
background: linear-gradient(45deg, #4CAF50, #45a049);
|
245 |
color: white;
|
246 |
font-weight: bold;
|
|
|
247 |
}
|
248 |
.gr-textbox {
|
249 |
text-align: right;
|
250 |
direction: rtl;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
251 |
}
|
252 |
"""
|
253 |
) as demo:
|
254 |
|
255 |
gr.Markdown(
|
256 |
"""
|
257 |
-
# 🏥 نظام الأسئلة والأجوبة الطبي
|
258 |
-
### اسأل أي سؤال واحصل على إجابة
|
|
|
|
|
|
|
|
|
|
|
|
|
259 |
|
260 |
-
|
|
|
|
|
261 |
- 🏥 مواعيد العيادات والأطباء
|
262 |
- 🧪 التحاليل الطبية والمعمل
|
263 |
-
- 🩺 النصائح الطبية العامة
|
264 |
- 📋 أسعار الكشف والخدمات
|
|
|
265 |
""",
|
266 |
elem_id="header"
|
267 |
)
|
@@ -269,38 +432,41 @@ with gr.Blocks(
|
|
269 |
with gr.Row():
|
270 |
with gr.Column(scale=4):
|
271 |
question_input = gr.Textbox(
|
272 |
-
label="سؤالك",
|
273 |
-
placeholder="
|
274 |
-
lines=
|
275 |
text_align="right",
|
276 |
rtl=True
|
277 |
)
|
278 |
with gr.Column(scale=1):
|
279 |
submit_btn = gr.Button(
|
280 |
-
"اسأل السؤال",
|
281 |
variant="primary",
|
282 |
size="lg"
|
283 |
)
|
284 |
|
285 |
answer_output = gr.Textbox(
|
286 |
-
label="الإجابة",
|
287 |
-
lines=
|
288 |
interactive=False,
|
289 |
text_align="right",
|
290 |
rtl=True
|
291 |
)
|
292 |
|
293 |
-
#
|
294 |
gr.Examples(
|
295 |
examples=[
|
296 |
-
["ما
|
297 |
-
["
|
298 |
-
["
|
299 |
-
["
|
300 |
-
["
|
|
|
|
|
|
|
301 |
],
|
302 |
inputs=question_input,
|
303 |
-
label="أمثلة على الأسئلة"
|
304 |
)
|
305 |
|
306 |
# Set up the interaction
|
@@ -316,14 +482,23 @@ with gr.Blocks(
|
|
316 |
inputs=question_input,
|
317 |
outputs=answer_output
|
318 |
)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
319 |
|
320 |
if __name__ == "__main__":
|
321 |
-
print("Starting Hospital Q&A System...")
|
322 |
-
# Launch the Gradio app
|
323 |
demo.launch(
|
324 |
-
server_name="0.0.0.0",
|
325 |
-
server_port=7860,
|
326 |
-
share=False,
|
327 |
debug=True,
|
328 |
show_error=True
|
329 |
)
|
|
|
1 |
import pandas as pd
|
2 |
import gradio as gr
|
3 |
+
from transformers import AutoTokenizer, AutoModelForSequenceClassification, pipeline
|
4 |
from sentence_transformers import SentenceTransformer, util
|
5 |
from difflib import get_close_matches
|
6 |
import requests
|
7 |
import io
|
8 |
import torch
|
9 |
+
# No need for OpenAI import - using free Hugging Face models only
|
10 |
+
from typing import Optional
|
11 |
|
12 |
# GitHub Excel file URL
|
13 |
GITHUB_EXCEL_URL = "https://raw.githubusercontent.com/3Zzamt0o/HospitalData/main/Hospital%20Data%20(1).xlsx"
|
14 |
|
15 |
def load_hospital_data():
|
16 |
try:
|
|
|
17 |
response = requests.get(GITHUB_EXCEL_URL)
|
18 |
+
response.raise_for_status()
|
|
|
|
|
19 |
excel_data = io.BytesIO(response.content)
|
20 |
df = pd.read_excel(excel_data)
|
|
|
21 |
print("Successfully loaded data from GitHub")
|
22 |
return df
|
23 |
except Exception as e:
|
24 |
print(f"Error loading data from GitHub: {e}")
|
|
|
25 |
return pd.DataFrame({
|
26 |
'العيادات': ['عيادة الأسنان', 'عيادة الباطنة', 'عيادة العظام', 'عيادة الأطفال'],
|
27 |
'الدكتور': ['د. أحمد محمد', 'د. محمد علي', 'د. علي حسن', 'د. سارة أحمد'],
|
|
|
33 |
print("Loading hospital data...")
|
34 |
df = load_hospital_data()
|
35 |
|
36 |
+
# Enhanced Q&A data for lab tests and equipment
|
37 |
data = {
|
38 |
"السؤال": [
|
39 |
+
"ما هي مواعيد معمل التحاليل؟", "ما هي المده المستغرقه لعمل التحاليل؟",
|
40 |
+
"ما هي انواع التحاليل الموجوده و المتوفره؟", "هل يوجد تحليل صوره دم؟",
|
41 |
+
"ماهي تحاليل صوره الدم؟", "ما هي تحاليل السكر؟", "ما هي تحاليل وظائف الكبد؟",
|
42 |
+
"ما هي تحاليل وظائف الكلي؟", "ما هي تحاليل البول و البراز؟",
|
43 |
+
"ما هي تحاليل الدهون؟", "ما هي تحاليل الألتهابات و الروماتيزم؟",
|
44 |
+
"ما هي تحاليل الفيروسات؟", "ما هي تحاليل الغده الدرقيه؟",
|
45 |
+
"هل يوجد حشو اسنان؟", "هل يوجد جهاز سونار؟", "هل يوجد اجهزه تنفس اصطناعي؟",
|
46 |
+
"هل يوجد قياس نظر؟", "ما هي الاجهزه المتاحه في عياده الرمد؟",
|
47 |
+
"هل يوجد قياس ضغط؟", "هل يوجد سونار؟", "هل يوجد رسم قلب؟"
|
48 |
],
|
49 |
"الجواب": [
|
50 |
"طول ايام الاسبوع من 9 صباحا الي 9 مسائا", "من 24 ساعه الي 48 ساعه",
|
|
|
62 |
|
63 |
qa_data = pd.DataFrame(data)
|
64 |
|
65 |
+
# Expanded medical knowledge base with more comprehensive information
|
66 |
medical_kb = {
|
67 |
+
"الجفاف": {
|
68 |
+
"symptoms": ["عطش شديد", "فم جاف", "بول أصفر داكن", "إعياء", "دوخة"],
|
69 |
+
"treatment": "شرب الكثير من السوائل، تناول الأطعمة الغنية بالماء، تجنب التعرض المباشر للشمس، استشارة الطبيب إذا استمرت الأعراض",
|
70 |
+
"prevention": "شرب الماء بانتظام، تناول الفواكه والخضروات، تجنب المشروبات الكحولية والكافيين الزائد"
|
71 |
+
},
|
72 |
+
"الصداع": {
|
73 |
+
"symptoms": ["ألم في الرأس", "حساسية للضوء", "غثيان"],
|
74 |
+
"treatment": "الراحة في مكان هادئ، شرب الماء بكثرة، تناول مسكن خفيف، تجنب الضوء القوي والضوضاء",
|
75 |
+
"prevention": "النوم الكافي، تجنب التوتر، تناول وجبات منتظمة"
|
76 |
+
},
|
77 |
+
"الحمى": {
|
78 |
+
"symptoms": ["ارتفاع درجة الحرارة", "قشعريرة", "تعرق", "صداع"],
|
79 |
+
"treatment": "الراحة التامة، شرب السوائل بكثرة، خفض درجة الحرارة بالكمادات، استشارة الطبيب إذا تجاوزت 39 درجة",
|
80 |
+
"emergency": "استشارة طبية فورية إذا تجاوزت 40 درجة أو صاحبتها أعراض شديدة"
|
81 |
+
},
|
82 |
+
"السعال": {
|
83 |
+
"symptoms": ["كحة جافة أو مع بلغم", "احتقان في الحلق"],
|
84 |
+
"treatment": "شرب الماء الدافئ مع العسل، استخدام مرطب الهواء، تجنب المثيرات، الراحة وتناول الأدوية المناسبة",
|
85 |
+
"prevention": "تجنب التدخين، تجنب الغبار والملوثات"
|
86 |
+
}
|
87 |
}
|
88 |
|
89 |
+
# Initialize models
|
90 |
+
print("Loading models...")
|
91 |
try:
|
92 |
+
# Try to load Arabic BERT model
|
93 |
model_id = "aubmindlab/bert-base-arabertv2"
|
94 |
tokenizer = AutoTokenizer.from_pretrained(model_id)
|
95 |
model = AutoModelForSequenceClassification.from_pretrained(model_id)
|
|
|
99 |
tokenizer = None
|
100 |
model = None
|
101 |
|
|
|
102 |
try:
|
103 |
+
# Load sentence transformer for semantic search
|
104 |
embedder = SentenceTransformer("sentence-transformers/all-MiniLM-L6-v2")
|
105 |
print("Sentence transformer loaded successfully")
|
106 |
except Exception as e:
|
107 |
print(f"Error loading sentence transformer: {e}")
|
108 |
embedder = None
|
109 |
|
110 |
+
# Try to load free Hugging Face models for medical questions
|
111 |
+
try:
|
112 |
+
# Option 1: Arabic GPT model (best for Arabic medical questions)
|
113 |
+
llm_pipeline = pipeline(
|
114 |
+
"text-generation",
|
115 |
+
model="aubmindlab/aragpt2-base", # Free Arabic GPT model
|
116 |
+
device=0 if torch.cuda.is_available() else -1,
|
117 |
+
max_length=512,
|
118 |
+
pad_token_id=50256
|
119 |
+
)
|
120 |
+
print("Arabic GPT model loaded successfully")
|
121 |
+
except Exception as e:
|
122 |
+
print(f"Could not load Arabic model, trying alternative: {e}")
|
123 |
+
try:
|
124 |
+
# Option 2: Small English model (fallback)
|
125 |
+
llm_pipeline = pipeline(
|
126 |
+
"text-generation",
|
127 |
+
model="distilgpt2", # Small, fast, free model
|
128 |
+
device=0 if torch.cuda.is_available() else -1,
|
129 |
+
max_length=256
|
130 |
+
)
|
131 |
+
print("DistilGPT2 model loaded successfully")
|
132 |
+
except Exception as e2:
|
133 |
+
print(f"Could not load any text generation model: {e2}")
|
134 |
+
# Option 3: Try question-answering model as fallback
|
135 |
+
try:
|
136 |
+
llm_pipeline = pipeline(
|
137 |
+
"question-answering",
|
138 |
+
model="distilbert-base-cased-distilled-squad",
|
139 |
+
device=0 if torch.cuda.is_available() else -1
|
140 |
+
)
|
141 |
+
print("Question-answering model loaded as fallback")
|
142 |
+
except Exception as e3:
|
143 |
+
print(f"Warning: Could not load any LLM pipeline: {e3}")
|
144 |
+
llm_pipeline = None
|
145 |
+
|
146 |
# Prepare passages from hospital data
|
147 |
passages = []
|
148 |
for _, row in df.iterrows():
|
|
|
162 |
else:
|
163 |
corpus_embeddings = None
|
164 |
|
165 |
+
def generate_medical_advice_with_llm(question: str) -> Optional[str]:
|
166 |
+
"""
|
167 |
+
Generate medical advice using free Hugging Face models
|
168 |
+
"""
|
169 |
+
try:
|
170 |
+
if llm_pipeline:
|
171 |
+
# Check what type of pipeline we have
|
172 |
+
if hasattr(llm_pipeline, 'task') and llm_pipeline.task == 'question-answering':
|
173 |
+
# Using QA model - need context
|
174 |
+
medical_context = """
|
175 |
+
الرعاية الصحية العامة تشمل النظافة الشخصية، التغذية المتوازنة، شرب الماء بكثرة،
|
176 |
+
النوم الكافي، التمارين الرياضية المنتظمة، وتجنب التدخين. للأعراض البسيطة مثل الصداع
|
177 |
+
يمكن الراحة وشرب الماء، وللحمى يمكن استخدام الكمادات الباردة وشرب السوائل.
|
178 |
+
"""
|
179 |
+
response = llm_pipeline(question=question, context=medical_context)
|
180 |
+
return response['answer']
|
181 |
+
|
182 |
+
else:
|
183 |
+
# Using text generation model
|
184 |
+
# Create Arabic medical prompt
|
185 |
+
if "arabic" in str(llm_pipeline.model).lower() or "arab" in str(llm_pipeline.model).lower():
|
186 |
+
prompt = f"""سؤال طبي: {question}
|
187 |
+
النصيحة الطبية: """
|
188 |
+
else:
|
189 |
+
# English prompt for English models
|
190 |
+
prompt = f"""Medical Question: {question}
|
191 |
+
Medical Advice: """
|
192 |
+
|
193 |
+
# Generate response
|
194 |
+
response = llm_pipeline(
|
195 |
+
prompt,
|
196 |
+
max_length=len(prompt.split()) + 100, # Dynamic length
|
197 |
+
num_return_sequences=1,
|
198 |
+
temperature=0.7,
|
199 |
+
do_sample=True,
|
200 |
+
pad_token_id=llm_pipeline.tokenizer.eos_token_id
|
201 |
+
)
|
202 |
+
|
203 |
+
# Extract generated text
|
204 |
+
generated_text = response[0]['generated_text']
|
205 |
+
answer = generated_text.replace(prompt, "").strip()
|
206 |
+
|
207 |
+
# If it's in English, add Arabic translation note
|
208 |
+
if not any(ord(char) > 127 for char in answer): # Check if contains Arabic
|
209 |
+
answer = f"{answer}\n\n(تم إنشاء هذه الإجابة باللغة الإنجليزية من نموذج الذكاء الاصطناعي)"
|
210 |
+
|
211 |
+
return answer
|
212 |
+
|
213 |
+
except Exception as e:
|
214 |
+
print(f"Error generating LLM response: {e}")
|
215 |
+
|
216 |
+
return None
|
217 |
+
|
218 |
+
def get_comprehensive_medical_answer(question: str) -> str:
|
219 |
+
"""
|
220 |
+
Enhanced function to provide comprehensive medical answers
|
221 |
+
"""
|
222 |
+
# Check for symptoms in the enhanced knowledge base
|
223 |
+
for symptom, info in medical_kb.items():
|
224 |
+
if symptom in question or any(s in question for s in info.get("symptoms", [])):
|
225 |
+
response = f"🩺 **معلومات طبية عن {symptom}:**\n\n"
|
226 |
+
|
227 |
+
if "symptoms" in info:
|
228 |
+
response += f"**الأعراض الشائعة:** {', '.join(info['symptoms'])}\n\n"
|
229 |
+
|
230 |
+
if "treatment" in info:
|
231 |
+
response += f"**العلاج والرعاية:** {info['treatment']}\n\n"
|
232 |
+
|
233 |
+
if "prevention" in info:
|
234 |
+
response += f"**الوقاية:** {info['prevention']}\n\n"
|
235 |
+
|
236 |
+
if "emergency" in info:
|
237 |
+
response += f"⚠️ **تحذير:** {info['emergency']}\n\n"
|
238 |
+
|
239 |
+
response += "⚠️ **ملاحظة هامة:** هذه النصائح عامة، يرجى استشارة الطبيب للتشخيص الدقيق والعلاج المناسب."
|
240 |
+
return response
|
241 |
+
|
242 |
+
# If not found in knowledge base, try to generate answer with LLM
|
243 |
+
llm_response = generate_medical_advice_with_llm(question)
|
244 |
+
if llm_response:
|
245 |
+
return f"🤖 **استشارة طبية ذكية:**\n\n{llm_response}\n\n⚠️ **تنبيه:** هذه نصائح عامة من الذكاء الاصطناعي وليست بديلاً عن الاستشارة الطبية المتخصصة."
|
246 |
+
|
247 |
+
# Fallback to general medical advice
|
248 |
+
return """
|
249 |
+
🩺 **استشارة طبية عامة:**
|
250 |
+
|
251 |
+
عذراً، لا يمكنني تقديم معلومات محددة عن هذا السؤال الطبي.
|
252 |
+
|
253 |
+
**نصائح عامة للصحة:**
|
254 |
+
• اشرب كمية كافية من الماء يومياً
|
255 |
+
• تناول غذاء متوازن غني بالفواكه والخضروات
|
256 |
+
• احصل على قسط كافٍ من النوم (7-8 ساعات)
|
257 |
+
• مارس التمارين الرياضية بانتظام
|
258 |
+
• تجنب التدخين والكحول
|
259 |
+
|
260 |
+
⚠️ **للحصول على استشارة طبية دقيقة، يرجى:**
|
261 |
+
• زيارة طبيب مختص
|
262 |
+
• الاتصال بخط الاستشارة الطبية
|
263 |
+
• زيارة أقرب عيادة أو مستشفى
|
264 |
+
"""
|
265 |
+
|
266 |
+
def is_medical_question(question: str) -> bool:
|
267 |
+
"""Check if the question is medical-related"""
|
268 |
+
medical_indicators = [
|
269 |
+
"مرض", "علاج", "دواء", "ألم", "وجع", "أعراض", "صحة", "طبي", "مريض",
|
270 |
+
"اشعر", "اعاني", "يؤلمني", "يوجعني", "حمى", "صداع", "سعال", "إسهال",
|
271 |
+
"إمساك", "غثيان", "دوخة", "تعب", "إعياء", "التهاب", "عدوى", "فيروس",
|
272 |
+
"جرثومة", "حساسية", "ضغط", "سكر", "قلب", "معدة", "كبد", "كلى"
|
273 |
+
]
|
274 |
+
return any(indicator in question for indicator in medical_indicators)
|
275 |
+
|
276 |
def check_lab_or_radiology(question):
|
277 |
+
"""Enhanced lab and radiology checking"""
|
278 |
+
keywords = ['أشعة', 'تحاليل', 'رنين', 'سونار', 'تحليل', 'مختبر', 'معمل', 'فحص']
|
279 |
if any(word in question for word in keywords):
|
280 |
try:
|
281 |
+
matches = get_close_matches(question, qa_data['السؤال'].tolist(), n=1, cutoff=0.3)
|
282 |
if matches:
|
283 |
matched_q = matches[0]
|
284 |
answer = qa_data[qa_data['السؤال'] == matched_q]['الجواب'].values[0]
|
|
|
288 |
return None
|
289 |
|
290 |
def answer_question_from_excel(user_question, k=3):
|
291 |
+
"""Enhanced question answering with better medical support"""
|
|
|
|
|
|
|
|
|
292 |
|
293 |
+
# Check if it's a medical question first
|
294 |
+
if is_medical_question(user_question):
|
295 |
+
medical_answer = get_comprehensive_medical_answer(user_question)
|
296 |
+
if "استشارة طبية عامة" not in medical_answer:
|
297 |
+
return medical_answer
|
298 |
+
|
299 |
+
# Check in qa_data for lab tests and equipment
|
|
|
|
|
300 |
qa_answer = check_lab_or_radiology(user_question)
|
301 |
if qa_answer:
|
302 |
return f"💡 **الرد:** {qa_answer}"
|
303 |
|
304 |
+
# Enhanced clinic mapping with more variations
|
305 |
clinic_mapping = {
|
306 |
+
"عيادة الباطنة": ["باطنة", "الباطنة", "باطنه", "داخلية", "امراض باطنة"],
|
307 |
+
"عيادة الجلدية": ["جلد", "جلدية", "الجلدية", "امراض جلدية", "تناسلية"],
|
308 |
+
"عيادة المسالك": ["مسالك", "المسالك", "مسالك بولية", "بولية", "تناسلية"],
|
309 |
+
"عيادة النساء": ["نسا", "نساء", "توليد", "ولادة", "النساء والتوليد"],
|
310 |
+
"عيادة الأنف والأذن": ["انف", "اذن", "حنجرة", "الأنف", "الأذن", "أنف وأذن"],
|
311 |
+
"عيادة الرمد": ["رمد", "الرمد", "عيون", "العيون", "بصريات"],
|
312 |
+
"عيادة الأسنان": ["اسنان", "الاسنان", "الأسنان", "سنان", "فم"],
|
313 |
+
"الحضانة": ["حضان", "حضانة", "الحضانة", "حضانات", "عناية مركزة"],
|
314 |
"المعمل": ["معمل", "المعمل", "تحاليل", "مختبر"],
|
315 |
+
"عيادة الأطفال": ["اطفال", "الاطفال", "الأطفال", "طب الاطفال"],
|
316 |
+
"عيادة الجهاز الهضمي": ["هضم", "هضمي", "الجهاز الهضمي", "معدة", "أمعاء"],
|
317 |
+
"عيادة التخاطب": ["تخاطب", "التخاطب", "نطق", "كلام"],
|
318 |
+
"عيادة العظام": ["عظام", "العظام", "مفاصل", "كسور", "روماتيزم"],
|
319 |
+
"عيادة القلب": ["قلب", "القلب", "قلبية", "دورة دموية"],
|
320 |
+
"عيادة الأعصاب": ["أعصاب", "الأعصاب", "عصبية", "مخ وأعصاب"]
|
321 |
}
|
322 |
|
323 |
# Check for specific clinic mentions
|
|
|
331 |
if target_clinic:
|
332 |
clinic_info = [p for p in passages if target_clinic in p]
|
333 |
if clinic_info:
|
334 |
+
return f"🏥 **معلومات العيادة:** \n" + "\n".join(clinic_info)
|
335 |
|
336 |
# For questions about doctors or clinics
|
337 |
+
if any(word in user_question for word in ["عيادة", "عيادات", "دكتور", "دكاترة", "دكتورة", "مواعيد", "طبيب"]):
|
338 |
+
return f"🏥 **جميع العيادات المتاحة:** \n" + "\n".join([p for p in passages if 'عيادة' in p])
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
339 |
|
340 |
+
# Use semantic search if available
|
341 |
if embedder and corpus_embeddings is not None:
|
342 |
try:
|
343 |
question_embedding = embedder.encode(user_question, convert_to_tensor=True)
|
|
|
350 |
except Exception as e:
|
351 |
print(f"Error in semantic search: {e}")
|
352 |
|
353 |
+
# If it's a medical question but not covered above, try LLM
|
354 |
+
if is_medical_question(user_question):
|
355 |
+
return get_comprehensive_medical_answer(user_question)
|
356 |
+
|
357 |
+
# Default response
|
358 |
+
return f"💡 **الرد:** عذراً، لا يمكنني العثور على إجابة محددة لسؤالك. يرجى التواصل مع المستشفى مباشرة للحصول على المعلومات المطلوبة."
|
|
|
|
|
|
|
|
|
|
|
359 |
|
360 |
def ask_question(question):
|
361 |
+
"""Main function to handle question answering with comprehensive error handling"""
|
|
|
|
|
362 |
try:
|
363 |
if not question or question.strip() == "":
|
364 |
return "❌ خطأ: السؤال مطلوب"
|
365 |
|
366 |
+
question = question.strip()
|
367 |
+
|
368 |
+
# First check lab/radiology
|
369 |
+
answer = check_lab_or_radiology(question)
|
370 |
+
if answer:
|
371 |
+
return f"💡 **الرد:** {answer}"
|
372 |
+
|
373 |
+
# Then use the comprehensive answering system
|
374 |
+
return answer_question_from_excel(question)
|
375 |
+
|
376 |
except Exception as e:
|
377 |
return f"❌ خطأ: {str(e)}"
|
378 |
|
379 |
+
# Enhanced Gradio interface
|
380 |
with gr.Blocks(
|
381 |
+
title="نظام الأسئلة والأجوبة الطبي المتطور",
|
382 |
theme=gr.themes.Soft(),
|
383 |
css="""
|
384 |
.gradio-container {
|
|
|
390 |
background: linear-gradient(45deg, #4CAF50, #45a049);
|
391 |
color: white;
|
392 |
font-weight: bold;
|
393 |
+
border-radius: 10px;
|
394 |
}
|
395 |
.gr-textbox {
|
396 |
text-align: right;
|
397 |
direction: rtl;
|
398 |
+
border-radius: 10px;
|
399 |
+
}
|
400 |
+
.header-style {
|
401 |
+
background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
|
402 |
+
color: white;
|
403 |
+
padding: 20px;
|
404 |
+
border-radius: 15px;
|
405 |
+
margin-bottom: 20px;
|
406 |
}
|
407 |
"""
|
408 |
) as demo:
|
409 |
|
410 |
gr.Markdown(
|
411 |
"""
|
412 |
+
# 🏥 نظام الأسئلة والأجوبة الطبي المتطور
|
413 |
+
### اسأل أي سؤال طبي واحصل على إجابة ذكية ومفصلة!
|
414 |
+
|
415 |
+
**🔥 الميزات الجديدة:**
|
416 |
+
- 🤖 ذكاء اصطناعي متقدم للأسئلة الطبية
|
417 |
+
- 📚 قاعدة معرفة طبية شاملة
|
418 |
+
- 🏥 معلومات مفصلة عن العيادات والأطباء
|
419 |
+
- 🧪 تفاصيل كاملة عن التحاليل والفحوصات
|
420 |
|
421 |
+
**يمكنك السؤال عن:**
|
422 |
+
- 🩺 الأعراض والأمراض الشائعة
|
423 |
+
- 💊 النصائح العلاجية والوقائية
|
424 |
- 🏥 مواعيد العيادات والأطباء
|
425 |
- 🧪 التحاليل الطبية والمعمل
|
|
|
426 |
- 📋 أسعار الكشف والخدمات
|
427 |
+
- ⚕️ أي استفسار طبي عام
|
428 |
""",
|
429 |
elem_id="header"
|
430 |
)
|
|
|
432 |
with gr.Row():
|
433 |
with gr.Column(scale=4):
|
434 |
question_input = gr.Textbox(
|
435 |
+
label="اكتب سؤالك الطبي هنا",
|
436 |
+
placeholder="مثال: ما علاج الصداع؟ أو ما مواعيد عيادة الأطفال؟",
|
437 |
+
lines=4,
|
438 |
text_align="right",
|
439 |
rtl=True
|
440 |
)
|
441 |
with gr.Column(scale=1):
|
442 |
submit_btn = gr.Button(
|
443 |
+
"🔍 اسأل السؤال",
|
444 |
variant="primary",
|
445 |
size="lg"
|
446 |
)
|
447 |
|
448 |
answer_output = gr.Textbox(
|
449 |
+
label="الإجابة الطبية",
|
450 |
+
lines=15,
|
451 |
interactive=False,
|
452 |
text_align="right",
|
453 |
rtl=True
|
454 |
)
|
455 |
|
456 |
+
# Enhanced example questions
|
457 |
gr.Examples(
|
458 |
examples=[
|
459 |
+
["ما علاج الحمى عند الأطفال؟"],
|
460 |
+
["أعاني من صداع مستمر، ما النصيحة؟"],
|
461 |
+
["ما هي أعراض الجفاف وكيف أعالجه؟"],
|
462 |
+
["ما هي مواعيد عيادة القلب؟"],
|
463 |
+
["هل يوجد تحليل فيروس كورونا؟"],
|
464 |
+
["مين أفضل دكتور عظام في المستشفى؟"],
|
465 |
+
["ما هي تحاليل وظائف الكبد المطلوبة؟"],
|
466 |
+
["كيف أعالج السعال الجاف؟"]
|
467 |
],
|
468 |
inputs=question_input,
|
469 |
+
label="أمثلة على الأسئلة الطبية"
|
470 |
)
|
471 |
|
472 |
# Set up the interaction
|
|
|
482 |
inputs=question_input,
|
483 |
outputs=answer_output
|
484 |
)
|
485 |
+
|
486 |
+
# Add disclaimer
|
487 |
+
gr.Markdown(
|
488 |
+
"""
|
489 |
+
---
|
490 |
+
⚠️ **إخلاء مسؤولية:** هذا النظام يقدم معلومات طبية عامة فقط وليس بديلاً عن الاستشارة الطبية المتخصصة.
|
491 |
+
يرجى استشارة طبيب مختص للحصول على تشخيص وعلاج دقيق.
|
492 |
+
""",
|
493 |
+
elem_id="disclaimer"
|
494 |
+
)
|
495 |
|
496 |
if __name__ == "__main__":
|
497 |
+
print("Starting Enhanced Hospital Q&A System...")
|
|
|
498 |
demo.launch(
|
499 |
+
server_name="0.0.0.0",
|
500 |
+
server_port=7860,
|
501 |
+
share=False,
|
502 |
debug=True,
|
503 |
show_error=True
|
504 |
)
|