import streamlit as st
from transformers import pipeline
from rouge_score import rouge_scorer
import textstat
import plotly.express as px
import plotly.graph_objects as go
from plotly.subplots import make_subplots
import pandas as pd
# -----------------------------
# Page Configuration
# -----------------------------
st.set_page_config(
page_title="Text Evaluation Suite",
page_icon="📊",
layout="wide",
initial_sidebar_state="expanded"
)
# -----------------------------
# Custom CSS for Black & White Theme
# -----------------------------
st.markdown("""
""", unsafe_allow_html=True)
# -----------------------------
# Summarizer Loader (cached)
# -----------------------------
@st.cache_resource
def load_summarizer(model_name):
return pipeline("summarization", model=model_name)
# -----------------------------
# Calculate ROUGE
# -----------------------------
def calculate_rouge(reference, generated):
scorer = rouge_scorer.RougeScorer(["rouge1", "rouge2", "rougeL"], use_stemmer=True)
return scorer.score(reference, generated)
# -----------------------------
# Calculate readability
# -----------------------------
def get_readability_scores(text):
return {
"Flesch Reading Ease": textstat.flesch_reading_ease(text),
"SMOG Index": textstat.smog_index(text),
"Flesch-Kincaid Grade": textstat.flesch_kincaid_grade(text),
"Gunning Fog": textstat.gunning_fog(text),
"Automated Readability": textstat.automated_readability_index(text),
"Coleman-Liau": textstat.coleman_liau_index(text),
"Dale-Chall": textstat.dale_chall_readability_score(text),
}
# -----------------------------
# Enhanced Plotly Theme
# -----------------------------
def create_readability_chart(orig_scores, sum_scores):
categories = list(orig_scores.keys())
fig = go.Figure()
# Add bars for original text
fig.add_trace(go.Bar(
name='Original',
x=categories,
y=list(orig_scores.values()),
marker_color='#ffffff',
marker_line_color='#cccccc',
marker_line_width=2,
hovertemplate='%{x}
Original: %{y:.2f}'
))
# Add bars for summary
fig.add_trace(go.Bar(
name='Summary',
x=categories,
y=list(sum_scores.values()),
marker_color='#666666',
marker_line_color='#444444',
marker_line_width=2,
hovertemplate='%{x}
Summary: %{y:.2f}'
))
fig.update_layout(
title='Readability Analysis Comparison',
title_font_size=20,
title_font_color='#ffffff',
xaxis_title='Readability Metrics',
yaxis_title='Scores',
barmode='group',
plot_bgcolor='#000000',
paper_bgcolor='#000000',
font_color='#ffffff',
xaxis=dict(
gridcolor='#333333',
zeroline=False
),
yaxis=dict(
gridcolor='#333333',
zeroline=False
),
legend=dict(
bgcolor='rgba(0,0,0,0)',
bordercolor='#666666',
borderwidth=1
)
)
return fig
def create_rouge_chart(rouge_scores):
metrics = []
precision_scores = []
recall_scores = []
f1_scores = []
for metric, result in rouge_scores.items():
metrics.append(metric.upper())
precision_scores.append(result.precision)
recall_scores.append(result.recall)
f1_scores.append(result.fmeasure)
fig = go.Figure()
fig.add_trace(go.Bar(
name='Precision',
x=metrics,
y=precision_scores,
marker_color='#ffffff',
hovertemplate='%{x}
Precision: %{y:.3f}'
))
fig.add_trace(go.Bar(
name='Recall',
x=metrics,
y=recall_scores,
marker_color='#aaaaaa',
hovertemplate='%{x}
Recall: %{y:.3f}'
))
fig.add_trace(go.Bar(
name='F1-Score',
x=metrics,
y=f1_scores,
marker_color='#666666',
hovertemplate='%{x}
F1-Score: %{y:.3f}'
))
fig.update_layout(
title='ROUGE Evaluation Metrics',
title_font_size=20,
title_font_color='#ffffff',
xaxis_title='ROUGE Metrics',
yaxis_title='Scores',
barmode='group',
plot_bgcolor='#000000',
paper_bgcolor='#000000',
font_color='#ffffff',
xaxis=dict(
gridcolor='#333333',
zeroline=False
),
yaxis=dict(
gridcolor='#333333',
zeroline=False,
range=[0, 1]
),
legend=dict(
bgcolor='rgba(0,0,0,0)',
bordercolor='#666666',
borderwidth=1
)
)
return fig
# -----------------------------
# Main Application
# -----------------------------
def main():
# Main title
st.markdown('
⭐ Text Evaluation
', unsafe_allow_html=True)
st.markdown('Advanced AI-powered text summarization with comprehensive evaluation metrics
', unsafe_allow_html=True)
# Sidebar configuration
with st.sidebar:
st.markdown("### ⚙️ Configuration")
# Model selection
model_choice = st.selectbox(
"🤖 Summarization Model",
["facebook/bart-large-cnn", "t5-small", "sshleifer/distilbart-cnn-12-6"],
help="Choose the AI model for text summarization"
)
# Summary length
length_choice = st.radio(
"📏 Summary Length",
["Short", "Medium", "Long"],
help="Select the desired length of the generated summary"
)
if length_choice == "Short":
max_len, min_len = 60, 20
elif length_choice == "Medium":
max_len, min_len = 120, 40
else: # Long
max_len, min_len = 200, 80
st.markdown(f"**Length Range:** {min_len}-{max_len} words")
# File upload section
st.markdown('', unsafe_allow_html=True)
uploaded_file = st.file_uploader(
"Upload your text document for analysis",
type=["txt"],
help="Upload a .txt file containing the text you want to summarize and evaluate"
)
if uploaded_file is not None:
# Read and display file info
text = uploaded_file.read().decode("utf-8")
word_count = len(text.split())
char_count = len(text)
col1, col2, col3 = st.columns(3)
with col1:
st.markdown(f'', unsafe_allow_html=True)
with col2:
st.markdown(f'', unsafe_allow_html=True)
with col3:
estimated_time = max(1, word_count // 100)
st.markdown(f'{estimated_time}
Est. Minutes
', unsafe_allow_html=True)
# Generate button
st.markdown("---")
if st.button("🚀 Generate Summary & Analyze", use_container_width=True):
with st.spinner("🔄 Processing your text... This may take a few moments"):
try:
# Load model and generate summary
summarizer = load_summarizer(model_choice)
summary = summarizer(text, max_length=max_len, min_length=min_len, do_sample=False)[0]['summary_text']
# Success message
st.success("✅ Analysis completed successfully!")
# Text comparison section
st.markdown('', unsafe_allow_html=True)
col1, col2 = st.columns(2)
with col1:
st.markdown('', unsafe_allow_html=True)
st.markdown("**📄 Original Text**")
st.text_area("", text, height=300, disabled=True, key="original")
st.markdown('
', unsafe_allow_html=True)
with col2:
st.markdown('', unsafe_allow_html=True)
st.markdown("**✨ Generated Summary**")
st.text_area("", summary, height=300, disabled=True, key="summary")
# Summary stats
summary_words = len(summary.split())
compression_ratio = (1 - summary_words / word_count) * 100
st.markdown(f"**Compression:** {compression_ratio:.1f}% reduction ({summary_words} words)")
st.markdown('
', unsafe_allow_html=True)
# Readability Analysis
st.markdown('', unsafe_allow_html=True)
orig_scores = get_readability_scores(text)
sum_scores = get_readability_scores(summary)
readability_fig = create_readability_chart(orig_scores, sum_scores)
st.plotly_chart(readability_fig, use_container_width=True)
# ROUGE Evaluation
st.markdown('', unsafe_allow_html=True)
rouge_scores = calculate_rouge(text, summary)
# ROUGE metrics cards
cols = st.columns(3)
rouge_metrics = ["rouge1", "rouge2", "rougeL"]
rouge_names = ["ROUGE-1", "ROUGE-2", "ROUGE-L"]
for i, (metric, name) in enumerate(zip(rouge_metrics, rouge_names)):
with cols[i]:
result = rouge_scores[metric]
st.markdown(f'''
{name}
Precision: {result.precision:.3f}
Recall: {result.recall:.3f}
F1-Score: {result.fmeasure:.3f}
''', unsafe_allow_html=True)
# ROUGE chart
rouge_fig = create_rouge_chart(rouge_scores)
st.plotly_chart(rouge_fig, use_container_width=True)
# Performance summary
st.markdown('', unsafe_allow_html=True)
avg_f1 = sum(result.fmeasure for result in rouge_scores.values()) / len(rouge_scores)
if avg_f1 >= 0.5:
performance = "Excellent"
color = "#00ff00"
elif avg_f1 >= 0.3:
performance = "Good"
color = "#ffff00"
else:
performance = "Needs Improvement"
color = "#ff6666"
st.markdown(f'''
Overall Performance: {performance}
Average F1-Score: {avg_f1:.3f}
Model: {model_choice} | Length: {length_choice}
''', unsafe_allow_html=True)
except Exception as e:
st.error(f"❌ An error occurred during processing: {str(e)}")
st.info("💡 Try with a shorter text or different model if the issue persists.")
else:
# Welcome message when no file is uploaded
st.markdown('''
🚀 Ready to Analyze Your Text?
Upload a text file to get started with AI-powered summarization and comprehensive evaluation.
Features:
✨ Advanced AI Summarization | 📊 ROUGE Score Analysis | 📈 Readability Metrics | 🎯 Performance Insights
''', unsafe_allow_html=True)
if __name__ == "__main__":
main()