Spaces:
Sleeping
Sleeping
import streamlit as st | |
import nltk | |
import spacy | |
import matplotlib.pyplot as plt | |
from transformers import pipeline | |
import random | |
import subprocess | |
# Ensure spaCy model is installed | |
try: | |
nlp = spacy.load("en_core_web_sm") | |
except OSError: | |
subprocess.run(["python", "-m", "spacy", "download", "en_core_web_sm"]) | |
nlp = spacy.load("en_core_web_sm") | |
# Ensure NLTK resources are available | |
nltk.download("vader_lexicon") | |
from nltk.sentiment import SentimentIntensityAnalyzer | |
sia = SentimentIntensityAnalyzer() | |
# Load English emotion detection pipeline | |
emotion_pipeline = pipeline("text-classification", model="j-hartmann/emotion-english-distilroberta-base", return_all_scores=True) | |
# Load multilingual sentiment model (returns star ratings 1-5 for non-English texts) | |
multilingual_pipeline = pipeline("text-classification", model="nlptown/bert-base-multilingual-uncased-sentiment") | |
# Sample texts | |
sample_texts = [ | |
"The digital world is transforming the way we read and engage with text.", | |
"Reading is an essential skill that shapes our understanding of the world.", | |
"AI-driven education tools can personalize the learning experience for students." | |
] | |
# Supported languages for multilingual sentiment analysis | |
supported_languages = { | |
"English": "en", | |
"Dutch": "nl", | |
"French": "fr", | |
"German": "de", | |
"Spanish": "es", | |
"Italian": "it" | |
} | |
# Streamlit UI | |
st.title("π AI-Powered Adaptive Reading Engagement") | |
st.write("Analyze how users engage with digital reading using AI-powered insights.") | |
# Language selection | |
selected_language = st.selectbox("Select a language:", list(supported_languages.keys())) | |
# Use session state to store text input | |
if "user_text" not in st.session_state: | |
st.session_state.user_text = "" | |
# Dropdown menu with a new option for "Choose Your Own Text" | |
text_option = st.selectbox("Choose a sample text or enter your own:", ["Choose Your Own Text"] + sample_texts) | |
# Text input limit | |
MAX_WORDS = 100 # Set the max word limit | |
# If user selects a sample text, use it. Otherwise, allow manual input. | |
if text_option == "Choose Your Own Text": | |
text = st.text_area("Enter your own text:", st.session_state.user_text, height=150) | |
else: | |
text = sample_texts[sample_texts.index(text_option)] # Select the chosen sample text | |
# Show word count & limit warning only if the user is entering their own text | |
word_count = len(text.split()) | |
if text_option == "Choose Your Own Text": | |
st.markdown(f'<p style="font-size:12px; color:gray;">β οΈ Limit: {MAX_WORDS} words max.</p>', unsafe_allow_html=True) | |
if word_count > MAX_WORDS: | |
st.warning(f"β οΈ Your input has {word_count} words. Please limit it to {MAX_WORDS} words.") | |
# Save user input in session state only if within limit | |
if text_option == "Choose Your Own Text" and word_count <= MAX_WORDS: | |
st.session_state.user_text = text | |
# Function to convert star ratings (1-5) into emotion categories | |
def convert_star_rating_to_emotion(stars): | |
star_to_emotion = { | |
"1 star": ("very negative", 0.1), | |
"2 stars": ("negative", 0.3), | |
"3 stars": ("neutral", 0.5), | |
"4 stars": ("positive", 0.7), | |
"5 stars": ("very positive", 0.9) | |
} | |
return star_to_emotion.get(stars, ("unknown", 0.0)) | |
# Function to generate AI-driven feedback | |
def generate_feedback(sentiment_score, top_emotion): | |
if sentiment_score['pos'] > 0.6 or top_emotion in ["very positive", "positive", "joy", "optimism"]: | |
return "π Your reading is positive! This text might boost engagement and motivation." | |
elif sentiment_score['neg'] > 0.6 or top_emotion in ["very negative", "negative", "anger", "disgust"]: | |
return "π The text seems to have a strong negative tone. Consider balancing it with positive information." | |
elif top_emotion in ["neutral"]: | |
return "π€ The text is neutral. You might want to explore different perspectives." | |
else: | |
return "βοΈ The analysis is inconclusive. Try refining your text for clearer sentiment." | |
# Sentiment Analysis | |
if st.button("Analyze Engagement"): | |
if text and (text_option != "Choose Your Own Text" or word_count <= MAX_WORDS): | |
# Sentiment Analysis (English) | |
sentiment_score = sia.polarity_scores(text) | |
# Emotion Detection | |
emotion_scores = {} | |
if selected_language == "English": | |
emotion_results = emotion_pipeline(text) | |
top_emotion = max(emotion_results[0], key=lambda x: x['score'])['label'] | |
for e in emotion_results[0]: | |
emotion_scores[e["label"]] = e["score"] | |
else: | |
# Multilingual Sentiment Analysis (Converts Star Ratings to Emotion) | |
multilingual_results = multilingual_pipeline(text) | |
top_emotion, emotion_intensity = convert_star_rating_to_emotion(multilingual_results[0]["label"]) | |
emotion_scores = {top_emotion: emotion_intensity} | |
# Display Sentiment | |
st.subheader("π Sentiment Analysis") | |
st.write(f"Positive: {sentiment_score['pos'] * 100:.2f}%, Negative: {sentiment_score['neg'] * 100:.2f}%, Neutral: {sentiment_score['neu'] * 100:.2f}%") | |
# Display Emotion | |
st.subheader("π Emotion Detection") | |
st.write(f"Top Emotion: **{top_emotion.capitalize()}**") | |
# AI-Generated Feedback | |
st.subheader("π‘ AI-Generated Feedback") | |
feedback = generate_feedback(sentiment_score, top_emotion) | |
st.write(feedback) | |
# π **Visual Display Chart (Fixed & Restored)** | |
if emotion_scores: | |
st.subheader("π Emotion Intensity Chart") | |
fig, ax = plt.subplots() | |
ax.bar(emotion_scores.keys(), emotion_scores.values(), color=["red", "orange", "yellow", "green", "blue"]) | |
ax.set_ylabel("Emotion Intensity") | |
ax.set_xlabel("Emotions") | |
ax.set_title("Emotion Analysis") | |
st.pyplot(fig) | |
elif text_option == "Choose Your Own Text" and word_count > MAX_WORDS: | |
st.warning("β οΈ Please reduce the text length to analyze.") | |
else: | |
st.warning("β οΈ Please enter a text to analyze.") |