Update app.py
Browse files
app.py
CHANGED
|
@@ -229,52 +229,62 @@ if st.button("๐ Run Topic Modeling Pipeline", type="primary", use_container_w
|
|
| 229 |
st.info(f"**Theme {t_id + 1}**\n\n" + "\n".join([f"๐น {w}" for w in theme_w]))
|
| 230 |
col_idx += 1
|
| 231 |
|
| 232 |
-
# --- METRICS CALCULATIONS ---
|
| 233 |
div_val, npmi_val, sil_val = 0.0, 0.0, 0.0
|
|
|
|
| 234 |
|
| 235 |
if len(eval_metrics) > 0:
|
| 236 |
-
|
| 237 |
-
|
| 238 |
with st.spinner("Calculating mathematical metrics... (NPMI requires building a dictionary and takes a moment)"):
|
| 239 |
|
| 240 |
-
|
| 241 |
-
if
|
| 242 |
-
|
| 243 |
-
|
| 244 |
-
|
| 245 |
-
|
| 246 |
-
|
| 247 |
-
|
| 248 |
-
|
| 249 |
-
|
| 250 |
-
|
| 251 |
-
|
| 252 |
-
|
| 253 |
-
|
| 254 |
-
|
| 255 |
-
temp_npmi = cm.get_coherence()
|
| 256 |
-
if np.isnan(temp_npmi):
|
| 257 |
-
st.metric("NPMI Coherence", "N/A (Too few words)")
|
| 258 |
-
else:
|
| 259 |
-
npmi_val = float(temp_npmi)
|
| 260 |
-
st.metric("NPMI Coherence (Target: >0.1)", f"{npmi_val:.2f}")
|
| 261 |
-
except Exception:
|
| 262 |
-
st.metric("NPMI Coherence", "Skipped (Data too small)")
|
| 263 |
-
|
| 264 |
-
elif "Silhouette" in metric:
|
| 265 |
-
valid_idx = [i for i, t in enumerate(topics) if t != -1]
|
| 266 |
-
unique_topics = set([topics[i] for i in valid_idx])
|
| 267 |
-
|
| 268 |
-
if 1 < len(unique_topics) < len(valid_idx):
|
| 269 |
-
sil_val = float(silhouette_score(
|
| 270 |
-
np.array([embeddings[i] for i in valid_idx]),
|
| 271 |
-
[topics[i] for i in valid_idx],
|
| 272 |
-
metric='cosine'
|
| 273 |
-
))
|
| 274 |
-
st.metric("Silhouette Score (Target: >0.0)", f"{sil_val:.2f}")
|
| 275 |
else:
|
| 276 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 277 |
|
|
|
|
| 278 |
# ==========================================
|
| 279 |
# 5. XAI VISUALIZATION GRAPH
|
| 280 |
# ==========================================
|
|
|
|
| 229 |
st.info(f"**Theme {t_id + 1}**\n\n" + "\n".join([f"๐น {w}" for w in theme_w]))
|
| 230 |
col_idx += 1
|
| 231 |
|
| 232 |
+
# --- METRICS CALCULATIONS (Math First, UI Second) ---
|
| 233 |
div_val, npmi_val, sil_val = 0.0, 0.0, 0.0
|
| 234 |
+
div_status, npmi_status, sil_status = "Skipped", "Skipped", "Skipped"
|
| 235 |
|
| 236 |
if len(eval_metrics) > 0:
|
| 237 |
+
# 1. DO ALL THE MATH INVISIBLY FIRST
|
|
|
|
| 238 |
with st.spinner("Calculating mathematical metrics... (NPMI requires building a dictionary and takes a moment)"):
|
| 239 |
|
| 240 |
+
if "Topic Diversity" in eval_metrics:
|
| 241 |
+
if len(all_words) > 0:
|
| 242 |
+
u_words = set([w for t in all_words for w in t])
|
| 243 |
+
t_words = sum([len(t) for t in all_words])
|
| 244 |
+
div_val = float(len(u_words) / t_words) if t_words > 0 else 0.0
|
| 245 |
+
div_status = f"{div_val:.2f}"
|
| 246 |
+
|
| 247 |
+
if "NPMI Coherence" in eval_metrics:
|
| 248 |
+
try:
|
| 249 |
+
tokenized = [vectorizer_model.build_analyzer()(s) for s in sentences]
|
| 250 |
+
dictionary = corpora.Dictionary(tokenized)
|
| 251 |
+
cm = CoherenceModel(topics=all_words, texts=tokenized, dictionary=dictionary, coherence='c_npmi')
|
| 252 |
+
temp_npmi = cm.get_coherence()
|
| 253 |
+
if np.isnan(temp_npmi):
|
| 254 |
+
npmi_status = "N/A (Too few words)"
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 255 |
else:
|
| 256 |
+
npmi_val = float(temp_npmi)
|
| 257 |
+
npmi_status = f"{npmi_val:.2f}"
|
| 258 |
+
except Exception:
|
| 259 |
+
npmi_status = "Skipped (Data too small)"
|
| 260 |
+
|
| 261 |
+
if "Silhouette Score" in eval_metrics:
|
| 262 |
+
valid_idx = [i for i, t in enumerate(topics) if t != -1]
|
| 263 |
+
unique_topics = set([topics[i] for i in valid_idx])
|
| 264 |
+
if 1 < len(unique_topics) < len(valid_idx):
|
| 265 |
+
sil_val = float(silhouette_score(
|
| 266 |
+
np.array([embeddings[i] for i in valid_idx]),
|
| 267 |
+
[topics[i] for i in valid_idx],
|
| 268 |
+
metric='cosine'
|
| 269 |
+
))
|
| 270 |
+
sil_status = f"{sil_val:.2f}"
|
| 271 |
+
else:
|
| 272 |
+
sil_status = "Skipped (Themes need โฅ2 sentences)"
|
| 273 |
+
|
| 274 |
+
# 2. DRAW THE UI INSTANTLY (No more jumping!)
|
| 275 |
+
st.markdown("### ๐ Key Performance Indicators (KPI)")
|
| 276 |
+
kpi_cols = st.columns(len(eval_metrics))
|
| 277 |
+
|
| 278 |
+
for idx, metric in enumerate(eval_metrics):
|
| 279 |
+
with kpi_cols[idx]:
|
| 280 |
+
if metric == "Topic Diversity":
|
| 281 |
+
st.metric("Topic Diversity (Target: 1.0)", div_status)
|
| 282 |
+
elif metric == "NPMI Coherence":
|
| 283 |
+
st.metric("NPMI Coherence (Target: >0.1)", npmi_status)
|
| 284 |
+
elif metric == "Silhouette Score":
|
| 285 |
+
st.metric("Silhouette Score (Target: >0.0)", sil_status)
|
| 286 |
|
| 287 |
+
|
| 288 |
# ==========================================
|
| 289 |
# 5. XAI VISUALIZATION GRAPH
|
| 290 |
# ==========================================
|