Spaces:
Sleeping
Sleeping
Update app.py
Browse files
app.py
CHANGED
@@ -6,75 +6,109 @@ from sentence_transformers import SentenceTransformer
|
|
6 |
from functools import lru_cache
|
7 |
from huggingface_hub import AsyncInferenceClient
|
8 |
from sklearn.decomposition import PCA
|
|
|
9 |
|
10 |
-
# ------ Data Loading ------
|
11 |
-
df = pd.read_csv("symbipredict_2022_filtered.csv")
|
|
|
|
|
12 |
|
13 |
-
# ------ Model Initialization ------
|
14 |
-
model = SentenceTransformer("all-MiniLM-L6-v2")
|
15 |
-
embedding_arr = model.encode(df[
|
16 |
|
17 |
-
# ------ Clustering Setup ------
|
18 |
-
kmeans = MiniBatchKMeans(
|
|
|
|
|
|
|
|
|
|
|
19 |
cluster_labels = kmeans.fit_predict(embedding_arr)
|
20 |
-
|
21 |
|
22 |
-
#
|
23 |
-
|
24 |
|
25 |
-
#
|
26 |
-
|
27 |
-
|
28 |
-
|
29 |
|
30 |
-
# ------
|
31 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
32 |
|
33 |
-
# ------ Streaming Response
|
34 |
async def respond(message, history, system_message, max_tokens, temperature, top_p):
|
35 |
try:
|
36 |
-
# Encoding and clustering
|
37 |
query_embedding = cached_encode(message)
|
38 |
-
|
|
|
39 |
|
|
|
|
|
|
|
|
|
|
|
40 |
# Generate streaming response
|
41 |
stream = await client.chat_completion(
|
42 |
messages=[{
|
43 |
"role": "system",
|
44 |
-
"content": system_message
|
45 |
}, {
|
46 |
"role": "user",
|
47 |
"content": message
|
48 |
}],
|
49 |
-
max_tokens=max_tokens,
|
50 |
stream=True,
|
51 |
-
temperature=temperature,
|
52 |
top_p=top_p
|
53 |
)
|
54 |
-
|
55 |
full_response = ""
|
56 |
async for chunk in stream:
|
57 |
-
|
58 |
-
|
59 |
-
full_response
|
60 |
-
|
61 |
-
|
62 |
-
|
63 |
-
yield f"{full_response}\n\
|
64 |
-
|
65 |
except Exception as e:
|
66 |
-
yield f"
|
67 |
|
68 |
-
# ------ Gradio Interface ------
|
69 |
demo = gr.ChatInterface(
|
70 |
respond,
|
71 |
additional_inputs=[
|
72 |
gr.Textbox(value="Medical diagnosis assistant", label="System Role"),
|
73 |
-
gr.Slider(512,
|
74 |
-
gr.Slider(0.1,
|
75 |
-
gr.Slider(0.
|
76 |
-
]
|
77 |
-
|
|
|
78 |
|
79 |
if __name__ == "__main__":
|
80 |
-
demo.launch()
|
|
|
6 |
from functools import lru_cache
|
7 |
from huggingface_hub import AsyncInferenceClient
|
8 |
from sklearn.decomposition import PCA
|
9 |
+
from sklearn.metrics import pairwise_distances_argmin_min
|
10 |
|
11 |
+
# ------ Enhanced Data Loading ------
|
12 |
+
df = pd.read_csv("symbipredict_2022_filtered.csv").sample(frac=1, random_state=42) # Shuffle data
|
13 |
+
SYMPTOM_FIELD = 'symptoms'
|
14 |
+
PROGNOSIS_FIELD = 'prognosis'
|
15 |
|
16 |
+
# ------ Optimized Model Initialization ------
|
17 |
+
model = SentenceTransformer("all-MiniLM-L6-v2", device='cpu')
|
18 |
+
embedding_arr = model.encode(df[SYMPTOM_FIELD], show_progress_bar=True).astype(np.float32)
|
19 |
|
20 |
+
# ------ Robust Clustering Setup ------
|
21 |
+
kmeans = MiniBatchKMeans(
|
22 |
+
n_clusters=15, # Increased for better granularity [2][13]
|
23 |
+
random_state=42,
|
24 |
+
n_init=5, # Multiple initializations [2][10]
|
25 |
+
max_iter=300 # Better convergence [2]
|
26 |
+
)
|
27 |
cluster_labels = kmeans.fit_predict(embedding_arr)
|
28 |
+
centroids = kmeans.cluster_centers_
|
29 |
|
30 |
+
# Cluster validation metrics
|
31 |
+
cluster_quality = pairwise_distances_argmin_min(embedding_arr, centroids)[1].mean()
|
32 |
|
33 |
+
# Prognosis mapping with confidence scores
|
34 |
+
cluster_prognosis_map = df.groupby(cluster_labels)[PROGNOSIS_FIELD].agg(
|
35 |
+
lambda x: x.value_counts(normalize=True).head(3).to_dict() # Top 3 prognoses with frequencies
|
36 |
+
)
|
37 |
|
38 |
+
# ------ Session Context Management ------
|
39 |
+
class DiagnosisSession:
|
40 |
+
def __init__(self):
|
41 |
+
self.sessions = {}
|
42 |
+
self.similarity_threshold = 0.82 # Optimized per [11]
|
43 |
+
|
44 |
+
def get_cluster(self, history, query_embedding):
|
45 |
+
session_id = hash(frozenset(history))
|
46 |
+
if session_id in self.sessions:
|
47 |
+
prev_centroid = centroids[self.sessions[session_id]['cluster']]
|
48 |
+
distance = np.linalg.norm(query_embedding - prev_centroid)
|
49 |
+
if distance < self.similarity_threshold:
|
50 |
+
return self.sessions[session_id]
|
51 |
+
|
52 |
+
new_cluster = kmeans.predict(query_embedding.reshape(1, -1))[0]
|
53 |
+
self.sessions[session_id] = {
|
54 |
+
'cluster': new_cluster,
|
55 |
+
'embedding': query_embedding
|
56 |
+
}
|
57 |
+
return self.sessions[session_id]
|
58 |
+
|
59 |
+
session_manager = DiagnosisSession()
|
60 |
|
61 |
+
# ------ Streaming Response Improvements ------
|
62 |
async def respond(message, history, system_message, max_tokens, temperature, top_p):
|
63 |
try:
|
|
|
64 |
query_embedding = cached_encode(message)
|
65 |
+
session = session_manager.get_cluster(history, query_embedding)
|
66 |
+
cluster_info = cluster_prognosis_map[session['cluster']]
|
67 |
|
68 |
+
# Validate cluster quality
|
69 |
+
if cluster_quality < 0.65: # [10][13]
|
70 |
+
yield "System confidence low - consult a healthcare professional"
|
71 |
+
return
|
72 |
+
|
73 |
# Generate streaming response
|
74 |
stream = await client.chat_completion(
|
75 |
messages=[{
|
76 |
"role": "system",
|
77 |
+
f"content": f"{system_message}\nCurrent cluster: {session['cluster']}"
|
78 |
}, {
|
79 |
"role": "user",
|
80 |
"content": message
|
81 |
}],
|
82 |
+
max_tokens=min(max_tokens, 1024), # Safety limit
|
83 |
stream=True,
|
84 |
+
temperature=max(0.1, min(temperature, 1.0)), # Constrained randomness
|
85 |
top_p=top_p
|
86 |
)
|
87 |
+
|
88 |
full_response = ""
|
89 |
async for chunk in stream:
|
90 |
+
if chunk.choices[0].delta.content:
|
91 |
+
full_response += chunk.choices[0].delta.content
|
92 |
+
yield full_response
|
93 |
+
|
94 |
+
# Format prognosis display
|
95 |
+
top_diagnoses = [f"{k} ({v:.1%})" for k,v in cluster_info.items()]
|
96 |
+
yield f"{full_response}\n\nLikely conditions: {', '.join(top_diagnoses)}"
|
97 |
+
|
98 |
except Exception as e:
|
99 |
+
yield f"⚠️ Medical system error: {str(e)}"
|
100 |
|
101 |
+
# ------ Enhanced Gradio Interface ------
|
102 |
demo = gr.ChatInterface(
|
103 |
respond,
|
104 |
additional_inputs=[
|
105 |
gr.Textbox(value="Medical diagnosis assistant", label="System Role"),
|
106 |
+
gr.Slider(512, 1024, value=512, step=128, label="Max Tokens"),
|
107 |
+
gr.Slider(0.1, 1.0, value=0.5, step=0.1, label="Temperature"),
|
108 |
+
gr.Slider(0.7, 1.0, value=0.9, step=0.05, label="Top-p")
|
109 |
+
],
|
110 |
+
examples=[["Headache and fever"], ["Chest pain radiating to arm"]]
|
111 |
+
).queue(concurrency_count=5) # Improved throughput [1]
|
112 |
|
113 |
if __name__ == "__main__":
|
114 |
+
demo.launch(server_port=7860, share=True)
|