File size: 7,910 Bytes
3bc0305
3dc2123
 
51ebb55
 
 
94adeb8
3dc2123
 
51ebb55
 
 
 
3dc2123
51ebb55
 
 
3dc2123
51ebb55
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
3dc2123
51ebb55
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
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
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
import gradio as gr
from transformers import pipeline

# --- Model Loading ---
# Using the model ID you've been working with, which is fine-tuned on an English dataset (IMDB).
# It's crucial that this model is indeed fine-tuned for sentiment analysis in English.
MODEL_ID = "Light-Dav/sentiment-analysis-full-project"

try:
    # Attempt to load the pipeline. This needs to be outside the function for efficiency.
    # The 'return_all_scores=True' is important for getting scores for all labels.
    sentiment_analyzer = pipeline("sentiment-analysis", model=MODEL_ID, return_all_scores=True)
    model_loaded_successfully = True
except Exception as e:
    print(f"Error loading model: {e}")
    sentiment_analyzer = None
    model_loaded_successfully = False

# --- Custom CSS for a unique look ---
custom_css = """
body {
    background-color: #f0f2f5; /* Light grey background */
}
.gradio-container {
    box-shadow: 0 4px 8px rgba(0, 0, 0, 0.1);
    border-radius: 15px;
    overflow: hidden;
    background-color: #ffffff; /* White card background */
}
h1, h2, h3 {
    color: #4CAF50; /* Green accents */
    text-align: center;
    font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif;
    animation: fadeIn 1s ease-in-out;
}
.gr-button.primary {
    background-color: #4CAF50 !important;
    color: white !important;
    border-radius: 8px;
    transition: background-color 0.3s ease;
}
.gr-button.primary:hover {
    background-color: #45a049 !important;
}
.gradio-output {
    border: 1px solid #e0e0e0;
    border-radius: 10px;
    padding: 15px;
    margin-top: 20px;
    background-color: #f9f9f9;
}
.sentiment-display {
    text-align: center;
    padding: 10px;
    border-radius: 8px;
    margin-top: 15px;
    font-size: 1.2em;
    font-weight: bold;
}
.sentiment-positive {
    background-color: #e6ffe6; /* Light green */
    color: #28a745; /* Darker green */
}
.sentiment-negative {
    background-color: #ffe6e6; /* Light red */
    color: #dc3545; /* Darker red */
}
.sentiment-neutral {
    background-color: #e6f7ff; /* Light blue */
    color: #007bff; /* Darker blue */
}
@keyframes fadeIn {
    from { opacity: 0; }
    to { opacity: 1; }
}
"""

# --- Helper Function for Sentiment Interpretation ---
def interpret_sentiment(label, score):
    emoji = ""
    description = ""
    color_class = ""

    if label.lower() == "positive": # Your model might output 'LABEL_2' or 'POS'
        emoji = "😊"
        description = "This text expresses a **highly positive** sentiment." if score > 0.9 else "This text expresses a **positive** sentiment."
        color_class = "sentiment-positive"
    elif label.lower() == "negative": # Your model might output 'LABEL_0' or 'NEG'
        emoji = "😠"
        description = "This text expresses a **highly negative** sentiment." if score > 0.9 else "This text expresses a **negative** sentiment."
        color_class = "sentiment-negative"
    elif label.lower() == "neutral": # Your model might output 'LABEL_1' or 'NEUTRAL'
        emoji = "😐"
        description = "This text expresses a **neutral** sentiment."
        color_class = "sentiment-neutral"
    else:
        emoji = "❓"
        description = "Could not confidently determine sentiment."
        color_class = ""
    
    return f"<div class='sentiment-display {color_class}'>{emoji} {label.upper()} ({score:.2f})</div>" + \
           f"<p>{description}</p>"

