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.")
|