zafirabdullah12's picture
Update app.py
d44ba12 verified
# Importing Libraries
import os
import sys
import io
os.environ['CUDA_VISIBLE_DEVICES'] = '-1'
os.environ['TF_ENABLE_ONEDNN_OPTS'] = '0'
os.environ['TF_CPP_MIN_LOG_LEVEL'] = '3'
os.environ['GRADIO_HOT_RELOAD'] = 'false'
os.environ['WRAPT_DISABLE_EXTENSIONS'] = 'true'
os.environ['PYTHONWARNINGS'] = 'ignore'
import re
import nltk
import pickle
import string
import warnings
import numpy as np
import gradio as gr
from keras.models import load_model
from keras.preprocessing.sequence import pad_sequences
# Suppress all warnings
warnings.filterwarnings('ignore')
warnings.simplefilter('ignore')
# Constants
MAX_LEN = 100
MODEL_PATH = "sentiment_analysis_best.keras"
TOKENIZER_PATH = "tokenizer.pkl"
nltk.download('stopwords', quiet=True)
# Expand common English contractions
def expand_contractions(text):
contractions = {
"i'm": "i am", "you're": "you are", "he's": "he is",
"she's": "she is", "it's": "it is", "we're": "we are",
"they're": "they are", "i've": "i have", "you've": "you have",
"we've": "we have", "they've": "they have", "i'll": "i will",
"you'll": "you will", "he'll": "he will", "she'll": "she will",
"we'll": "we will", "they'll": "they will", "i'd": "i would",
"you'd": "you would", "he'd": "he would", "she'd": "she would",
"we'd": "we would", "they'd": "they would", "don't": "do not",
"doesn't": "does not", "didn't": "did not", "can't": "cannot",
"couldn't": "could not", "won't": "will not", "wouldn't": "would not",
"shouldn't": "should not", "isn't": "is not", "aren't": "are not",
"wasn't": "was not", "weren't": "were not", "hasn't": "has not",
"haven't": "have not", "hadn't": "had not", "mightn't": "might not",
"mustn't": "must not", "needn't": "need not", "shan't": "shall not"
}
for contraction, expansion in contractions.items():
text = re.sub(r'\b' + contraction + r'\b', expansion, text, flags=re.IGNORECASE)
return text
# Preprocessing Function
def preprocess(text):
negations = {"not", "no", "nor", "never", "n't", "nobody", "nothing", "neither", "nowhere", "none"}
important_words = {"am", "is", "are", "was", "were", "be", "been", "being"}
try:
from nltk.corpus import stopwords
stop_words = set(stopwords.words("english")) - negations - important_words
except:
stop_words = set()
text = text.lower()
text = expand_contractions(text)
text = re.sub(r"\d+", "", text)
text = text.translate(str.maketrans('', '', string.punctuation))
words = [w for w in text.split() if w not in stop_words or w in negations or w in important_words]
return " ".join(words)
# Load Train Model and Tokenizer
def load_resources():
try:
model = load_model(MODEL_PATH)
print(f"βœ“ Model loaded successfully from {MODEL_PATH}")
with open(TOKENIZER_PATH, "rb") as f:
tokenizer = pickle.load(f)
print(f"βœ“ Tokenizer loaded successfully from {TOKENIZER_PATH}")
return model, tokenizer
except FileNotFoundError as e:
print(f"βœ— Error: Model or Tokenizer file not found!")
print(f" Make sure {MODEL_PATH} AND {TOKENIZER_PATH} are in the same directory.")
raise e
except Exception as e:
print(f"βœ— Error loading resources: {e}")
raise e
# Load model and tokenizer globally
model, tokenizer = load_resources()
# Prediction Function
def predict_sentiment(text):
if not text or not text.strip():
return "⚠️ Neutral", "33.33%", "Please enter some text to analyze!"
processed_text = preprocess(text)
if not processed_text.strip():
return "⚠️ Neutral", "33.33%", "Text is empty after preprocessing. Try adding more words."
seq = tokenizer.texts_to_sequences([processed_text])
padded = pad_sequences(seq, maxlen=MAX_LEN, padding='post')
pred = model.predict(padded, verbose=0)
label_idx = np.argmax(pred, axis=1)[0]
confidence = pred[0][label_idx]
labels = ["😞 Negative", "😊 Positive", "😐 Neutral"]
sentiment = labels[label_idx]
confidence_percentage = f"{confidence * 100:.2f}%"
detailed_results = f"""
### πŸ“Š Detailed Analysis:
**Original Text:** {text}
**Processed Text:** {processed_text}
**Prediction Probabilities:**
- 😞 Negative: {pred[0][0] * 100:.2f}%
- 😊 Positive: {pred[0][1] * 100:.2f}%
- 😐 Neutral: {pred[0][2] * 100:.2f}%
**Final Sentiment:** {sentiment}
**Confidence:** {confidence_percentage}
"""
return sentiment, confidence_percentage, detailed_results
# GRADIO INTERFACE
def create_gradio_interface():
"""Create and configure Gradio interface"""
examples = [
["I'm so happy with my purchase! Highly recommended!"],
["I don't like this at all. Very disappointing."],
["I absolutely love this product! It's amazing!"],
["This is the worst experience I've ever had."],
["Fantastic! Best decision I ever made!"],
["I'm not sure how I feel about this."],
["It's okay, nothing special really."],
["Amazing work! Best I've ever seen!"],
["This is the worst experience ever"],
["This is terrible and I hate it"],
["It works fine, no complaints."],
["Not bad, but could be better."],
["He is no good boy"],
["I'm doing great"],
["I'm not normal"],
["Both of you"],
["I am fine"],
["I am good"],
["I'm okay"]
]
with gr.Blocks(title="Sentiment Analysis") as interface:
gr.Markdown("""
# 🎭 Sentiment Analysis - AI Powered
### Analyze the sentiment of your text using Deep Learning (LSTM Model)
**Instructions:** Enter any text in English and the model will predict whether it's Positive, Negative, or Neutral.
""")
with gr.Row():
with gr.Column(scale=1):
text_input = gr.Textbox(
label="πŸ“ Enter Your Text",
placeholder="Type your text here... (e.g., 'I love this product!')",
lines=5,
max_lines=10
)
with gr.Row():
analyze_btn = gr.Button("πŸ” Analyze Sentiment", variant="primary", size="lg")
clear_btn = gr.ClearButton([text_input], value="πŸ—‘οΈ Clear", size="lg")
with gr.Column(scale=1):
sentiment_output = gr.Textbox(
label="🎯 Predicted Sentiment",
interactive=False
)
confidence_output = gr.Textbox(
label="πŸ“ˆ Confidence Score",
interactive=False
)
detailed_output = gr.Markdown(
label="πŸ“Š Detailed Analysis",
value="Results will appear here after analysis..."
)
gr.Markdown("### πŸ’‘ Try These Examples:")
gr.Examples(
examples=examples,
inputs=text_input,
outputs=[sentiment_output, confidence_output, detailed_output],
fn=predict_sentiment,
cache_examples=False
)
gr.Markdown("""
---
**Model Information:**
- Architecture: Bidirectional LSTM with Embedding Layer
- Classes: Negative (0), Positive (1), Neutral (2)
- Max Sequence Length: 100 tokens
**Tips for Best Results:**
- Use clear, complete sentences
- The model works best with English text
- Longer texts provide more context for accurate predictions
""")
analyze_btn.click(
fn=predict_sentiment,
inputs=text_input,
outputs=[sentiment_output, confidence_output, detailed_output]
)
text_input.submit(
fn=predict_sentiment,
inputs=text_input,
outputs=[sentiment_output, confidence_output, detailed_output]
)
return interface
# Context manager to suppress stderr temporarily
class SuppressStderr:
def __enter__(self):
self.original_stderr = sys.stderr
sys.stderr = io.StringIO()
return self
def __exit__(self, exc_type, exc_val, exc_tb):
sys.stderr = self.original_stderr
# MAIN EXECUTION
if __name__ == "__main__":
print("\n" + "=" * 70)
print("πŸš€ Starting Sentiment Analysis Gradio Interface...")
print("=" * 70 + "\n")
# Create interface
interface = create_gradio_interface()
# Launch with stderr suppression to hide asyncio warnings
print("⏳ Launching server...")
with SuppressStderr():
# Launch configuration
interface.launch(
server_name="0.0.0.0",
server_port=7860,
share=False,
show_error=True,
ssr_mode=False,
theme=gr.themes.Soft(),
quiet=False,
prevent_thread_lock=False
)
print("\n" + "=" * 70)
print("βœ… Interface is LIVE and ready to use!")
print(" 🌐 Local URL: http://localhost:7860")
print(" ⚑ Server is running smoothly")
print(" πŸ›‘ Press Ctrl+C to stop")
print("=" * 70)