# --- Sentiment Analysis Function ---
def analyze_sentiment(text):
    if not model_loaded_successfully:
        return {
            "Overall Sentiment": "<div class='sentiment-display'>⚠️ Model Not Loaded ⚠️</div><p>Please contact the administrator. The sentiment analysis model failed to load.</p>",
            "Confidence Scores": {},
            "Raw Output": "Model loading failed."
        }

    if not text.strip():
        return {
            "Overall Sentiment": "<div class='sentiment-display'>✍️ Please enter some text! ✍️</div><p>Start typing to analyze its sentiment.</p>",
            "Confidence Scores": {},
            "Raw Output": ""
        }

    try:
        # The pipeline returns a list of dictionaries if return_all_scores=True
        # e.g., [[{'label': 'LABEL_0', 'score': 0.9}, {'label': 'LABEL_1', 'score': 0.05}]]
        results = sentiment_analyzer(text)[0] # Get the first (and only) list of results

        # Sort results by score in descending order
        results_sorted = sorted(results, key=lambda x: x['score'], reverse=True)

        # Get the top sentiment
        top_sentiment = results_sorted[0]
        label = top_sentiment['label']
        score = top_sentiment['score']

        # Format for Gradio Label component (Dictionary {label: score})
        # This is for the 'Confidence Scores' output
        confidence_scores_output = {item['label']: item['score'] for item in results}

        # Interpret sentiment for the 'Overall Sentiment' output
        overall_sentiment_display = interpret_sentiment(label, score)

        return {
            "Overall Sentiment": overall_sentiment_display,
            "Confidence Scores": confidence_scores_output,
            "Raw Output": str(results)
        }
    except Exception as e:
        return {
            "Overall Sentiment": f"<div class='sentiment-display'>❌ Error ❌</div><p>An error occurred during analysis: {e}</p>",
            "Confidence Scores": {},
            "Raw Output": f"Error: {e}"
        }

# --- Gradio Interface ---
with gr.Blocks(css=custom_css, theme=gr.themes.Soft()) as demo: # Using gr.Blocks for more layout control
    gr.Markdown("# ✨ Sentiment Spark ✨")
    gr.Markdown("---")
    gr.Markdown("### Uncover the emotional tone of your English text instantly!")

    with gr.Row(): # Horizontal layout for input and outputs
        with gr.Column(scale=2):
            text_input = gr.Textbox(
                lines=7,
                placeholder="Type your English text here...",
                label="Your Text",
                interactive=True,
                value="This movie was absolutely brilliant! A masterpiece of storytelling and emotion."
            )
            analyze_btn = gr.Button("Analyze Sentiment", variant="primary") # The main action button

            gr.Markdown("---")
            gr.Markdown("### Try some examples:")
            gr.Examples(
                examples=[
                    ["This product exceeded my expectations, truly amazing!"],
                    ["I found the customer service to be quite disappointing and slow."],
                    ["The weather forecast predicts light rain for tomorrow morning."],
                    ["What a fantastic experience! Highly recommend it."],
                    ["I'm so frustrated with this slow internet connection."],
                    ["The meeting concluded without any major decisions."]
                ],
                inputs=text_input,
                cache_examples=True # Caching examples for faster loading
            )

        with gr.Column(scale=3):
            gr.Markdown("## πŸ“ˆ Analysis Results πŸ“‰")
            overall_sentiment_output = gr.HTML(label="Overall Sentiment") # Using HTML to render custom styled sentiment
            confidence_scores_output = gr.Label(num_top_classes=3, label="Confidence Scores") # Default Gradio Label
            raw_output = gr.JSON(label="Raw Model Output", visible=False) # For debugging/advanced users

    # --- Event Listeners ---
    text_input.change(
        fn=analyze_sentiment,
        inputs=text_input,
        outputs=[overall_sentiment_output, confidence_scores_output, raw_output],
        # live=True # Uncomment for live updates as user types (can be resource intensive)
    )
    analyze_btn.click(
        fn=analyze_sentiment,
        inputs=text_input,
        outputs=[overall_sentiment_output, confidence_scores_output, raw_output]
    )

demo.launch()