Spaces:
Runtime error
Runtime error
Update streamlit_app.py
Browse files- streamlit_app.py +98 -257
streamlit_app.py
CHANGED
|
@@ -416,239 +416,88 @@ def main():
|
|
| 416 |
)
|
| 417 |
st.stop()
|
| 418 |
|
| 419 |
-
# Metric selection
|
| 420 |
-
st.sidebar.header("π Metrics")
|
| 421 |
-
|
| 422 |
-
# Dynamic metric categorization based on common patterns
|
| 423 |
-
def categorize_metrics(metrics):
|
| 424 |
-
"""Dynamically categorize metrics based on naming patterns"""
|
| 425 |
-
categories = {"All": metrics} # Always include all metrics
|
| 426 |
-
|
| 427 |
-
# Common patterns to look for
|
| 428 |
-
patterns = {
|
| 429 |
-
"Length": ["length", "byte", "word", "token", "char"],
|
| 430 |
-
"Readability": ["readability", "flesch", "standard"],
|
| 431 |
-
"Compression": ["lzw", "compression"],
|
| 432 |
-
"Language Model": ["ll_", "rll_", "logprob"],
|
| 433 |
-
"Working Memory": ["wm_"],
|
| 434 |
-
"Discourse": ["discourse"],
|
| 435 |
-
"Evaluation": ["rubric", "evaluation", "stealth"],
|
| 436 |
-
"Distribution": ["zipf", "type_token"],
|
| 437 |
-
"Coherence": ["coherence"],
|
| 438 |
-
"Entity": ["entity", "entities"],
|
| 439 |
-
"Cognitive": ["cognitive", "load"],
|
| 440 |
-
}
|
| 441 |
-
|
| 442 |
-
# Categorize metrics
|
| 443 |
-
for category, keywords in patterns.items():
|
| 444 |
-
matching_metrics = [
|
| 445 |
-
m for m in metrics if any(keyword in m.lower() for keyword in keywords)
|
| 446 |
-
]
|
| 447 |
-
if matching_metrics:
|
| 448 |
-
categories[category] = matching_metrics
|
| 449 |
-
|
| 450 |
-
# Find uncategorized metrics
|
| 451 |
-
categorized = set()
|
| 452 |
-
for cat_metrics in categories.values():
|
| 453 |
-
if cat_metrics != metrics: # Skip "All" category
|
| 454 |
-
categorized.update(cat_metrics)
|
| 455 |
-
|
| 456 |
-
uncategorized = [m for m in metrics if m not in categorized]
|
| 457 |
-
if uncategorized:
|
| 458 |
-
categories["Other"] = uncategorized
|
| 459 |
-
|
| 460 |
-
return categories
|
| 461 |
-
|
| 462 |
-
metric_categories = categorize_metrics(available_metrics)
|
| 463 |
-
|
| 464 |
-
# Metric selection interface
|
| 465 |
-
selection_mode = st.sidebar.radio(
|
| 466 |
-
"Selection Mode",
|
| 467 |
-
["By Category", "Search/Filter", "Select All"],
|
| 468 |
-
help="Choose how to select metrics",
|
| 469 |
-
)
|
| 470 |
-
|
| 471 |
-
if selection_mode == "By Category":
|
| 472 |
-
selected_category = st.sidebar.selectbox(
|
| 473 |
-
"Metric Category",
|
| 474 |
-
options=list(metric_categories.keys()),
|
| 475 |
-
help=f"Found {len(metric_categories)} categories",
|
| 476 |
-
)
|
| 477 |
-
|
| 478 |
-
available_in_category = metric_categories[selected_category]
|
| 479 |
-
default_selection = (
|
| 480 |
-
available_in_category[:5]
|
| 481 |
-
if len(available_in_category) > 5
|
| 482 |
-
else available_in_category
|
| 483 |
-
)
|
| 484 |
-
|
| 485 |
-
# Add select all button for category
|
| 486 |
-
col1, col2 = st.sidebar.columns(2)
|
| 487 |
-
with col1:
|
| 488 |
-
if st.button("Select All", key="select_all_category"):
|
| 489 |
-
st.session_state.selected_metrics_category = available_in_category
|
| 490 |
-
with col2:
|
| 491 |
-
if st.button("Clear All", key="clear_all_category"):
|
| 492 |
-
st.session_state.selected_metrics_category = []
|
| 493 |
-
|
| 494 |
-
# Use session state for persistence
|
| 495 |
-
if "selected_metrics_category" not in st.session_state:
|
| 496 |
-
st.session_state.selected_metrics_category = default_selection
|
| 497 |
-
|
| 498 |
-
selected_metrics = st.sidebar.multiselect(
|
| 499 |
-
f"Select Metrics ({len(available_in_category)} available)",
|
| 500 |
-
options=available_in_category,
|
| 501 |
-
default=st.session_state.selected_metrics_category,
|
| 502 |
-
key="metrics_multiselect_category",
|
| 503 |
-
help="Choose metrics to visualize",
|
| 504 |
-
)
|
| 505 |
-
|
| 506 |
-
elif selection_mode == "Search/Filter":
|
| 507 |
-
search_term = st.sidebar.text_input(
|
| 508 |
-
"Search Metrics",
|
| 509 |
-
placeholder="Enter keywords to filter metrics...",
|
| 510 |
-
help="Search for metrics containing specific terms",
|
| 511 |
-
)
|
| 512 |
-
|
| 513 |
-
if search_term:
|
| 514 |
-
filtered_metrics = [
|
| 515 |
-
m for m in available_metrics if search_term.lower() in m.lower()
|
| 516 |
-
]
|
| 517 |
-
else:
|
| 518 |
-
filtered_metrics = available_metrics
|
| 519 |
-
|
| 520 |
-
st.sidebar.write(f"Found {len(filtered_metrics)} metrics")
|
| 521 |
-
|
| 522 |
-
# Add select all button for search results
|
| 523 |
-
col1, col2 = st.sidebar.columns(2)
|
| 524 |
-
with col1:
|
| 525 |
-
if st.button("Select All", key="select_all_search"):
|
| 526 |
-
st.session_state.selected_metrics_search = filtered_metrics
|
| 527 |
-
with col2:
|
| 528 |
-
if st.button("Clear All", key="clear_all_search"):
|
| 529 |
-
st.session_state.selected_metrics_search = []
|
| 530 |
-
|
| 531 |
-
# Use session state for persistence
|
| 532 |
-
if "selected_metrics_search" not in st.session_state:
|
| 533 |
-
st.session_state.selected_metrics_search = (
|
| 534 |
-
filtered_metrics[:5]
|
| 535 |
-
if len(filtered_metrics) > 5
|
| 536 |
-
else filtered_metrics[:3]
|
| 537 |
-
)
|
| 538 |
-
|
| 539 |
-
selected_metrics = st.sidebar.multiselect(
|
| 540 |
-
"Select Metrics",
|
| 541 |
-
options=filtered_metrics,
|
| 542 |
-
default=st.session_state.selected_metrics_search,
|
| 543 |
-
key="metrics_multiselect_search",
|
| 544 |
-
help="Choose metrics to visualize",
|
| 545 |
-
)
|
| 546 |
-
|
| 547 |
-
else: # Select All
|
| 548 |
-
# Add select all button for all metrics
|
| 549 |
-
col1, col2 = st.sidebar.columns(2)
|
| 550 |
-
with col1:
|
| 551 |
-
if st.button("Select All", key="select_all_all"):
|
| 552 |
-
st.session_state.selected_metrics_all = available_metrics
|
| 553 |
-
with col2:
|
| 554 |
-
if st.button("Clear All", key="clear_all_all"):
|
| 555 |
-
st.session_state.selected_metrics_all = []
|
| 556 |
-
|
| 557 |
-
# Use session state for persistence
|
| 558 |
-
if "selected_metrics_all" not in st.session_state:
|
| 559 |
-
st.session_state.selected_metrics_all = available_metrics[
|
| 560 |
-
:10
|
| 561 |
-
] # Limit default to first 10 for performance
|
| 562 |
-
|
| 563 |
-
selected_metrics = st.sidebar.multiselect(
|
| 564 |
-
f"All Metrics ({len(available_metrics)} total)",
|
| 565 |
-
options=available_metrics,
|
| 566 |
-
default=st.session_state.selected_metrics_all,
|
| 567 |
-
key="metrics_multiselect_all",
|
| 568 |
-
help="All available metrics - be careful with performance for large selections",
|
| 569 |
-
)
|
| 570 |
-
|
| 571 |
-
# Show selection summary
|
| 572 |
-
if selected_metrics:
|
| 573 |
-
st.sidebar.success(f"Selected {len(selected_metrics)} metrics")
|
| 574 |
-
|
| 575 |
-
# Performance warning for large selections
|
| 576 |
-
if len(selected_metrics) > 20:
|
| 577 |
-
st.sidebar.warning(
|
| 578 |
-
f"β οΈ Large selection ({len(selected_metrics)} metrics) may impact performance"
|
| 579 |
-
)
|
| 580 |
-
elif len(selected_metrics) > 50:
|
| 581 |
-
st.sidebar.error(
|
| 582 |
-
f"π¨ Very large selection ({len(selected_metrics)} metrics) - consider reducing for better performance"
|
| 583 |
-
)
|
| 584 |
-
else:
|
| 585 |
-
st.sidebar.warning("No metrics selected")
|
| 586 |
-
|
| 587 |
-
# Metric info expander
|
| 588 |
-
with st.sidebar.expander("βΉοΈ Metric Information", expanded=False):
|
| 589 |
-
st.write(f"**Total Available Metrics:** {len(available_metrics)}")
|
| 590 |
-
st.write(f"**Categories Found:** {len(metric_categories)}")
|
| 591 |
-
|
| 592 |
-
if st.checkbox("Show all metric names", key="show_all_metrics"):
|
| 593 |
-
st.write("**All Available Metrics:**")
|
| 594 |
-
for i, metric in enumerate(available_metrics, 1):
|
| 595 |
-
st.write(f"{i}. `{metric}`")
|
| 596 |
-
|
| 597 |
# Main content tabs
|
| 598 |
tab1, tab2, tab3, tab4, tab5 = st.tabs(
|
| 599 |
[
|
| 600 |
"π Distributions",
|
| 601 |
-
"π Correlations",
|
| 602 |
"π Comparisons",
|
| 603 |
"π Conversation",
|
| 604 |
"π― Details",
|
| 605 |
]
|
| 606 |
)
|
| 607 |
|
|
|
|
|
|
|
|
|
|
| 608 |
with tab1:
|
| 609 |
st.header("Distribution Analysis")
|
| 610 |
-
|
| 611 |
-
|
| 612 |
-
|
| 613 |
-
|
| 614 |
-
|
| 615 |
-
#
|
| 616 |
-
st.
|
| 617 |
-
|
|
|
|
|
|
|
| 618 |
)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 619 |
|
| 620 |
-
#
|
| 621 |
-
|
| 622 |
-
|
| 623 |
-
|
| 624 |
-
|
| 625 |
-
|
| 626 |
-
|
| 627 |
-
|
| 628 |
-
|
| 629 |
-
|
| 630 |
-
|
| 631 |
-
|
| 632 |
-
|
| 633 |
-
|
| 634 |
-
|
| 635 |
-
|
| 636 |
-
|
| 637 |
-
|
| 638 |
-
):
|
| 639 |
-
render_metric_distribution(
|
| 640 |
-
metric, filtered_df_exploded, selected_types
|
| 641 |
)
|
| 642 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 643 |
with tab2:
|
| 644 |
st.header("Correlation Analysis")
|
| 645 |
|
| 646 |
-
if len(
|
| 647 |
st.warning("Please select at least 2 metrics for correlation analysis.")
|
| 648 |
else:
|
| 649 |
# Add button to trigger correlation analysis
|
| 650 |
st.info(
|
| 651 |
-
f"π Ready to analyze correlations between {len(
|
| 652 |
)
|
| 653 |
|
| 654 |
col1, col2 = st.columns([1, 3])
|
|
@@ -658,15 +507,15 @@ def main():
|
|
| 658 |
help="Calculate and display correlation matrix and scatter plots",
|
| 659 |
)
|
| 660 |
with col2:
|
| 661 |
-
if len(
|
| 662 |
st.warning(
|
| 663 |
-
f"β οΈ Large analysis ({len(
|
| 664 |
)
|
| 665 |
|
| 666 |
if run_correlation:
|
| 667 |
with st.spinner("Calculating correlations..."):
|
| 668 |
# Prepare correlation data
|
| 669 |
-
corr_columns = [f"turn.turn_metrics.{m}" for m in
|
| 670 |
corr_data = filtered_df_exploded[corr_columns + ["type"]].copy()
|
| 671 |
|
| 672 |
# Clean column names for display
|
|
@@ -739,11 +588,11 @@ def main():
|
|
| 739 |
with tab3:
|
| 740 |
st.header("Type Comparisons")
|
| 741 |
|
| 742 |
-
if not
|
| 743 |
st.warning("Please select at least one metric to compare.")
|
| 744 |
else:
|
| 745 |
# Box plots for each metric
|
| 746 |
-
for metric in
|
| 747 |
full_metric_name = f"turn.turn_metrics.{metric}"
|
| 748 |
|
| 749 |
if full_metric_name not in filtered_df_exploded.columns:
|
|
@@ -777,53 +626,45 @@ def main():
|
|
| 777 |
# Conversation selector
|
| 778 |
st.subheader("π Select Conversation")
|
| 779 |
|
| 780 |
-
# Get
|
| 781 |
-
|
| 782 |
-
|
| 783 |
-
|
| 784 |
-
|
| 785 |
-
conv_turns = len(row.get("conversation", []))
|
| 786 |
-
conversation_info.append(
|
| 787 |
-
{
|
| 788 |
-
"index": idx,
|
| 789 |
-
"type": conv_type,
|
| 790 |
-
"turns": conv_turns,
|
| 791 |
-
"display": f"Conversation {idx} ({conv_type}) - {conv_turns} turns",
|
| 792 |
-
}
|
| 793 |
-
)
|
| 794 |
-
|
| 795 |
-
# Sort by type and number of turns for better organization
|
| 796 |
-
conversation_info = sorted(
|
| 797 |
-
conversation_info, key=lambda x: (x["type"], -x["turns"])
|
| 798 |
-
)
|
| 799 |
|
| 800 |
-
# Conversation selection
|
| 801 |
-
col1, col2 = st.columns([
|
| 802 |
|
| 803 |
with col1:
|
| 804 |
-
|
| 805 |
-
"
|
| 806 |
-
|
| 807 |
-
|
|
|
|
|
|
|
|
|
|
| 808 |
)
|
| 809 |
|
| 810 |
with col2:
|
| 811 |
if st.button("π² Random", help="Select a random conversation"):
|
| 812 |
import random
|
| 813 |
-
|
| 814 |
-
selected_conv_display = random.choice(
|
| 815 |
-
[conv["display"] for conv in conversation_info]
|
| 816 |
-
)
|
| 817 |
st.rerun()
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 818 |
|
| 819 |
-
#
|
| 820 |
-
|
| 821 |
-
|
| 822 |
-
|
| 823 |
-
|
| 824 |
-
|
| 825 |
-
selected_idx = selected_conv_info["index"]
|
| 826 |
-
selected_conversation = filtered_df.iloc[selected_idx]
|
| 827 |
|
| 828 |
# Display conversation metadata
|
| 829 |
st.subheader("π Conversation Overview")
|
|
@@ -979,7 +820,7 @@ def main():
|
|
| 979 |
st.subheader("π¬ Conversation with Metrics")
|
| 980 |
|
| 981 |
# Get actual turn-level data for this conversation
|
| 982 |
-
turn_metric_columns = [f"turn.turn_metrics.{m}" for m in
|
| 983 |
available_columns = [
|
| 984 |
col
|
| 985 |
for col in turn_metric_columns
|
|
@@ -1200,7 +1041,7 @@ def main():
|
|
| 1200 |
"No numeric metric data available to plot for this conversation type."
|
| 1201 |
)
|
| 1202 |
|
| 1203 |
-
elif
|
| 1204 |
st.info(
|
| 1205 |
"Select metrics that are available in the dataset to see turn-level analysis."
|
| 1206 |
)
|
|
@@ -1223,7 +1064,7 @@ def main():
|
|
| 1223 |
help="Generate comprehensive dataset overview and metric analysis",
|
| 1224 |
)
|
| 1225 |
with col2:
|
| 1226 |
-
if len(
|
| 1227 |
st.warning("β οΈ Large metric selection - analysis may take some time")
|
| 1228 |
|
| 1229 |
if show_details:
|
|
@@ -1263,7 +1104,7 @@ def main():
|
|
| 1263 |
if st.checkbox("Show raw data sample"):
|
| 1264 |
sample_cols = ["type"] + [
|
| 1265 |
f"turn.turn_metrics.{m}"
|
| 1266 |
-
for m in
|
| 1267 |
if f"turn.turn_metrics.{m}" in filtered_df_exploded.columns
|
| 1268 |
]
|
| 1269 |
sample_data = filtered_df_exploded[sample_cols].head(100)
|
|
@@ -1273,7 +1114,7 @@ def main():
|
|
| 1273 |
st.subheader("π Metric Availability")
|
| 1274 |
|
| 1275 |
metric_completeness = {}
|
| 1276 |
-
for metric in
|
| 1277 |
full_metric_name = f"turn.turn_metrics.{metric}"
|
| 1278 |
if full_metric_name in filtered_df_exploded.columns:
|
| 1279 |
completeness = (
|
|
|
|
| 416 |
)
|
| 417 |
st.stop()
|
| 418 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 419 |
# Main content tabs
|
| 420 |
tab1, tab2, tab3, tab4, tab5 = st.tabs(
|
| 421 |
[
|
| 422 |
"π Distributions",
|
| 423 |
+
"π Correlations",
|
| 424 |
"π Comparisons",
|
| 425 |
"π Conversation",
|
| 426 |
"π― Details",
|
| 427 |
]
|
| 428 |
)
|
| 429 |
|
| 430 |
+
# Make available metrics accessible to all tabs
|
| 431 |
+
available_metrics_for_analysis = available_metrics
|
| 432 |
+
|
| 433 |
with tab1:
|
| 434 |
st.header("Distribution Analysis")
|
| 435 |
+
|
| 436 |
+
# Simple metric selection - just show all metrics with checkboxes
|
| 437 |
+
st.subheader("π Select Metrics to Plot")
|
| 438 |
+
st.info(f"**{len(available_metrics)} metrics available** - Check the boxes below to plot their distributions")
|
| 439 |
+
|
| 440 |
+
# Optional: Add search functionality to help users find metrics
|
| 441 |
+
search_term = st.text_input(
|
| 442 |
+
"π Search metrics (optional)",
|
| 443 |
+
placeholder="Enter keywords to filter metrics...",
|
| 444 |
+
help="Search for metrics containing specific terms"
|
| 445 |
)
|
| 446 |
+
|
| 447 |
+
if search_term:
|
| 448 |
+
filtered_metrics = [
|
| 449 |
+
m for m in available_metrics if search_term.lower() in m.lower()
|
| 450 |
+
]
|
| 451 |
+
st.write(f"**{len(filtered_metrics)} metrics** match your search")
|
| 452 |
+
else:
|
| 453 |
+
filtered_metrics = available_metrics
|
| 454 |
|
| 455 |
+
# Create checkboxes for each metric to allow multiple selections
|
| 456 |
+
if not filtered_metrics:
|
| 457 |
+
st.warning("No metrics found. Try adjusting your search.")
|
| 458 |
+
else:
|
| 459 |
+
# Organize checkboxes in columns for better layout
|
| 460 |
+
cols_per_row = 3
|
| 461 |
+
selected_for_plotting = []
|
| 462 |
+
|
| 463 |
+
for i in range(0, len(filtered_metrics), cols_per_row):
|
| 464 |
+
cols = st.columns(cols_per_row)
|
| 465 |
+
for j, metric in enumerate(filtered_metrics[i : i + cols_per_row]):
|
| 466 |
+
with cols[j]:
|
| 467 |
+
friendly_name = get_human_friendly_metric_name(metric)
|
| 468 |
+
# Truncate checkbox text if too long
|
| 469 |
+
checkbox_text = (
|
| 470 |
+
friendly_name[:25] + "..."
|
| 471 |
+
if len(friendly_name) > 25
|
| 472 |
+
else friendly_name
|
|
|
|
|
|
|
|
|
|
| 473 |
)
|
| 474 |
|
| 475 |
+
if st.checkbox(
|
| 476 |
+
f"π {checkbox_text}",
|
| 477 |
+
key=f"plot_{metric}",
|
| 478 |
+
help=f"Plot distribution for {friendly_name}",
|
| 479 |
+
):
|
| 480 |
+
selected_for_plotting.append(metric)
|
| 481 |
+
|
| 482 |
+
# Render selected metrics
|
| 483 |
+
if selected_for_plotting:
|
| 484 |
+
st.success(f"Plotting {len(selected_for_plotting)} selected metrics...")
|
| 485 |
+
for metric in selected_for_plotting:
|
| 486 |
+
render_metric_distribution(
|
| 487 |
+
metric, filtered_df_exploded, selected_types
|
| 488 |
+
)
|
| 489 |
+
else:
|
| 490 |
+
st.info("π Check the boxes above to plot metric distributions")
|
| 491 |
+
|
| 492 |
with tab2:
|
| 493 |
st.header("Correlation Analysis")
|
| 494 |
|
| 495 |
+
if len(available_metrics_for_analysis) < 2:
|
| 496 |
st.warning("Please select at least 2 metrics for correlation analysis.")
|
| 497 |
else:
|
| 498 |
# Add button to trigger correlation analysis
|
| 499 |
st.info(
|
| 500 |
+
f"π Ready to analyze correlations between {len(available_metrics_for_analysis)} metrics"
|
| 501 |
)
|
| 502 |
|
| 503 |
col1, col2 = st.columns([1, 3])
|
|
|
|
| 507 |
help="Calculate and display correlation matrix and scatter plots",
|
| 508 |
)
|
| 509 |
with col2:
|
| 510 |
+
if len(available_metrics_for_analysis) > 10:
|
| 511 |
st.warning(
|
| 512 |
+
f"β οΈ Large analysis ({len(available_metrics_for_analysis)} metrics) - may take some time"
|
| 513 |
)
|
| 514 |
|
| 515 |
if run_correlation:
|
| 516 |
with st.spinner("Calculating correlations..."):
|
| 517 |
# Prepare correlation data
|
| 518 |
+
corr_columns = [f"turn.turn_metrics.{m}" for m in available_metrics_for_analysis]
|
| 519 |
corr_data = filtered_df_exploded[corr_columns + ["type"]].copy()
|
| 520 |
|
| 521 |
# Clean column names for display
|
|
|
|
| 588 |
with tab3:
|
| 589 |
st.header("Type Comparisons")
|
| 590 |
|
| 591 |
+
if not available_metrics_for_analysis:
|
| 592 |
st.warning("Please select at least one metric to compare.")
|
| 593 |
else:
|
| 594 |
# Box plots for each metric
|
| 595 |
+
for metric in available_metrics_for_analysis:
|
| 596 |
full_metric_name = f"turn.turn_metrics.{metric}"
|
| 597 |
|
| 598 |
if full_metric_name not in filtered_df_exploded.columns:
|
|
|
|
| 626 |
# Conversation selector
|
| 627 |
st.subheader("π Select Conversation")
|
| 628 |
|
| 629 |
+
# Get total number of conversations and basic info
|
| 630 |
+
total_conversations = len(filtered_df)
|
| 631 |
+
available_indices = list(filtered_df.index)
|
| 632 |
+
|
| 633 |
+
st.info(f"π Dataset contains {total_conversations:,} conversations (indices: {min(available_indices)} to {max(available_indices)})")
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 634 |
|
| 635 |
+
# Conversation selection with number input
|
| 636 |
+
col1, col2, col3 = st.columns([2, 1, 1])
|
| 637 |
|
| 638 |
with col1:
|
| 639 |
+
selected_idx = st.number_input(
|
| 640 |
+
"Conversation Index",
|
| 641 |
+
min_value=min(available_indices),
|
| 642 |
+
max_value=max(available_indices),
|
| 643 |
+
value=available_indices[0], # Default to first available
|
| 644 |
+
step=1,
|
| 645 |
+
help=f"Enter a conversation index between {min(available_indices)} and {max(available_indices)}"
|
| 646 |
)
|
| 647 |
|
| 648 |
with col2:
|
| 649 |
if st.button("π² Random", help="Select a random conversation"):
|
| 650 |
import random
|
| 651 |
+
selected_idx = random.choice(available_indices)
|
|
|
|
|
|
|
|
|
|
| 652 |
st.rerun()
|
| 653 |
+
|
| 654 |
+
with col3:
|
| 655 |
+
if st.button("βΉοΈ Info", help="Show conversation preview"):
|
| 656 |
+
if selected_idx in available_indices:
|
| 657 |
+
preview_row = filtered_df.loc[selected_idx]
|
| 658 |
+
st.info(f"**Type:** {preview_row['type']} | **Turns:** {len(preview_row.get('conversation', []))}")
|
| 659 |
+
else:
|
| 660 |
+
st.error("Invalid conversation index")
|
| 661 |
|
| 662 |
+
# Validate and get the selected conversation data
|
| 663 |
+
if selected_idx not in available_indices:
|
| 664 |
+
st.error(f"β Conversation index {selected_idx} not found in filtered dataset. Available range: {min(available_indices)} to {max(available_indices)}")
|
| 665 |
+
st.stop()
|
| 666 |
+
|
| 667 |
+
selected_conversation = filtered_df.loc[selected_idx]
|
|
|
|
|
|
|
| 668 |
|
| 669 |
# Display conversation metadata
|
| 670 |
st.subheader("π Conversation Overview")
|
|
|
|
| 820 |
st.subheader("π¬ Conversation with Metrics")
|
| 821 |
|
| 822 |
# Get actual turn-level data for this conversation
|
| 823 |
+
turn_metric_columns = [f"turn.turn_metrics.{m}" for m in available_metrics_for_analysis]
|
| 824 |
available_columns = [
|
| 825 |
col
|
| 826 |
for col in turn_metric_columns
|
|
|
|
| 1041 |
"No numeric metric data available to plot for this conversation type."
|
| 1042 |
)
|
| 1043 |
|
| 1044 |
+
elif available_metrics_for_analysis:
|
| 1045 |
st.info(
|
| 1046 |
"Select metrics that are available in the dataset to see turn-level analysis."
|
| 1047 |
)
|
|
|
|
| 1064 |
help="Generate comprehensive dataset overview and metric analysis",
|
| 1065 |
)
|
| 1066 |
with col2:
|
| 1067 |
+
if len(available_metrics_for_analysis) > 20:
|
| 1068 |
st.warning("β οΈ Large metric selection - analysis may take some time")
|
| 1069 |
|
| 1070 |
if show_details:
|
|
|
|
| 1104 |
if st.checkbox("Show raw data sample"):
|
| 1105 |
sample_cols = ["type"] + [
|
| 1106 |
f"turn.turn_metrics.{m}"
|
| 1107 |
+
for m in available_metrics_for_analysis
|
| 1108 |
if f"turn.turn_metrics.{m}" in filtered_df_exploded.columns
|
| 1109 |
]
|
| 1110 |
sample_data = filtered_df_exploded[sample_cols].head(100)
|
|
|
|
| 1114 |
st.subheader("π Metric Availability")
|
| 1115 |
|
| 1116 |
metric_completeness = {}
|
| 1117 |
+
for metric in available_metrics_for_analysis:
|
| 1118 |
full_metric_name = f"turn.turn_metrics.{metric}"
|
| 1119 |
if full_metric_name in filtered_df_exploded.columns:
|
| 1120 |
completeness = (
|