Spaces:
Sleeping
Sleeping
jocko
commited on
Commit
Β·
4a259f2
1
Parent(s):
24f3768
initial commit
Browse files- src/streamlit_app.py +28 -9
src/streamlit_app.py
CHANGED
@@ -27,7 +27,7 @@ from pathlib import Path
|
|
27 |
# === CONFIG ===
|
28 |
# Set the API key
|
29 |
client = openai.OpenAI(api_key=os.getenv("OPENAI_API_KEY"))
|
30 |
-
#openai.api_key = os.getenv("OPENAI_API_KEY")
|
31 |
# REMEDI_PATH = "ReMeDi-base.json"
|
32 |
BASE_DIR = Path(__file__).parent
|
33 |
REMEDI_PATH = BASE_DIR / "ReMeDi-base.json"
|
@@ -40,11 +40,13 @@ if not REMEDI_PATH.exists():
|
|
40 |
with open(REMEDI_PATH, "r", encoding="utf-8") as f:
|
41 |
data = json.load(f)
|
42 |
|
|
|
43 |
# === LOAD MODEL ===
|
44 |
@st.cache_resource
|
45 |
def load_model():
|
46 |
return SentenceTransformer("all-MiniLM-L6-v2")
|
47 |
-
#return model
|
|
|
48 |
|
49 |
@st.cache_resource
|
50 |
def load_data():
|
@@ -53,20 +55,22 @@ def load_data():
|
|
53 |
dialogue_pairs = []
|
54 |
for conversation in data:
|
55 |
turns = conversation["information"]
|
56 |
-
for i in range(len(turns)-1):
|
57 |
-
if turns[i]["role"] == "patient" and turns[i+1]["role"] == "doctor":
|
58 |
dialogue_pairs.append({
|
59 |
"patient": turns[i]["sentence"],
|
60 |
-
"doctor": turns[i+1]["sentence"]
|
61 |
})
|
62 |
return dialogue_pairs
|
63 |
|
|
|
64 |
@st.cache_data
|
65 |
def build_embeddings(dialogue_pairs, _model):
|
66 |
patient_sentences = [pair["patient"] for pair in dialogue_pairs]
|
67 |
embeddings = _model.encode(patient_sentences, convert_to_tensor=True)
|
68 |
return embeddings
|
69 |
|
|
|
70 |
# === TRANSLATE USING GPT ===
|
71 |
def translate_to_english(chinese_text):
|
72 |
prompt = f"Translate the following Chinese medical response to English:\n\n{chinese_text}"
|
@@ -78,10 +82,11 @@ def translate_to_english(chinese_text):
|
|
78 |
)
|
79 |
return response.choices[0].message.content
|
80 |
|
81 |
-
#return response.choices[0].message["content"].strip()
|
82 |
except Exception as e:
|
83 |
return f"Translation failed: {str(e)}"
|
84 |
|
|
|
85 |
def gpt_direct_response(user_input):
|
86 |
prompt = f"You are a knowledgeable and compassionate medical assistant. Answer the following patient question clearly and concisely:\n\n{user_input}"
|
87 |
try:
|
@@ -99,6 +104,8 @@ def gpt_direct_response(user_input):
|
|
99 |
def chatbot_response(user_input, _model, dialogue_pairs, patient_embeddings, top_k=1):
|
100 |
user_embedding = _model.encode(user_input, convert_to_tensor=True)
|
101 |
similarities = util.cos_sim(user_embedding, patient_embeddings)[0]
|
|
|
|
|
102 |
top_idx = torch.topk(similarities, k=top_k).indices[0].item()
|
103 |
|
104 |
match = dialogue_pairs[top_idx]
|
@@ -108,8 +115,10 @@ def chatbot_response(user_input, _model, dialogue_pairs, patient_embeddings, top
|
|
108 |
"matched_question": match["patient"],
|
109 |
"original_response": match["doctor"],
|
110 |
"translated_response": translated
|
|
|
111 |
}
|
112 |
|
|
|
113 |
# === MAIN APP ===
|
114 |
st.set_page_config(page_title="Dr_Q_bot", layout="centered")
|
115 |
st.title("π©Ί Dr_Q_bot - Medical Chatbot")
|
@@ -128,6 +137,12 @@ if st.button("Submit") and user_input:
|
|
128 |
result = chatbot_response(user_input, model, dialogue_pairs, patient_embeddings)
|
129 |
gpt_response = gpt_direct_response(user_input)
|
130 |
|
|
|
|
|
|
|
|
|
|
|
|
|
131 |
st.markdown("### π§ββοΈ Closest Patient Question")
|
132 |
st.write(result["matched_question"])
|
133 |
|
@@ -136,10 +151,14 @@ if st.button("Submit") and user_input:
|
|
136 |
|
137 |
st.markdown("### π Translated Doctor Response (English)")
|
138 |
st.success(result["translated_response"])
|
|
|
|
|
139 |
|
140 |
-
st.markdown("### π¬ GPT Doctor Response (AI-generated)")
|
141 |
-
st.info(gpt_response)
|
142 |
|
|
|
143 |
|
144 |
st.markdown("---")
|
145 |
-
st.warning(
|
|
|
|
27 |
# === CONFIG ===
|
28 |
# Set the API key
|
29 |
client = openai.OpenAI(api_key=os.getenv("OPENAI_API_KEY"))
|
30 |
+
# openai.api_key = os.getenv("OPENAI_API_KEY")
|
31 |
# REMEDI_PATH = "ReMeDi-base.json"
|
32 |
BASE_DIR = Path(__file__).parent
|
33 |
REMEDI_PATH = BASE_DIR / "ReMeDi-base.json"
|
|
|
40 |
with open(REMEDI_PATH, "r", encoding="utf-8") as f:
|
41 |
data = json.load(f)
|
42 |
|
43 |
+
|
44 |
# === LOAD MODEL ===
|
45 |
@st.cache_resource
|
46 |
def load_model():
|
47 |
return SentenceTransformer("all-MiniLM-L6-v2")
|
48 |
+
# return model
|
49 |
+
|
50 |
|
51 |
@st.cache_resource
|
52 |
def load_data():
|
|
|
55 |
dialogue_pairs = []
|
56 |
for conversation in data:
|
57 |
turns = conversation["information"]
|
58 |
+
for i in range(len(turns) - 1):
|
59 |
+
if turns[i]["role"] == "patient" and turns[i + 1]["role"] == "doctor":
|
60 |
dialogue_pairs.append({
|
61 |
"patient": turns[i]["sentence"],
|
62 |
+
"doctor": turns[i + 1]["sentence"]
|
63 |
})
|
64 |
return dialogue_pairs
|
65 |
|
66 |
+
|
67 |
@st.cache_data
|
68 |
def build_embeddings(dialogue_pairs, _model):
|
69 |
patient_sentences = [pair["patient"] for pair in dialogue_pairs]
|
70 |
embeddings = _model.encode(patient_sentences, convert_to_tensor=True)
|
71 |
return embeddings
|
72 |
|
73 |
+
|
74 |
# === TRANSLATE USING GPT ===
|
75 |
def translate_to_english(chinese_text):
|
76 |
prompt = f"Translate the following Chinese medical response to English:\n\n{chinese_text}"
|
|
|
82 |
)
|
83 |
return response.choices[0].message.content
|
84 |
|
85 |
+
# return response.choices[0].message["content"].strip()
|
86 |
except Exception as e:
|
87 |
return f"Translation failed: {str(e)}"
|
88 |
|
89 |
+
|
90 |
def gpt_direct_response(user_input):
|
91 |
prompt = f"You are a knowledgeable and compassionate medical assistant. Answer the following patient question clearly and concisely:\n\n{user_input}"
|
92 |
try:
|
|
|
104 |
def chatbot_response(user_input, _model, dialogue_pairs, patient_embeddings, top_k=1):
|
105 |
user_embedding = _model.encode(user_input, convert_to_tensor=True)
|
106 |
similarities = util.cos_sim(user_embedding, patient_embeddings)[0]
|
107 |
+
top_score, top_idx = torch.topk(similarities, k=1)
|
108 |
+
top_score = top_score.item()
|
109 |
top_idx = torch.topk(similarities, k=top_k).indices[0].item()
|
110 |
|
111 |
match = dialogue_pairs[top_idx]
|
|
|
115 |
"matched_question": match["patient"],
|
116 |
"original_response": match["doctor"],
|
117 |
"translated_response": translated
|
118 |
+
# "similarity_score": top_score
|
119 |
}
|
120 |
|
121 |
+
|
122 |
# === MAIN APP ===
|
123 |
st.set_page_config(page_title="Dr_Q_bot", layout="centered")
|
124 |
st.title("π©Ί Dr_Q_bot - Medical Chatbot")
|
|
|
137 |
result = chatbot_response(user_input, model, dialogue_pairs, patient_embeddings)
|
138 |
gpt_response = gpt_direct_response(user_input)
|
139 |
|
140 |
+
st.markdown("## β
GPT-4 Doctor's Response")
|
141 |
+
st.success(gpt_response)
|
142 |
+
|
143 |
+
# if torch.max(similarities).item() < 0.4:
|
144 |
+
|
145 |
+
st.markdown("## π Example Historical Dialogue")
|
146 |
st.markdown("### π§ββοΈ Closest Patient Question")
|
147 |
st.write(result["matched_question"])
|
148 |
|
|
|
151 |
|
152 |
st.markdown("### π Translated Doctor Response (English)")
|
153 |
st.success(result["translated_response"])
|
154 |
+
# else:
|
155 |
+
# st.warning("No close match found in dataset. Using GPT response only.")
|
156 |
|
157 |
+
# st.markdown("### π¬ GPT Doctor Response (AI-generated)")
|
158 |
+
# st.info(gpt_response)
|
159 |
|
160 |
+
# Skip dataset result
|
161 |
|
162 |
st.markdown("---")
|
163 |
+
st.warning(
|
164 |
+
"This chatbot uses real dialogue data for research and educational use only. Not a substitute for professional medical advice.")
|