File size: 3,632 Bytes
9d89b04 0647b9e 9d89b04 | 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 | import pickle
import re
import string
import contractions
import gradio as gr
import nltk
from bs4 import BeautifulSoup
from nltk.tokenize import word_tokenize
from nltk.corpus import stopwords
from tensorflow.keras.models import load_model
from tensorflow.keras.preprocessing.sequence import pad_sequences
# --------------------------------------------------
# NLTK Downloads
# --------------------------------------------------
nltk.download('stopwords', quiet=True)
nltk.download('punkt', quiet=True)
nltk.download('punkt_tab', quiet=True)
# --------------------------------------------------
# Load Model and Tokenizer
# --------------------------------------------------
MODEL_PATH = "bilstm_sentiment_model.keras"
TOKENIZER_PATH = "BiLSTM_tokenizer.pkl"
loaded_model = load_model(MODEL_PATH)
with open(TOKENIZER_PATH, "rb") as f:
loaded_tokenizer = pickle.load(f)
print("β
Model and Tokenizer loaded successfully")
# --------------------------------------------------
# Constants
# --------------------------------------------------
MAX_LEN = 200
STOP_WORDS = set(stopwords.words("english"))
# --------------------------------------------------
# Text Preprocessing
# --------------------------------------------------
def preprocess_text(text: str) -> str:
# Remove HTML
text = BeautifulSoup(text, "html.parser").get_text()
# Remove URLs
text = re.sub(r"http\S+|www\.\S+", "", text)
# Normalize special characters
text = text.replace("\u2019", "'").replace("\u2018", "'")
text = text.replace("\u201c", '"').replace("\u201d", '"')
text = text.replace("\u2013", "-").replace("\u2014", "-")
text = text.encode("ascii", errors="ignore").decode("ascii")
# Expand contractions
text = contractions.fix(text)
# Lowercase
text = text.lower()
# Remove punctuation
text = text.translate(str.maketrans("", "", string.punctuation))
# Remove numbers
text = re.sub(r"\b\d+\b", "", text)
# Remove extra spaces
text = re.sub(r"\s+", " ", text).strip()
# Tokenize and remove stopwords
tokens = word_tokenize(text)
tokens = [word for word in tokens if word not in STOP_WORDS]
return " ".join(tokens)
# --------------------------------------------------
# Prediction Function
# --------------------------------------------------
def predict_sentiment(review_text):
clean_text = preprocess_text(review_text)
seq = loaded_tokenizer.texts_to_sequences([clean_text])
padded = pad_sequences(
seq,
maxlen=MAX_LEN,
padding="post",
truncating="post"
)
score = float(loaded_model.predict(padded, verbose=0)[0][0])
if score >= 0.5:
sentiment = "Positive π"
confidence = score * 100
else:
sentiment = "Negative π"
confidence = (1 - score) * 100
return (
clean_text,
sentiment,
f"{confidence:.2f}%",
round(score, 4)
)
# --------------------------------------------------
# Gradio UI
# --------------------------------------------------
app = gr.Interface(
fn=predict_sentiment,
inputs=gr.Textbox(
lines=5,
placeholder="Enter a movie review...",
label="Movie Review"
),
outputs=[
gr.Textbox(label="Cleaned Text"),
gr.Textbox(label="Predicted Sentiment"),
gr.Textbox(label="Confidence"),
gr.Number(label="Raw Score")
],
title="π¬ BiLSTM Movie Review Sentiment Analyzer",
description="Enter a movie review and the trained BiLSTM model will predict whether the sentiment is positive or negative."
)
app.launch() |