|
|
import streamlit as st |
|
|
from transformers import pipeline |
|
|
import re |
|
|
|
|
|
st.set_page_config(page_title="Hindi Sentiment Analysis", layout="centered") |
|
|
|
|
|
|
|
|
st.markdown(""" |
|
|
<style> |
|
|
@import url('https://fonts.googleapis.com/css2?family=Poppins&display=swap'); |
|
|
|
|
|
html, body, [class*="css"] { |
|
|
font-family: 'Poppins', sans-serif; |
|
|
text-align: center; |
|
|
} |
|
|
|
|
|
.centered-title { |
|
|
font-size: 50px; |
|
|
font-weight: bold; |
|
|
margin-bottom: 10px; |
|
|
} |
|
|
|
|
|
.sentiment-result { |
|
|
font-size: 26px; |
|
|
font-weight: 600; |
|
|
margin-top: 20px; |
|
|
} |
|
|
|
|
|
.confidence { |
|
|
font-size: 20px; |
|
|
margin-top: 10px; |
|
|
} |
|
|
|
|
|
.original-text { |
|
|
font-style: italic; |
|
|
margin-top: 10px; |
|
|
} |
|
|
|
|
|
textarea { |
|
|
text-align: left !important; |
|
|
} |
|
|
</style> |
|
|
""", unsafe_allow_html=True) |
|
|
|
|
|
|
|
|
pipe = pipeline("text-classification", model="NeonSamurai/hindi_sentiment_bert_finetuned") |
|
|
|
|
|
names = ["neutral", "positive", "negative"] |
|
|
emojis = {"positive": "🤗", "negative": "😔", "neutral": "😐"} |
|
|
|
|
|
|
|
|
def is_mostly_hindi(text): |
|
|
if not text.strip(): |
|
|
return False |
|
|
devanagari_pattern = r'[\u0900-\u097F]' |
|
|
allowed_pattern = r'[a-zA-Z0-9\s.,!?]' |
|
|
devanagari_chars = len(re.findall(devanagari_pattern, text)) |
|
|
allowed_chars = len(re.findall(allowed_pattern, text)) |
|
|
total_chars = len(text) |
|
|
hindi_proportion = devanagari_chars / total_chars if total_chars > 0 else 0 |
|
|
valid_chars = devanagari_chars + allowed_chars == total_chars |
|
|
return hindi_proportion >= 0.7 and valid_chars |
|
|
|
|
|
def clean_input(text): |
|
|
cleaned_text = re.sub(r'[^a-zA-Z0-9\u0900-\u097F\s?.!]', ' ', text) |
|
|
cleaned_text = re.sub(r'([?.!])(?![?.!]\s|$)', '', cleaned_text) |
|
|
cleaned_text = ' '.join(cleaned_text.split()) |
|
|
return cleaned_text |
|
|
|
|
|
|
|
|
st.markdown("<div class='centered-title'>📊 Hindi Sentiment Analysis</div>", unsafe_allow_html=True) |
|
|
|
|
|
|
|
|
with st.expander("ℹ️ Instructions"): |
|
|
st.markdown(""" |
|
|
- Please enter a sentence or paragraph in **Hindi (Devanagari script)**. |
|
|
- Example: *यह फिल्म बहुत अच्छी थी और अभिनय शानदार था।* |
|
|
- The app will classify the text as **positive**, **negative**, or **neutral**. |
|
|
""") |
|
|
|
|
|
|
|
|
user_input = st.text_area("✍️ Enter Hindi text below:", height=150, placeholder="Type your Hindi text here...") |
|
|
|
|
|
|
|
|
if st.button("🔍 Predict Sentiment"): |
|
|
if not user_input.strip(): |
|
|
st.warning("⚠️ Please enter some text.") |
|
|
else: |
|
|
cleaned_input = clean_input(user_input) |
|
|
if not is_mostly_hindi(cleaned_input): |
|
|
st.error("❌ Input should be primarily in Hindi (Devanagari script).") |
|
|
else: |
|
|
result = int(pipe(cleaned_input)[0]['label'].split("_")[1]) |
|
|
sentiment = names[result] |
|
|
emoji = emojis[sentiment] |
|
|
|
|
|
st.markdown(f"<div class='sentiment-result'>✅ Sentiment: <b>{sentiment.capitalize()} {emoji}</b></div>", unsafe_allow_html=True) |
|
|
st.markdown(f"<div class='confidence'>Confidence Score: <code>{result['score']:.2f}</code></div>", unsafe_allow_html=True) |
|
|
st.markdown(f"<div class='original-text'>“{user_input}”</div>", unsafe_allow_html=True) |
|
|
|
|
|
|
|
|
st.markdown( |
|
|
""" |
|
|
<style> |
|
|
.stApp { |
|
|
background-image: url("https://cdn-uploads.huggingface.co/production/uploads/673f5e166c2774fcc8a82f0b/OIaLFHTZGXeTvsizCCNsK.png"); |
|
|
background-size: cover; |
|
|
background-position: center; |
|
|
height: 100vh; |
|
|
} |
|
|
|
|
|
/* Semi-transparent overlay */ |
|
|
.stApp::before { |
|
|
content: ""; |
|
|
position: absolute; |
|
|
top: 0; |
|
|
left: 0; |
|
|
width: 100%; |
|
|
height: 100%; |
|
|
background: rgba(0, 0, 0, 0.4); /* 40% transparency */ |
|
|
z-index: -1; |
|
|
} |
|
|
</style> |
|
|
""", |
|
|
unsafe_allow_html=True |
|
|
) |