Spaces:
Build error
Build error
Ryan commited on
Commit ·
9a92712
1
Parent(s): 916f9cc
update
Browse files- app.py +44 -25
- ui/roberta_screen.py +8 -5
- visualization/roberta_visualizer.py +68 -70
app.py
CHANGED
|
@@ -586,25 +586,27 @@ def create_app():
|
|
| 586 |
gr.update(visible=True, value=f"❌ **Error during analysis:**\n\n```\n{str(e)}\n```") # status_message
|
| 587 |
)
|
| 588 |
|
| 589 |
-
# RoBERTa Sentiment Analysis Tab (
|
| 590 |
with gr.Tab("RoBERTa Sentiment"):
|
| 591 |
# Create the RoBERTa analysis UI components
|
| 592 |
run_roberta_btn, roberta_output, sentence_level, visualization_style, visualization_container, roberta_status = create_roberta_screen()
|
| 593 |
|
| 594 |
-
#
|
| 595 |
with gr.Column() as roberta_viz_container:
|
| 596 |
-
|
|
|
|
|
|
|
| 597 |
|
| 598 |
-
# Function to run RoBERTa sentiment analysis
|
| 599 |
def run_roberta_analysis(dataset, sentence_level, visualization_style):
|
| 600 |
try:
|
| 601 |
if not dataset or "entries" not in dataset or not dataset["entries"]:
|
| 602 |
return (
|
| 603 |
{}, # roberta_results_state
|
| 604 |
-
True, #
|
| 605 |
-
gr.update(visible=
|
| 606 |
-
False, #
|
| 607 |
-
|
| 608 |
)
|
| 609 |
|
| 610 |
print(f"Running RoBERTa sentiment analysis with sentence-level={sentence_level}, style={visualization_style}")
|
|
@@ -616,23 +618,40 @@ def create_app():
|
|
| 616 |
if "error" in roberta_results:
|
| 617 |
return (
|
| 618 |
roberta_results, # Store in state anyway for debugging
|
| 619 |
-
True, #
|
| 620 |
-
gr.update(visible=
|
| 621 |
-
False, #
|
| 622 |
-
|
| 623 |
)
|
| 624 |
|
| 625 |
-
#
|
| 626 |
viz_components = process_and_visualize_sentiment_analysis(roberta_results)
|
| 627 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 628 |
return (
|
| 629 |
roberta_results, # roberta_results_state
|
| 630 |
-
False, #
|
| 631 |
-
gr.update(visible=False), #
|
| 632 |
-
|
| 633 |
-
|
| 634 |
)
|
| 635 |
-
|
| 636 |
except Exception as e:
|
| 637 |
import traceback
|
| 638 |
error_msg = f"Error in RoBERTa analysis: {str(e)}\n{traceback.format_exc()}"
|
|
@@ -640,22 +659,22 @@ def create_app():
|
|
| 640 |
|
| 641 |
return (
|
| 642 |
{"error": error_msg}, # roberta_results_state
|
| 643 |
-
True, #
|
| 644 |
-
gr.update(visible=
|
| 645 |
-
False, #
|
| 646 |
-
|
| 647 |
)
|
| 648 |
|
| 649 |
-
# Connect the run button to the analysis function
|
| 650 |
run_roberta_btn.click(
|
| 651 |
fn=run_roberta_analysis,
|
| 652 |
inputs=[dataset_state, sentence_level, visualization_style],
|
| 653 |
outputs=[
|
| 654 |
roberta_results_state,
|
| 655 |
-
gr.Checkbox(visible=False, value=False), # Hidden checkbox for status visibility
|
| 656 |
roberta_status,
|
| 657 |
roberta_output,
|
| 658 |
-
|
|
|
|
| 659 |
]
|
| 660 |
)
|
| 661 |
|
|
|
|
| 586 |
gr.update(visible=True, value=f"❌ **Error during analysis:**\n\n```\n{str(e)}\n```") # status_message
|
| 587 |
)
|
| 588 |
|
| 589 |
+
# RoBERTa Sentiment Analysis Tab (FIXED)
|
| 590 |
with gr.Tab("RoBERTa Sentiment"):
|
| 591 |
# Create the RoBERTa analysis UI components
|
| 592 |
run_roberta_btn, roberta_output, sentence_level, visualization_style, visualization_container, roberta_status = create_roberta_screen()
|
| 593 |
|
| 594 |
+
# Create a container for visualization results
|
| 595 |
with gr.Column() as roberta_viz_container:
|
| 596 |
+
# We'll create placeholder components to update
|
| 597 |
+
roberta_viz_title = gr.Markdown("## RoBERTa Sentiment Analysis Results", visible=False)
|
| 598 |
+
roberta_viz_content = gr.HTML("", visible=False)
|
| 599 |
|
| 600 |
+
# Function to run RoBERTa sentiment analysis (FIXED)
|
| 601 |
def run_roberta_analysis(dataset, sentence_level, visualization_style):
|
| 602 |
try:
|
| 603 |
if not dataset or "entries" not in dataset or not dataset["entries"]:
|
| 604 |
return (
|
| 605 |
{}, # roberta_results_state
|
| 606 |
+
gr.update(visible=True, value="❌ **Error:** No dataset loaded. Please create or load a dataset first."), # roberta_status
|
| 607 |
+
gr.update(visible=False), # roberta_output
|
| 608 |
+
gr.update(visible=False), # roberta_viz_title
|
| 609 |
+
gr.update(visible=False) # roberta_viz_content
|
| 610 |
)
|
| 611 |
|
| 612 |
print(f"Running RoBERTa sentiment analysis with sentence-level={sentence_level}, style={visualization_style}")
|
|
|
|
| 618 |
if "error" in roberta_results:
|
| 619 |
return (
|
| 620 |
roberta_results, # Store in state anyway for debugging
|
| 621 |
+
gr.update(visible=True, value=f"❌ **Error:** {roberta_results['error']}"), # roberta_status
|
| 622 |
+
gr.update(visible=False), # Hide raw output
|
| 623 |
+
gr.update(visible=False), # roberta_viz_title
|
| 624 |
+
gr.update(visible=False) # roberta_viz_content
|
| 625 |
)
|
| 626 |
|
| 627 |
+
# Process the visualization
|
| 628 |
viz_components = process_and_visualize_sentiment_analysis(roberta_results)
|
| 629 |
|
| 630 |
+
# Convert the visualization components to HTML
|
| 631 |
+
html_content = "<div class='sentiment-visualization'>"
|
| 632 |
+
|
| 633 |
+
for component in viz_components:
|
| 634 |
+
if isinstance(component, gr.Markdown):
|
| 635 |
+
# Convert Markdown to HTML
|
| 636 |
+
html_content += f"<div class='markdown-content'>{component.value}</div>"
|
| 637 |
+
elif isinstance(component, gr.Plot):
|
| 638 |
+
# For Plot components, add a placeholder message
|
| 639 |
+
html_content += "<div class='plot-placeholder'>Sentiment plot will appear here</div>"
|
| 640 |
+
elif isinstance(component, gr.HTML):
|
| 641 |
+
# Directly include HTML components
|
| 642 |
+
html_content += component.value
|
| 643 |
+
|
| 644 |
+
html_content += "</div>"
|
| 645 |
+
|
| 646 |
+
# Return updated values
|
| 647 |
return (
|
| 648 |
roberta_results, # roberta_results_state
|
| 649 |
+
gr.update(visible=False), # roberta_status (hide status message)
|
| 650 |
+
gr.update(visible=False), # roberta_output (hide raw output)
|
| 651 |
+
gr.update(visible=True), # roberta_viz_title (show title)
|
| 652 |
+
gr.update(visible=True, value=html_content) # roberta_viz_content (show content)
|
| 653 |
)
|
| 654 |
+
|
| 655 |
except Exception as e:
|
| 656 |
import traceback
|
| 657 |
error_msg = f"Error in RoBERTa analysis: {str(e)}\n{traceback.format_exc()}"
|
|
|
|
| 659 |
|
| 660 |
return (
|
| 661 |
{"error": error_msg}, # roberta_results_state
|
| 662 |
+
gr.update(visible=True, value=f"❌ **Error during RoBERTa analysis:**\n\n```\n{str(e)}\n```"), # roberta_status
|
| 663 |
+
gr.update(visible=False), # Hide raw output
|
| 664 |
+
gr.update(visible=False), # roberta_viz_title
|
| 665 |
+
gr.update(visible=False) # roberta_viz_content
|
| 666 |
)
|
| 667 |
|
| 668 |
+
# Connect the run button to the analysis function (FIXED)
|
| 669 |
run_roberta_btn.click(
|
| 670 |
fn=run_roberta_analysis,
|
| 671 |
inputs=[dataset_state, sentence_level, visualization_style],
|
| 672 |
outputs=[
|
| 673 |
roberta_results_state,
|
|
|
|
| 674 |
roberta_status,
|
| 675 |
roberta_output,
|
| 676 |
+
roberta_viz_title,
|
| 677 |
+
roberta_viz_content
|
| 678 |
]
|
| 679 |
)
|
| 680 |
|
ui/roberta_screen.py
CHANGED
|
@@ -9,7 +9,7 @@ def create_roberta_screen():
|
|
| 9 |
Create the RoBERTa sentiment analysis screen components
|
| 10 |
|
| 11 |
Returns:
|
| 12 |
-
tuple: (run_roberta_btn, roberta_output,
|
| 13 |
"""
|
| 14 |
with gr.Column() as roberta_screen:
|
| 15 |
gr.Markdown("## RoBERTa Sentiment Analysis")
|
|
@@ -42,14 +42,17 @@ def create_roberta_screen():
|
|
| 42 |
# Run button in its own column for better visibility
|
| 43 |
run_roberta_btn = gr.Button("Run Sentiment Analysis", variant="primary", size="large")
|
| 44 |
|
|
|
|
|
|
|
|
|
|
| 45 |
# Hidden output to store raw analysis results
|
| 46 |
roberta_output = gr.JSON(label="Sentiment Analysis Results", visible=False)
|
| 47 |
|
| 48 |
-
#
|
|
|
|
| 49 |
visualization_container = gr.Markdown(visible=False)
|
| 50 |
-
status_message = gr.Markdown(visible=False)
|
| 51 |
|
| 52 |
-
return run_roberta_btn, roberta_output, sentence_level, visualization_style, visualization_container,
|
| 53 |
|
| 54 |
def process_roberta_request(dataset, sentence_level=True, visualization_style="Standard"):
|
| 55 |
"""
|
|
@@ -122,4 +125,4 @@ def process_roberta_request(dataset, sentence_level=True, visualization_style="S
|
|
| 122 |
}
|
| 123 |
}
|
| 124 |
}
|
| 125 |
-
}
|
|
|
|
| 9 |
Create the RoBERTa sentiment analysis screen components
|
| 10 |
|
| 11 |
Returns:
|
| 12 |
+
tuple: (run_roberta_btn, roberta_output, sentence_level, visualization_style, visualization_container, roberta_status)
|
| 13 |
"""
|
| 14 |
with gr.Column() as roberta_screen:
|
| 15 |
gr.Markdown("## RoBERTa Sentiment Analysis")
|
|
|
|
| 42 |
# Run button in its own column for better visibility
|
| 43 |
run_roberta_btn = gr.Button("Run Sentiment Analysis", variant="primary", size="large")
|
| 44 |
|
| 45 |
+
# Status message area
|
| 46 |
+
roberta_status = gr.Markdown(visible=False)
|
| 47 |
+
|
| 48 |
# Hidden output to store raw analysis results
|
| 49 |
roberta_output = gr.JSON(label="Sentiment Analysis Results", visible=False)
|
| 50 |
|
| 51 |
+
# Placeholder for visualization container - this won't be directly updated
|
| 52 |
+
# but is included for backward compatibility
|
| 53 |
visualization_container = gr.Markdown(visible=False)
|
|
|
|
| 54 |
|
| 55 |
+
return run_roberta_btn, roberta_output, sentence_level, visualization_style, visualization_container, roberta_status
|
| 56 |
|
| 57 |
def process_roberta_request(dataset, sentence_level=True, visualization_style="Standard"):
|
| 58 |
"""
|
|
|
|
| 125 |
}
|
| 126 |
}
|
| 127 |
}
|
| 128 |
+
}
|
visualization/roberta_visualizer.py
CHANGED
|
@@ -43,89 +43,83 @@ def create_sentiment_visualization(analysis_results):
|
|
| 43 |
if len(models) >= 2:
|
| 44 |
output_components.append(gr.Markdown(f"### RoBERTa Sentiment Analysis: Comparing {models[0]} and {models[1]}"))
|
| 45 |
|
| 46 |
-
# Create
|
| 47 |
sa_data = sentiment_results.get("sentiment_analysis", {})
|
| 48 |
if sa_data and len(models) >= 2:
|
| 49 |
# Extract sentiment scores and labels for comparison
|
| 50 |
model_data = []
|
| 51 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 52 |
for model_name in models:
|
| 53 |
if model_name in sa_data:
|
| 54 |
model_result = sa_data[model_name]
|
| 55 |
-
|
| 56 |
-
|
| 57 |
-
|
| 58 |
-
|
| 59 |
-
|
| 60 |
-
|
| 61 |
-
|
| 62 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 63 |
|
| 64 |
-
|
| 65 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 66 |
|
| 67 |
-
# Create gauge
|
| 68 |
-
|
| 69 |
|
| 70 |
-
# Add
|
| 71 |
-
for
|
| 72 |
-
#
|
| 73 |
-
|
|
|
|
| 74 |
|
| 75 |
-
|
| 76 |
-
|
| 77 |
-
|
| 78 |
-
|
| 79 |
-
|
| 80 |
-
|
| 81 |
-
|
| 82 |
-
|
| 83 |
-
|
| 84 |
-
|
| 85 |
-
|
| 86 |
-
|
| 87 |
-
},
|
| 88 |
-
"steps": [
|
| 89 |
-
{"range": [-2, -0.5], "color": "rgba(255, 0, 0, 0.2)"},
|
| 90 |
-
{"range": [-0.5, 0.5], "color": "rgba(128, 128, 128, 0.2)"},
|
| 91 |
-
{"range": [0.5, 2], "color": "rgba(0, 128, 0, 0.2)"}
|
| 92 |
-
]
|
| 93 |
-
},
|
| 94 |
-
domain={"row": 0, "column": i}
|
| 95 |
-
))
|
| 96 |
-
|
| 97 |
-
# Layout adjustments
|
| 98 |
-
fig.update_layout(
|
| 99 |
-
title="Sentiment Score Comparison",
|
| 100 |
-
grid={"rows": 1, "columns": len(df), "pattern": "independent"},
|
| 101 |
-
height=300,
|
| 102 |
-
margin=dict(t=70, b=30, l=30, r=30)
|
| 103 |
-
)
|
| 104 |
-
|
| 105 |
-
output_components.append(gr.Plot(value=fig))
|
| 106 |
-
|
| 107 |
-
# Create detailed scores visualization
|
| 108 |
-
fig2 = make_subplots(rows=1, cols=len(df),
|
| 109 |
-
subplot_titles=[f"{row['model']} Detailed Scores" for i, row in df.iterrows()])
|
| 110 |
-
|
| 111 |
-
for i, row in df.iterrows():
|
| 112 |
-
fig2.add_trace(
|
| 113 |
-
go.Bar(
|
| 114 |
-
x=["Contradiction (Negative)", "Neutral", "Entailment (Positive)"],
|
| 115 |
-
y=[row["contradiction"], row["neutral"], row["entailment"]],
|
| 116 |
-
marker_color=["rgba(255, 0, 0, 0.6)", "rgba(128, 128, 128, 0.6)", "rgba(0, 128, 0, 0.6)"]
|
| 117 |
-
),
|
| 118 |
-
row=1, col=i+1
|
| 119 |
-
)
|
| 120 |
|
| 121 |
-
|
| 122 |
-
title="RoBERTa Classification Scores",
|
| 123 |
-
showlegend=False,
|
| 124 |
-
height=350,
|
| 125 |
-
margin=dict(t=70, b=30, l=30, r=30)
|
| 126 |
-
)
|
| 127 |
|
| 128 |
-
output_components.append(gr.
|
| 129 |
|
| 130 |
# Display comparison summary
|
| 131 |
if "comparison" in sentiment_results:
|
|
@@ -237,4 +231,8 @@ def process_and_visualize_sentiment_analysis(analysis_results):
|
|
| 237 |
import traceback
|
| 238 |
error_msg = f"Sentiment visualization error: {str(e)}\n{traceback.format_exc()}"
|
| 239 |
print(error_msg)
|
| 240 |
-
return [
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 43 |
if len(models) >= 2:
|
| 44 |
output_components.append(gr.Markdown(f"### RoBERTa Sentiment Analysis: Comparing {models[0]} and {models[1]}"))
|
| 45 |
|
| 46 |
+
# Create text-based summary of sentiment scores
|
| 47 |
sa_data = sentiment_results.get("sentiment_analysis", {})
|
| 48 |
if sa_data and len(models) >= 2:
|
| 49 |
# Extract sentiment scores and labels for comparison
|
| 50 |
model_data = []
|
| 51 |
|
| 52 |
+
summary_html = "<div style='margin: 20px 0; padding: 15px; background-color: #f8f9fa; border-radius: 5px;'>"
|
| 53 |
+
summary_html += "<h4 style='margin-top: 0;'>Sentiment Score Comparison</h4>"
|
| 54 |
+
summary_html += "<table style='width: 100%; border-collapse: collapse;'>"
|
| 55 |
+
summary_html += "<tr><th style='text-align: left; padding: 8px; border-bottom: 1px solid #ddd;'>Model</th>"
|
| 56 |
+
summary_html += "<th style='text-align: center; padding: 8px; border-bottom: 1px solid #ddd;'>Sentiment Score</th>"
|
| 57 |
+
summary_html += "<th style='text-align: center; padding: 8px; border-bottom: 1px solid #ddd;'>Label</th></tr>"
|
| 58 |
+
|
| 59 |
for model_name in models:
|
| 60 |
if model_name in sa_data:
|
| 61 |
model_result = sa_data[model_name]
|
| 62 |
+
score = model_result.get("sentiment_score", 0)
|
| 63 |
+
label = model_result.get("label", "neutral").capitalize()
|
| 64 |
+
|
| 65 |
+
# Set color based on sentiment
|
| 66 |
+
if label.lower() == "positive":
|
| 67 |
+
color = "green"
|
| 68 |
+
elif label.lower() == "negative":
|
| 69 |
+
color = "red"
|
| 70 |
+
else:
|
| 71 |
+
color = "gray"
|
| 72 |
+
|
| 73 |
+
summary_html += f"<tr>"
|
| 74 |
+
summary_html += f"<td style='padding: 8px; border-bottom: 1px solid #ddd;'>{model_name}</td>"
|
| 75 |
+
summary_html += f"<td style='text-align: center; padding: 8px; border-bottom: 1px solid #ddd;'>{score:.2f}</td>"
|
| 76 |
+
summary_html += f"<td style='text-align: center; padding: 8px; border-bottom: 1px solid #ddd; color: {color}; font-weight: bold;'>{label}</td>"
|
| 77 |
+
summary_html += f"</tr>"
|
| 78 |
|
| 79 |
+
summary_html += "</table></div>"
|
| 80 |
+
output_components.append(gr.HTML(summary_html))
|
| 81 |
+
|
| 82 |
+
# Create HTML-based score comparison gauge
|
| 83 |
+
model_scores = []
|
| 84 |
+
for model_name in models:
|
| 85 |
+
if model_name in sa_data:
|
| 86 |
+
score = sa_data[model_name].get("sentiment_score", 0)
|
| 87 |
+
model_scores.append((model_name, score))
|
| 88 |
+
|
| 89 |
+
if len(model_scores) >= 2:
|
| 90 |
+
gauge_html = "<div style='margin: 20px 0; padding: 15px; background-color: #f8f9fa; border-radius: 5px;'>"
|
| 91 |
+
gauge_html += "<h4 style='text-align: center; margin-top: 0;'>Sentiment Scale</h4>"
|
| 92 |
+
gauge_html += "<div style='display: flex; justify-content: space-between; margin-bottom: 5px;'>"
|
| 93 |
+
gauge_html += "<span>Very Negative (-2.0)</span>"
|
| 94 |
+
gauge_html += "<span>Neutral (0.0)</span>"
|
| 95 |
+
gauge_html += "<span>Very Positive (2.0)</span>"
|
| 96 |
+
gauge_html += "</div>"
|
| 97 |
|
| 98 |
+
# Create the gauge background
|
| 99 |
+
gauge_html += "<div style='position: relative; width: 100%; height: 30px; background: linear-gradient(to right, #d73027, #f46d43, #fdae61, #fee08b, #ffffbf, #d9ef8b, #a6d96a, #66bd63, #1a9850); border-radius: 5px;'>"
|
| 100 |
|
| 101 |
+
# Add model markers
|
| 102 |
+
for model_name, score in model_scores:
|
| 103 |
+
# Calculate position (0-100%)
|
| 104 |
+
position = ((score + 2.0) / 4.0) * 100
|
| 105 |
+
position = max(0, min(100, position)) # Clamp between 0-100%
|
| 106 |
|
| 107 |
+
# Calculate color
|
| 108 |
+
if score > 0.5:
|
| 109 |
+
color = "#006400" # Dark green
|
| 110 |
+
elif score < -0.5:
|
| 111 |
+
color = "#8B0000" # Dark red
|
| 112 |
+
else:
|
| 113 |
+
color = "#000000" # Black
|
| 114 |
+
|
| 115 |
+
gauge_html += f"<div style='position: absolute; left: {position}%; transform: translateX(-50%); top: 0;'>"
|
| 116 |
+
gauge_html += f"<div style='width: 3px; height: 30px; background-color: {color};'></div>"
|
| 117 |
+
gauge_html += f"<div style='position: absolute; top: 100%; left: 50%; transform: translateX(-50%); white-space: nowrap; font-weight: bold; color: {color};'>{model_name}: {score:.2f}</div>"
|
| 118 |
+
gauge_html += "</div>"
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 119 |
|
| 120 |
+
gauge_html += "</div></div>"
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 121 |
|
| 122 |
+
output_components.append(gr.HTML(gauge_html))
|
| 123 |
|
| 124 |
# Display comparison summary
|
| 125 |
if "comparison" in sentiment_results:
|
|
|
|
| 231 |
import traceback
|
| 232 |
error_msg = f"Sentiment visualization error: {str(e)}\n{traceback.format_exc()}"
|
| 233 |
print(error_msg)
|
| 234 |
+
return [
|
| 235 |
+
gr.Markdown(f"**Error during sentiment visualization:**"),
|
| 236 |
+
gr.HTML(f"<div style='background-color: #FEE; padding: 10px; border-radius: 5px; border: 1px solid #F88;'>" +
|
| 237 |
+
f"<pre style='white-space: pre-wrap; overflow-wrap: break-word;'>{str(e)}</pre></div>")
|
| 238 |
+
]
|