|
|
import streamlit as st |
|
|
from transformers import pipeline |
|
|
import re |
|
|
|
|
|
st.set_page_config(page_title="Hindi Sentiment Analysis", page_icon="😊") |
|
|
|
|
|
pipe = pipeline("text-classification", model="trohith89/Hindi_Sentiment_3_class") |
|
|
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(""" |
|
|
<style> |
|
|
html, body, .stApp { |
|
|
background-image: url("https://cdn-uploads.huggingface.co/production/uploads/67441c51a784a9d15cb12871/8cwxuMFDAzxohCfoqCxnE.jpeg"); |
|
|
background-size: cover; |
|
|
background-position: center; |
|
|
background-repeat: no-repeat; |
|
|
background-attachment: fixed; |
|
|
font-family: 'Segoe UI', sans-serif; |
|
|
} |
|
|
|
|
|
/* 🌈 Gradient & Animated Title */ |
|
|
h1 { |
|
|
text-align: center; |
|
|
font-size: 56px; |
|
|
background: linear-gradient(to right, #ffb6c1, #ffa07a, #87cefa); |
|
|
-webkit-background-clip: text; |
|
|
-webkit-text-fill-color: transparent; |
|
|
animation: popFadeSlide 2s ease-in-out; |
|
|
margin-bottom: 30px; |
|
|
letter-spacing: 1px; |
|
|
} |
|
|
@keyframes popFadeSlide { |
|
|
0% { |
|
|
opacity: 0; |
|
|
transform: scale(0.9) translateY(-40px); |
|
|
} |
|
|
50% { |
|
|
opacity: 1; |
|
|
transform: scale(1.05) translateY(5px); |
|
|
} |
|
|
100% { |
|
|
transform: scale(1) translateY(0); |
|
|
} |
|
|
} |
|
|
|
|
|
/* 🧾 Instruction Box */ |
|
|
.instructions { |
|
|
text-align: center; |
|
|
font-size: 18px; |
|
|
color: #fff; |
|
|
background: rgba(0, 0, 0, 0.7); |
|
|
padding: 20px; |
|
|
border-radius: 15px; |
|
|
animation: rotateIn 1.5s ease-out; |
|
|
margin-bottom: 25px; |
|
|
max-width: 600px; |
|
|
margin-left: auto; |
|
|
margin-right: auto; |
|
|
} |
|
|
@keyframes rotateIn { |
|
|
0% { opacity: 0; transform: rotateY(-90deg); } |
|
|
100% { opacity: 1; transform: rotateY(0); } |
|
|
} |
|
|
|
|
|
/* 📥 Text Area */ |
|
|
.stTextArea textarea { |
|
|
border: none; |
|
|
outline: none; |
|
|
border-radius: 12px; |
|
|
padding: 15px; |
|
|
background: rgba(42, 42, 42, 0.85); |
|
|
color: #e6e6e6; |
|
|
font-size: 16px; |
|
|
width: 100%; |
|
|
max-width: 800px; |
|
|
height: 160px !important; |
|
|
box-sizing: border-box; |
|
|
transition: all 0.4s ease; |
|
|
} |
|
|
.stTextArea textarea:focus { |
|
|
transform: scale(1.02); |
|
|
box-shadow: 0 0 15px rgba(255, 255, 255, 0.4); |
|
|
} |
|
|
|
|
|
/* 🔘 Button */ |
|
|
div.stButton > button { |
|
|
background: linear-gradient(45deg, #004d00, #000000, #000066); |
|
|
color: #e6e6e6; |
|
|
font-size: 18px; |
|
|
padding: 12px 30px; |
|
|
border: none; |
|
|
border-radius: 30px; |
|
|
display: block; |
|
|
margin: 20px auto; |
|
|
transition: all 0.5s ease; |
|
|
} |
|
|
div.stButton > button:hover { |
|
|
transform: translateY(-5px) rotate(1deg); |
|
|
box-shadow: 0 8px 20px rgba(255, 255, 255, 0.4); |
|
|
background: linear-gradient(45deg, #006600, #333333, #000099); |
|
|
} |
|
|
|
|
|
/* 🎯 Colored Sentiment Output Box */ |
|
|
.output-container { |
|
|
padding: 25px 20px; |
|
|
border-radius: 20px; |
|
|
animation: fadeInUp 1s ease-out; |
|
|
text-align: center; |
|
|
width: 100%; |
|
|
max-width: 650px; |
|
|
margin: 30px auto 10px auto; |
|
|
min-height: 100px; |
|
|
font-size: 45px; |
|
|
font-weight: 700; |
|
|
} |
|
|
@keyframes fadeInUp { |
|
|
0% { opacity: 0; transform: translateY(40px); } |
|
|
100% { opacity: 1; transform: translateY(0); } |
|
|
} |
|
|
.output-positive { |
|
|
background: linear-gradient(45deg, #00ff00, #00cccc); |
|
|
color: #1a1a1a; |
|
|
} |
|
|
.output-negative { |
|
|
background: linear-gradient(45deg, #330066, #666666); |
|
|
color: #e6e6e6; |
|
|
} |
|
|
.output-neutral { |
|
|
background: linear-gradient(45deg, #66ccff, #ffffff); |
|
|
color: #1a1a1a; |
|
|
} |
|
|
|
|
|
/* 📊 Output Info */ |
|
|
.output-info { |
|
|
color: #f1f1f1; |
|
|
font-size: 16px; |
|
|
text-align: center; |
|
|
margin-top: 10px; |
|
|
} |
|
|
</style> |
|
|
""", unsafe_allow_html=True) |
|
|
|
|
|
|
|
|
st.markdown("<h1>Hindi Sentiment Analysis</h1>", unsafe_allow_html=True) |
|
|
|
|
|
st.markdown(""" |
|
|
<div class='instructions'> |
|
|
Please enter a sentence or paragraph in Hindi in the text area below. <br> |
|
|
Text must be primarily in Hindi. <br> |
|
|
Example: "यह फिल्म बहुत अच्छी थी और अभिनय शानदार था। <br> |
|
|
Click the 'Predict' button to analyze the sentiment (positive, negative, or neutral)! |
|
|
</div> |
|
|
""", unsafe_allow_html=True) |
|
|
|
|
|
user_input = st.text_area("", placeholder="Enter your text in Hindi here...") |
|
|
|
|
|
if st.button("Predict"): |
|
|
if not user_input.strip(): |
|
|
st.warning("⚠️ Please enter text. Empty input is not allowed.") |
|
|
else: |
|
|
cleaned_input = clean_input(user_input) |
|
|
if not is_mostly_hindi(cleaned_input): |
|
|
st.error("❌ Please enter text primarily in Hindi (Devanagari script).") |
|
|
else: |
|
|
result = pipe(cleaned_input)[0] |
|
|
sentiment_index = int(result['label'].split("_")[1]) |
|
|
sentiment = names[sentiment_index] |
|
|
emoji = emojis[sentiment] |
|
|
output_class = f"output-{sentiment}" |
|
|
st.markdown(f"<div class='output-container {output_class}'>{sentiment.capitalize()} {emoji}</div>", unsafe_allow_html=True) |
|
|
st.markdown(f"<div class='output-info'><strong>Your Text:</strong> {user_input}<br><strong>Confidence Score:</strong> {result['score']:.2f}</div>", unsafe_allow_html=True) |