File size: 4,054 Bytes
8103fc7
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
5cdfd0f
8103fc7
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
5cdfd0f
 
8103fc7
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
import streamlit as st
from transformers import pipeline
import re

st.set_page_config(page_title="Hindi Sentiment Analysis", layout="centered")

# Custom CSS for styling
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)

# Load model
pipe = pipeline("text-classification", model="NeonSamurai/hindi_sentiment_bert_finetuned")

names = ["neutral", "positive", "negative"]
emojis = {"positive": "🤗", "negative": "😔", "neutral": "😐"}

# Utility functions
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

# Title
st.markdown("<div class='centered-title'>📊 Hindi Sentiment Analysis</div>", unsafe_allow_html=True)

# Instructions
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**.
    """)

# Text input
user_input = st.text_area("✍️ Enter Hindi text below:", height=150, placeholder="Type your Hindi text here...")

# Predict button
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)

# Background-Image
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
)