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('
📂 Document Upload
', 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'
{word_count:,}
Words
', unsafe_allow_html=True) with col2: st.markdown(f'
{char_count:,}
Characters
', 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('
📖 Text Comparison
', 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('
📊 Readability Analysis
', 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('
📈 ROUGE Evaluation
', 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('
🎯 Performance Summary
', 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()