hassansattar
commited on
Upload 3 files
Browse files- Amazon_Sentiment_Review.ipynb +632 -0
- sentiment_model.h5 +3 -0
- tokenizer.pkl +3 -0
Amazon_Sentiment_Review.ipynb
ADDED
@@ -0,0 +1,632 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
{
|
2 |
+
"cells": [
|
3 |
+
{
|
4 |
+
"cell_type": "markdown",
|
5 |
+
"id": "023d00e4",
|
6 |
+
"metadata": {},
|
7 |
+
"source": [
|
8 |
+
"# This a sentiment analysis task that design and optimization of the model, as well as potentially utilizing advanced NLP techniques such as fine-tuning pre-trained models like BERT. In a local Python environment where you can use TensorFlow and Keras, I took an optimized approach using a more complex LSTM model, incorporating some advanced techniques that help improve the accuracy."
|
9 |
+
]
|
10 |
+
},
|
11 |
+
{
|
12 |
+
"cell_type": "markdown",
|
13 |
+
"id": "cb52f311",
|
14 |
+
"metadata": {},
|
15 |
+
"source": [
|
16 |
+
"## Import Libraries:\n",
|
17 |
+
"\n",
|
18 |
+
"#### numpy and tensorflow are foundational libraries for numerical operations and machine learning.\n",
|
19 |
+
"#### Classes imported from tensorflow.keras are used to build neural network models:\n",
|
20 |
+
"- Sequential for linear stacking of layers.\n",
|
21 |
+
"- Embedding, LSTM, Dense, Dropout, and Bidirectional for different types of neural network layers.\n",
|
22 |
+
"- Tokenizer and pad_sequences are utilities for text processing.\n",
|
23 |
+
"- train_test_split from sklearn is used for splitting data into training and test sets."
|
24 |
+
]
|
25 |
+
},
|
26 |
+
{
|
27 |
+
"cell_type": "code",
|
28 |
+
"execution_count": 1,
|
29 |
+
"id": "214a844b",
|
30 |
+
"metadata": {},
|
31 |
+
"outputs": [],
|
32 |
+
"source": [
|
33 |
+
"import numpy as np\n",
|
34 |
+
"import tensorflow as tf\n",
|
35 |
+
"from tensorflow.keras.models import Sequential\n",
|
36 |
+
"from tensorflow.keras.layers import Embedding, LSTM, Dense, Dropout, Bidirectional\n",
|
37 |
+
"from tensorflow.keras.preprocessing.text import Tokenizer\n",
|
38 |
+
"from tensorflow.keras.preprocessing.sequence import pad_sequences\n",
|
39 |
+
"from tensorflow.keras.initializers import Constant\n",
|
40 |
+
"from sklearn.model_selection import train_test_split"
|
41 |
+
]
|
42 |
+
},
|
43 |
+
{
|
44 |
+
"cell_type": "code",
|
45 |
+
"execution_count": 2,
|
46 |
+
"id": "c01d5192",
|
47 |
+
"metadata": {},
|
48 |
+
"outputs": [
|
49 |
+
{
|
50 |
+
"name": "stdout",
|
51 |
+
"output_type": "stream",
|
52 |
+
"text": [
|
53 |
+
"2.10.0\n"
|
54 |
+
]
|
55 |
+
}
|
56 |
+
],
|
57 |
+
"source": [
|
58 |
+
"print(tf.__version__)"
|
59 |
+
]
|
60 |
+
},
|
61 |
+
{
|
62 |
+
"cell_type": "markdown",
|
63 |
+
"id": "c7ad5ab0",
|
64 |
+
"metadata": {},
|
65 |
+
"source": [
|
66 |
+
"## Load and Preprocess Data:\n",
|
67 |
+
"\n",
|
68 |
+
"### Download the NLP dataset Amazon Sentiment Review form Kaggle \n",
|
69 |
+
"#### https://www.kaggle.com/datasets/bittlingmayer/amazonreviews\n",
|
70 |
+
"\n",
|
71 |
+
"- Reads each line, splits it to separate the label from the review, assigns binary labels (1 for positive, 0 for negative), and stores the results in lists.\n",
|
72 |
+
"\n",
|
73 |
+
"- Converts the label list to a NumPy array for further processing.\n"
|
74 |
+
]
|
75 |
+
},
|
76 |
+
{
|
77 |
+
"cell_type": "code",
|
78 |
+
"execution_count": 3,
|
79 |
+
"id": "992745e5",
|
80 |
+
"metadata": {},
|
81 |
+
"outputs": [],
|
82 |
+
"source": [
|
83 |
+
"# Load the data (example path, replace with your actual path)\n",
|
84 |
+
"file_path= 'Dataset/train.txt'\n",
|
85 |
+
"\n",
|
86 |
+
"# Preprocess the data\n",
|
87 |
+
"with open(file_path, 'r', encoding='utf-8') as file:\n",
|
88 |
+
" lines = file.readlines()\n",
|
89 |
+
"\n",
|
90 |
+
"labels = []\n",
|
91 |
+
"reviews = []\n",
|
92 |
+
"for line in lines:\n",
|
93 |
+
" split_line = line.strip().split(' ', 1)\n",
|
94 |
+
" label = 1 if split_line[0] == '__label__2' else 0\n",
|
95 |
+
" review = split_line[1]\n",
|
96 |
+
" labels.append(label)\n",
|
97 |
+
" reviews.append(review)\n",
|
98 |
+
"\n",
|
99 |
+
"labels = np.array(labels)\n"
|
100 |
+
]
|
101 |
+
},
|
102 |
+
{
|
103 |
+
"cell_type": "markdown",
|
104 |
+
"id": "f2a2b587",
|
105 |
+
"metadata": {},
|
106 |
+
"source": [
|
107 |
+
"## Tokenization and Sequence Padding:\n",
|
108 |
+
"\n",
|
109 |
+
"- Initializes a Tokenizer object, specifying a maximum vocabulary size of 10,000 words and an out-of-vocabulary token <OOV>.\n",
|
110 |
+
"- Fits the tokenizer on the collected reviews, creating an index of all unique words.\n",
|
111 |
+
"- Converts the reviews into lists of integers based on the tokenizer's word index.\n",
|
112 |
+
"- Pads these sequences to a fixed length of 250, ensuring all input data has consistent dimensions, necessary for training neural networks."
|
113 |
+
]
|
114 |
+
},
|
115 |
+
{
|
116 |
+
"cell_type": "code",
|
117 |
+
"execution_count": 4,
|
118 |
+
"id": "edfcccbf",
|
119 |
+
"metadata": {},
|
120 |
+
"outputs": [],
|
121 |
+
"source": [
|
122 |
+
"# Tokenizing and padding text\n",
|
123 |
+
"tokenizer = Tokenizer(num_words=10000, oov_token=\"<OOV>\")\n",
|
124 |
+
"tokenizer.fit_on_texts(reviews)\n",
|
125 |
+
"sequences = tokenizer.texts_to_sequences(reviews)\n",
|
126 |
+
"padded_sequences = pad_sequences(sequences, padding='post', maxlen=250)"
|
127 |
+
]
|
128 |
+
},
|
129 |
+
{
|
130 |
+
"cell_type": "markdown",
|
131 |
+
"id": "62aea0f6",
|
132 |
+
"metadata": {},
|
133 |
+
"source": [
|
134 |
+
"## Loading Pre-trained GloVe Embeddings\n",
|
135 |
+
"\n",
|
136 |
+
"### Download the Glove Embedding from Kaggle\n",
|
137 |
+
"\n",
|
138 |
+
"#### https://www.kaggle.com/datasets/danielwillgeorge/glove6b100dtxt\n",
|
139 |
+
"\n",
|
140 |
+
"- Defines a function to load the GloVe (Global Vectors for Word Representation) embeddings.\n",
|
141 |
+
"- Reads the GloVe file, parsing each line to extract the word and its corresponding coefficient vector.\n",
|
142 |
+
"- Creates an embedding matrix that maps each word in the tokenizer's index to its GloVe vector, if available. Words not in GloVe will have a vector of zeros.\n"
|
143 |
+
]
|
144 |
+
},
|
145 |
+
{
|
146 |
+
"cell_type": "code",
|
147 |
+
"execution_count": 5,
|
148 |
+
"id": "a44dac7b",
|
149 |
+
"metadata": {},
|
150 |
+
"outputs": [],
|
151 |
+
"source": [
|
152 |
+
"# # Load pre-trained GloVe embeddings\n",
|
153 |
+
"\n",
|
154 |
+
"def load_glove_embeddings(path, word_index, embedding_dim):\n",
|
155 |
+
" embeddings_index = {}\n",
|
156 |
+
" # Open the file with UTF-8 encoding specified\n",
|
157 |
+
" with open(path, 'r', encoding='utf-8') as f:\n",
|
158 |
+
" for line in f:\n",
|
159 |
+
" word, coefs = line.split(maxsplit=1)\n",
|
160 |
+
" coefs = np.fromstring(coefs, 'f', sep=' ')\n",
|
161 |
+
" embeddings_index[word] = coefs\n",
|
162 |
+
"\n",
|
163 |
+
" # Prepare embedding matrix\n",
|
164 |
+
" num_words = min(len(word_index) + 1, 10000)\n",
|
165 |
+
" embedding_matrix = np.zeros((num_words, embedding_dim))\n",
|
166 |
+
" for word, i in word_index.items():\n",
|
167 |
+
" if i >= num_words:\n",
|
168 |
+
" continue\n",
|
169 |
+
" embedding_vector = embeddings_index.get(word)\n",
|
170 |
+
" if embedding_vector is not None: # Corrected line here\n",
|
171 |
+
" # Use the embedding vector for words found in the GloVe index\n",
|
172 |
+
" embedding_matrix[i] = embedding_vector # words not found will be all-zeros.\n",
|
173 |
+
"\n",
|
174 |
+
" return embedding_matrix\n",
|
175 |
+
"\n"
|
176 |
+
]
|
177 |
+
},
|
178 |
+
{
|
179 |
+
"cell_type": "code",
|
180 |
+
"execution_count": 6,
|
181 |
+
"id": "8800fc79",
|
182 |
+
"metadata": {},
|
183 |
+
"outputs": [],
|
184 |
+
"source": [
|
185 |
+
"embedding_dim = 100 # Size of the GloVe vectors you're using\n",
|
186 |
+
"glove_path = 'Embedding/glove.6B.100d/glove.6B.100d.txt'\n",
|
187 |
+
"embedding_matrix = load_glove_embeddings(glove_path, tokenizer.word_index, embedding_dim)\n"
|
188 |
+
]
|
189 |
+
},
|
190 |
+
{
|
191 |
+
"cell_type": "markdown",
|
192 |
+
"id": "5ed572bf",
|
193 |
+
"metadata": {},
|
194 |
+
"source": [
|
195 |
+
"## Model Definition and Compilation:\n",
|
196 |
+
"\n",
|
197 |
+
"- Defines a sequential model for sentiment analysis.\n",
|
198 |
+
"- Adds an Embedding layer to transform indices into dense vectors of fixed size.\n",
|
199 |
+
"- Utilizes Bidirectional layers with LSTM units to capture patterns from both forward and backward states of the input sequence.\n",
|
200 |
+
"- Adds Dense layers with ReLU activation for non-linear transformations and a dropout layer to reduce overfitting.\n",
|
201 |
+
"- The final output layer uses a sigmoid activation function for binary classification.\n",
|
202 |
+
"- Compiles the model with the Adam optimizer and binary cross-entropy loss function, tracking accuracy as a metric."
|
203 |
+
]
|
204 |
+
},
|
205 |
+
{
|
206 |
+
"cell_type": "code",
|
207 |
+
"execution_count": 7,
|
208 |
+
"id": "2d8b02df",
|
209 |
+
"metadata": {},
|
210 |
+
"outputs": [],
|
211 |
+
"source": [
|
212 |
+
"# Build the model\n",
|
213 |
+
"model = Sequential([\n",
|
214 |
+
" Embedding(10000, embedding_dim, embeddings_initializer=Constant(embedding_matrix), \n",
|
215 |
+
" input_length=250, trainable=False),\n",
|
216 |
+
" Bidirectional(LSTM(128, return_sequences=True)),\n",
|
217 |
+
" Dropout(0.5),\n",
|
218 |
+
" Bidirectional(LSTM(128)),\n",
|
219 |
+
" Dropout(0.5),\n",
|
220 |
+
" Dense(1, activation='sigmoid')\n",
|
221 |
+
"])"
|
222 |
+
]
|
223 |
+
},
|
224 |
+
{
|
225 |
+
"cell_type": "code",
|
226 |
+
"execution_count": 8,
|
227 |
+
"id": "ce4fa260",
|
228 |
+
"metadata": {},
|
229 |
+
"outputs": [
|
230 |
+
{
|
231 |
+
"name": "stdout",
|
232 |
+
"output_type": "stream",
|
233 |
+
"text": [
|
234 |
+
"Model: \"sequential\"\n",
|
235 |
+
"_________________________________________________________________\n",
|
236 |
+
" Layer (type) Output Shape Param # \n",
|
237 |
+
"=================================================================\n",
|
238 |
+
" embedding (Embedding) (None, 250, 100) 1000000 \n",
|
239 |
+
" \n",
|
240 |
+
" bidirectional (Bidirectiona (None, 250, 256) 234496 \n",
|
241 |
+
" l) \n",
|
242 |
+
" \n",
|
243 |
+
" dropout (Dropout) (None, 250, 256) 0 \n",
|
244 |
+
" \n",
|
245 |
+
" bidirectional_1 (Bidirectio (None, 256) 394240 \n",
|
246 |
+
" nal) \n",
|
247 |
+
" \n",
|
248 |
+
" dropout_1 (Dropout) (None, 256) 0 \n",
|
249 |
+
" \n",
|
250 |
+
" dense (Dense) (None, 1) 257 \n",
|
251 |
+
" \n",
|
252 |
+
"=================================================================\n",
|
253 |
+
"Total params: 1,628,993\n",
|
254 |
+
"Trainable params: 628,993\n",
|
255 |
+
"Non-trainable params: 1,000,000\n",
|
256 |
+
"_________________________________________________________________\n"
|
257 |
+
]
|
258 |
+
}
|
259 |
+
],
|
260 |
+
"source": [
|
261 |
+
"model.compile(optimizer='adam', loss='binary_crossentropy', metrics=['accuracy'])\n",
|
262 |
+
"model.summary()"
|
263 |
+
]
|
264 |
+
},
|
265 |
+
{
|
266 |
+
"cell_type": "code",
|
267 |
+
"execution_count": 9,
|
268 |
+
"id": "a3c4e6a3",
|
269 |
+
"metadata": {},
|
270 |
+
"outputs": [],
|
271 |
+
"source": [
|
272 |
+
"# Splitting the data\n",
|
273 |
+
"X_train, X_val, y_train, y_val = train_test_split(padded_sequences, labels, test_size=0.2, random_state=42)\n"
|
274 |
+
]
|
275 |
+
},
|
276 |
+
{
|
277 |
+
"cell_type": "markdown",
|
278 |
+
"id": "ddafc948",
|
279 |
+
"metadata": {},
|
280 |
+
"source": [
|
281 |
+
"## Model Training:\n",
|
282 |
+
"\n",
|
283 |
+
"- Trains the model on the padded text sequences and labels.\n",
|
284 |
+
"- Runs for 5 epochs with 20% of the data reserved for validation to monitor performance and mitigate overfitting."
|
285 |
+
]
|
286 |
+
},
|
287 |
+
{
|
288 |
+
"cell_type": "code",
|
289 |
+
"execution_count": 10,
|
290 |
+
"id": "596a0174",
|
291 |
+
"metadata": {},
|
292 |
+
"outputs": [
|
293 |
+
{
|
294 |
+
"name": "stdout",
|
295 |
+
"output_type": "stream",
|
296 |
+
"text": [
|
297 |
+
"Epoch 1/5\n",
|
298 |
+
"1093/1093 [==============================] - 1457s 1s/step - loss: 0.3991 - accuracy: 0.8189 - val_loss: 0.3092 - val_accuracy: 0.8722\n",
|
299 |
+
"Epoch 2/5\n",
|
300 |
+
"1093/1093 [==============================] - 1371s 1s/step - loss: 0.2911 - accuracy: 0.8783 - val_loss: 0.2605 - val_accuracy: 0.8944\n",
|
301 |
+
"Epoch 3/5\n",
|
302 |
+
"1093/1093 [==============================] - 1641s 2s/step - loss: 0.2511 - accuracy: 0.8970 - val_loss: 0.2432 - val_accuracy: 0.9026\n",
|
303 |
+
"Epoch 4/5\n",
|
304 |
+
"1093/1093 [==============================] - 1400s 1s/step - loss: 0.2308 - accuracy: 0.9075 - val_loss: 0.2350 - val_accuracy: 0.9058\n",
|
305 |
+
"Epoch 5/5\n",
|
306 |
+
"1093/1093 [==============================] - 1400s 1s/step - loss: 0.2066 - accuracy: 0.9193 - val_loss: 0.2306 - val_accuracy: 0.9133\n"
|
307 |
+
]
|
308 |
+
}
|
309 |
+
],
|
310 |
+
"source": [
|
311 |
+
"# Training the model\n",
|
312 |
+
"history = model.fit(X_train, y_train, epochs=5, batch_size=64, validation_data=(X_val, y_val), verbose=1)\n"
|
313 |
+
]
|
314 |
+
},
|
315 |
+
{
|
316 |
+
"cell_type": "markdown",
|
317 |
+
"id": "039f21c0",
|
318 |
+
"metadata": {},
|
319 |
+
"source": [
|
320 |
+
"## Save the Train Model"
|
321 |
+
]
|
322 |
+
},
|
323 |
+
{
|
324 |
+
"cell_type": "code",
|
325 |
+
"execution_count": 11,
|
326 |
+
"id": "e4693576",
|
327 |
+
"metadata": {},
|
328 |
+
"outputs": [],
|
329 |
+
"source": [
|
330 |
+
"# Save the model\n",
|
331 |
+
"model.save('sentiment_model.h5')"
|
332 |
+
]
|
333 |
+
},
|
334 |
+
{
|
335 |
+
"cell_type": "code",
|
336 |
+
"execution_count": 12,
|
337 |
+
"id": "2e1b099f",
|
338 |
+
"metadata": {},
|
339 |
+
"outputs": [],
|
340 |
+
"source": [
|
341 |
+
"# Save the tokenizer\n",
|
342 |
+
"import pickle\n",
|
343 |
+
"with open('tokenizer.pkl', 'wb') as handle:\n",
|
344 |
+
" pickle.dump(tokenizer, handle, protocol=pickle.HIGHEST_PROTOCOL)\n"
|
345 |
+
]
|
346 |
+
},
|
347 |
+
{
|
348 |
+
"cell_type": "markdown",
|
349 |
+
"id": "66daf062",
|
350 |
+
"metadata": {},
|
351 |
+
"source": [
|
352 |
+
"## Evaluate \n",
|
353 |
+
"\n",
|
354 |
+
"- Evaluate the model Validation loss\n",
|
355 |
+
"- Evaluate the model Validation accuracy\n"
|
356 |
+
]
|
357 |
+
},
|
358 |
+
{
|
359 |
+
"cell_type": "code",
|
360 |
+
"execution_count": 13,
|
361 |
+
"id": "b64ef635",
|
362 |
+
"metadata": {},
|
363 |
+
"outputs": [
|
364 |
+
{
|
365 |
+
"name": "stdout",
|
366 |
+
"output_type": "stream",
|
367 |
+
"text": [
|
368 |
+
"547/547 [==============================] - 191s 349ms/step - loss: 0.2306 - accuracy: 0.9133\n",
|
369 |
+
"Validation loss: 0.23057065904140472\n",
|
370 |
+
"Validation accuracy: 0.9132547974586487\n"
|
371 |
+
]
|
372 |
+
}
|
373 |
+
],
|
374 |
+
"source": [
|
375 |
+
"# Evaluate the model\n",
|
376 |
+
"loss, accuracy = model.evaluate(X_val, y_val)\n",
|
377 |
+
"print(\"Validation loss:\", loss)\n",
|
378 |
+
"print(\"Validation accuracy:\", accuracy)"
|
379 |
+
]
|
380 |
+
},
|
381 |
+
{
|
382 |
+
"cell_type": "code",
|
383 |
+
"execution_count": 14,
|
384 |
+
"id": "54a7aec7",
|
385 |
+
"metadata": {},
|
386 |
+
"outputs": [
|
387 |
+
{
|
388 |
+
"data": {
|
389 |
+
"image/png": "iVBORw0KGgoAAAANSUhEUgAAAkAAAAHHCAYAAABXx+fLAAAAOXRFWHRTb2Z0d2FyZQBNYXRwbG90bGliIHZlcnNpb24zLjguMCwgaHR0cHM6Ly9tYXRwbG90bGliLm9yZy81sbWrAAAACXBIWXMAAA9hAAAPYQGoP6dpAAB1jklEQVR4nO3dd3wU1frH8c+mJ5CEkkISAqGGTpAmYAFFEDCCFxWxgIj6UwFFrgURBBtguYiK/VL0KoINRekEAekIBpHeSyCNkkra7vz+WFhYEkogYVK+79drX7AzZ2afk02yT84854zFMAwDERERkXLExewARERERK41JUAiIiJS7igBEhERkXJHCZCIiIiUO0qAREREpNxRAiQiIiLljhIgERERKXeUAImIiEi5owRIREREyh0lQCJyTVksFsaMGVPo4/bv34/FYmHatGlFHpOIlD9KgETKoWnTpmGxWLBYLKxYsSLffsMwCA8Px2KxcMcdd5gQYdGYO3cuFouF0NBQbDab2eGISAmiBEikHPPy8mL69On5ti9btozDhw/j6elpQlRF55tvviEiIoKjR4+yZMkSs8MRkRJECZBIOda9e3e+//578vLynLZPnz6dli1bUq1aNZMiu3oZGRn88ssvDBs2jBYtWvDNN9+YHdIFZWRkmB2CSLmjBEikHOvbty/Hjh1j0aJFjm05OTn88MMP3H///QUek5GRwb///W/Cw8Px9PQkMjKSd999F8MwnNplZ2fz7LPPEhgYiK+vL3feeSeHDx8u8JxxcXE88sgjBAcH4+npSePGjZkyZcpV9W3WrFmcOnWKe+65h/vuu4+ffvqJrKysfO2ysrIYM2YM9evXx8vLi5CQEP71r3+xZ88eRxubzcb7779P06ZN8fLyIjAwkNtvv50///wTuHh90vk1T2PGjMFisbB161buv/9+KleuzA033ADA33//zcMPP0zt2rXx8vKiWrVqPPLIIxw7dqzAr9nAgQMJDQ3F09OTWrVq8eSTT5KTk8PevXuxWCy89957+Y5btWoVFouFb7/9trBfUpEyxc3sAETEPBEREbRr145vv/2Wbt26ATBv3jxSUlK47777+OCDD5zaG4bBnXfeye+//87AgQOJiopiwYIFPP/888TFxTl94D766KN8/fXX3H///bRv354lS5bQo0ePfDEkJCRw/fXXY7FYGDx4MIGBgcybN4+BAweSmprK0KFDr6hv33zzDZ06daJatWrcd999DB8+nF9//ZV77rnH0cZqtXLHHXcQExPDfffdxzPPPENaWhqLFi3in3/+oU6dOgAMHDiQadOm0a1bNx599FHy8vL4448/WLNmDa1atbqi+O655x7q1avH2LFjHcnjokWL2Lt3LwMGDKBatWps2bKFzz//nC1btrBmzRosFgsAR44coU2bNpw8eZLHH3+cBg0aEBcXxw8//EBmZia1a9emQ4cOfPPNNzz77LP5vi6+vr707NnziuIWKTMMESl3pk6dagDG+vXrjUmTJhm+vr5GZmamYRiGcc899xidOnUyDMMwatasafTo0cNx3M8//2wAxhtvvOF0vrvvvtuwWCzG7t27DcMwjNjYWAMwnnrqKad2999/vwEYo0ePdmwbOHCgERISYiQnJzu1ve+++wx/f39HXPv27TMAY+rUqZfsX0JCguHm5mZ88cUXjm3t27c3evbs6dRuypQpBmBMmDAh3zlsNpthGIaxZMkSAzCefvrpC7a5WGzn93f06NEGYPTt2zdf2zN9Pde3335rAMby5csd2/r162e4uLgY69evv2BMn332mQEY27Ztc+zLyckxAgICjP79++c7TqS80SUwkXLu3nvv5dSpU/z222+kpaXx22+/XfDy19y5c3F1deXpp5922v7vf/8bwzCYN2+eox2Qr935ozmGYfDjjz8SHR2NYRgkJyc7Hl27diUlJYWNGzcWuk8zZszAxcWF3r17O7b17duXefPmceLECce2H3/8kYCAAIYMGZLvHGdGW3788UcsFgujR4++YJsr8cQTT+Tb5u3t7fh/VlYWycnJXH/99QCOr4PNZuPnn38mOjq6wNGnMzHde++9eHl5OdU+LViwgOTkZB588MErjlukrFACJFLOBQYG0rlzZ6ZPn85PP/2E1Wrl7rvvLrDtgQMHCA0NxdfX12l7w4YNHfvP/Ovi4uK4hHRGZGSk0/OkpCROnjzJ559/TmBgoNNjwIABACQmJha6T19//TVt2rTh2LFj7N69m927d9OiRQtycnL4/vvvHe327NlDZGQkbm4XrgbYs2cPoaGhVKlSpdBxXEytWrXybTt+/DjPPPMMwcHBeHt7ExgY6GiXkpIC2L9mqampNGnS5KLnr1SpEtHR0U6z/L755hvCwsK45ZZbirAnIqWTaoBEhPvvv5/HHnuM+Ph4unXrRqVKla7J655Zm+fBBx+kf//+BbZp1qxZoc65a9cu1q9fD0C9evXy7f/mm294/PHHCxnpxV1oJMhqtV7wmHNHe8649957WbVqFc8//zxRUVFUrFgRm83G7bfffkXrGPXr14/vv/+eVatW0bRpU2bPns1TTz2Fi4v+9hVRAiQi3HXXXfzf//0fa9asYebMmRdsV7NmTRYvXkxaWprTKND27dsd+8/8a7PZHCMsZ+zYscPpfGdmiFmtVjp37lwkffnmm29wd3fnf//7H66urk77VqxYwQcffMDBgwepUaMGderUYe3ateTm5uLu7l7g+erUqcOCBQs4fvz4BUeBKleuDMDJkyedtp8ZEbscJ06cICYmhldffZVXXnnFsX3Xrl1O7QIDA/Hz8+Off/655Dlvv/12AgMD+eabb2jbti2ZmZk89NBDlx2TSFmmPwNEhIoVK/LJJ58wZswYoqOjL9iue/fuWK1WJk2a5LT9vffew2KxOGaSnfn3/FlkEydOdHru6upK7969+fHHHwv8QE9KSip0X7755htuvPFG+vTpw9133+30eP755wEcU8B79+5NcnJyvv4AjplZvXv3xjAMXn311Qu28fPzIyAggOXLlzvt//jjjy877jPJmnHecgLnf81cXFzo1asXv/76q2MafkExAbi5udG3b1++++47pk2bRtOmTQs9oiZSVmkESEQALngJ6lzR0dF06tSJl19+mf3799O8eXMWLlzIL7/8wtChQx01P1FRUfTt25ePP/6YlJQU2rdvT0xMDLt37853zvHjx/P777/Ttm1bHnvsMRo1asTx48fZuHEjixcv5vjx45fdh7Vr17J7924GDx5c4P6wsDCuu+46vvnmG1588UX69evHV199xbBhw1i3bh033ngjGRkZLF68mKeeeoqePXvSqVMnHnroIT744AN27drluBz1xx9/0KlTJ8drPfroo4wfP55HH32UVq1asXz5cnbu3HnZsfv5+XHTTTfx9ttvk5ubS1hYGAsXLmTfvn352o4dO5aFCxdy88038/jjj9OwYUOOHj3K999/z4oVK5wuYfbr148PPviA33//nbfeeuuy4xEp88ybgCYiZjl3GvzFnD8N3jAMIy0tzXj22WeN0NBQw93d3ahXr57xzjvvOKZfn3Hq1Cnj6aefNqpWrWpUqFDBiI6ONg4dOpRvWrhh2KetDxo0yAgPDzfc3d2NatWqGbfeeqvx+eefO9pczjT4IUOGGICxZ8+eC7YZM2aMARibNm0yDMM+9fzll182atWq5Xjtu+++2+kceXl5xjvvvGM0aNDA8PDwMAIDA41u3boZGzZscLTJzMw0Bg4caPj7+xu+vr7GvffeayQmJl5wGnxSUlK+2A4fPmzcddddRqVKlQx/f3/jnnvuMY4cOVLg1+zAgQNGv379jMDAQMPT09OoXbu2MWjQICM7OzvfeRs3bmy4uLgYhw8fvuDXRaS8sRjGeeOtIiJSprRo0YIqVaoQExNjdigiJYZqgEREyrA///yT2NhY+vXrZ3YoIiWKRoBERMqgf/75hw0bNvCf//yH5ORk9u7di5eXl9lhiZQYGgESESmDfvjhBwYMGEBubi7ffvutkh+R82gESERERModjQCJiIhIuaMESERERModLYRYAJvNxpEjR/D19b2quz2LiIjItWMYBmlpaYSGhl7ynndKgApw5MgRwsPDzQ5DRERErsChQ4eoXr36RdsoASrAmZs8Hjp0CD8/P5OjERERkcuRmppKeHi4082aL0QJUAHOXPby8/NTAiQiIlLKXE75ioqgRUREpNxRAiQiIiLljhIgERERKXdUA3QVrFYrubm5ZochUuTc3d1xdXU1OwwRkWKjBOgKGIZBfHw8J0+eNDsUkWJTqVIlqlWrprWwRKRMUgJ0Bc4kP0FBQfj4+OgDQsoUwzDIzMwkMTERgJCQEJMjEhEpekqACslqtTqSn6pVq5odjkix8Pb2BiAxMZGgoCBdDhORMqdEFEF/9NFHRERE4OXlRdu2bVm3bt0F2+bm5vLaa69Rp04dvLy8aN68OfPnz3dqM27cOFq3bo2vry9BQUH06tWLHTt2FEmsZ2p+fHx8iuR8IiXVme9x1bmJSFlkegI0c+ZMhg0bxujRo9m4cSPNmzena9eujuH3840cOZLPPvuMDz/8kK1bt/LEE09w11138ddffznaLFu2jEGDBrFmzRoWLVpEbm4uXbp0ISMjo8ji1mUvKev0PS4iZZnFMAzDzADatm1L69atmTRpEmC/EWl4eDhDhgxh+PDh+dqHhoby8ssvM2jQIMe23r174+3tzddff13gayQlJREUFMSyZcu46aabLhlTamoq/v7+pKSk5FsJOisri3379lGrVi28vLwK01WRUkXf6yJS2lzs8/t8po4A5eTksGHDBjp37uzY5uLiQufOnVm9enWBx2RnZ+f7Zezt7c2KFSsu+DopKSkAVKlSpQiiFhERkdLO1AQoOTkZq9VKcHCw0/bg4GDi4+MLPKZr165MmDCBXbt2YbPZWLRoET/99BNHjx4tsL3NZmPo0KF06NCBJk2aFNgmOzub1NRUp0dZtnr1alxdXenRo4fZoYiIiJjC9Bqgwnr//fepV68eDRo0wMPDg8GDBzNgwABcXAruyqBBg/jnn3+YMWPGBc85btw4/P39HY/w8PDiCr9EmDx5MkOGDGH58uUcOXLEtDhycnJMe20RETHP3qR0Dp/INDUGUxOggIAAXF1dSUhIcNqekJBAtWrVCjwmMDCQn3/+mYyMDA4cOMD27dupWLEitWvXztd28ODB/Pbbb/z+++9Ur179gnG89NJLpKSkOB6HDh26uo6VYOnp6cycOZMnn3ySHj16MG3aNKf9v/76K61bt8bLy4uAgADuuusux77s7GxefPFFwsPD8fT0pG7dukyePBmAadOmUalSJadz/fzzz06FtGPGjCEqKor//ve/TnUl8+fP54YbbqBSpUpUrVqVO+64gz179jid6/Dhw/Tt25cqVapQoUIFWrVqxdq1a9m/fz8uLi78+eefTu0nTpxIzZo1sdlsV/slExGRIhCfksV//9hL9IcruOU/y5i8Yp+p8Zi6DpCHhwctW7YkJiaGXr16AfZLVjExMQwePPiix3p5eREWFkZubi4//vgj9957r2OfYRgMGTKEWbNmsXTpUmrVqnXRc3l6euLp6XnF/TAMg1O51is+/kp5u7sWeqbOd999R4MGDYiMjOTBBx9k6NChvPTSS1gsFubMmcNdd93Fyy+/zFdffUVOTg5z5851HNuvXz9Wr17NBx98QPPmzdm3bx/JycmFev3du3fz448/8tNPPznWlsnIyGDYsGE0a9aM9PR0XnnlFe666y5iY2NxcXEhPT2dm2++mbCwMGbPnk21atXYuHEjNpuNiIgIOnfuzNSpU2nVqpXjdaZOncrDDz98wZFBEREpficzc5i7OZ7Zm+JYu+84Z6ZdubpYSMvKMzU20xdCHDZsGP3796dVq1a0adOGiRMnkpGRwYABAwD7h25YWBjjxo0DYO3atcTFxREVFUVcXBxjxozBZrPxwgsvOM45aNAgpk+fzi+//IKvr6+jnsjf39+xwFtROpVrpdErC4r8vJey9bWu+HgU7i2cPHkyDz74IAC33347KSkpLFu2jI4dO/Lmm29y33338eqrrzraN2/eHICdO3fy3XffsWjRIkfRekGjbpeSk5PDV199RWBgoGNb7969ndpMmTKFwMBAtm7dSpMmTZg+fTpJSUmsX7/eUchet25dR/tHH32UJ554ggkTJuDp6cnGjRvZvHkzv/zyS6HjExGRq5OZk8eirQn8uukIy3YmkWs9O9m8dURl7mweSvemIVSteOUDD0XB9ASoT58+JCUl8corrxAfH09UVBTz5893FEYfPHjQ6a/4rKwsRo4cyd69e6lYsSLdu3fnf//7n9Pll08++QSAjh07Or3WmVGB8mrHjh2sW7eOWbNmAeDm5kafPn2YPHkyHTt2JDY2lscee6zAY2NjY3F1deXmm2++qhhq1qzplPwA7Nq1i1deeYW1a9eSnJzsuGx18OBBmjRpQmxsLC1atLjgLL5evXoxaNAgZs2axX333ce0adPo1KkTERERVxWriIhcnpw8G3/sSmL2piMs3JLgdFWkYYgfdzYPJbp5CNUrl5xFhE1PgMBeq3OhS15Lly51en7zzTezdevWi57vWi9t5O3uytbXul7T1zzzuoUxefJk8vLyCA0NdWwzDANPT08mTZp00dGxS42cubi45Pu6F7SCcIUKFfJti46OpmbNmnzxxReEhoZis9lo0qSJo0j6Uq/t4eFBv379mDp1Kv/617+YPn0677///kWPERGRq2OzGazff5xfNh1h7uajnMw8+zu/RhUf7mweyp1RodQP9jUxygsrEQlQaWexWAp9Kepay8vL46uvvuI///kPXbp0cdrXq1cvvv32W5o1a0ZMTIzj8uO5mjZtis1mY9myZU7rNp0RGBhIWloaGRkZjiQnNjb2knEdO3aMHTt28MUXX3DjjTcC5FvTqVmzZvz3v//l+PHjFxwFevTRR2nSpAkff/wxeXl5/Otf/7rka4uISOEYhsGWI6nM3nSEXzcd4WhKlmNfQEVP7mgWQs+oUKLCK5X41eRL9qe2FJnffvuNEydOMHDgQPz9/Z329e7dm8mTJ/POO+9w6623UqdOHe677z7y8vKYO3cuL774IhEREfTv359HHnnEUQR94MABEhMTuffee2nb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NNzc3Ix3333X2LZtmzF69GjD3d3d2Lx5s1lduKjC9u/VV181FixYYOzZs8fYsGGDcd999xleXl7Gli1bzOrCRaWlpRl//fWX8ddffxmAMWHCBOOvv/4yDhw4YBiGYQwfPtx46KGHHO337t1r+Pj4GM8//7yxbds246OPPjJcXV2N+fPnm9WFiyps/9577z3j559/Nnbt2mVs3rzZeOaZZwwXFxdj8eLFZnXhop588knD39/fWLp0qXH06FHHIzMz09GmtP8MXkkfS9PP4fDhw41ly5YZ+/btM/7++29j+PDhhsViMRYuXGgYRul//wrbv9L03l3I+bPASsp7qASoGHz44YdGjRo1DA8PD6NNmzbGmjVrHPtuvvlmo3///k7tv/vuO6N+/fqGh4eH0bhxY2POnDnXOOLCKUz/hg4d6mgbHBxsdO/e3di4caMJUV+eM9O+z3+c6VP//v2Nm2++Od8xUVFRhoeHh1G7dm1j6tSp1zzuy1XY/r311ltGnTp1DC8vL6NKlSpGx44djSVLlpgT/GUoqG+A03tS2n8Gr6SPpenn8JFHHjFq1qxpeHh4GIGBgcatt97qSA4Mo/S/f4XtX2l67y7k/ASopLyHFsMwjOIdYxIREREpWVQDJCIiIuWOEiAREREpd5QAiYiISLmjBEhERETKHSVAIiIiUu4oARIREZFyRwmQiIiIlDtKgERELoPFYuHnn382OwwRKSJKgESkxHv44YexWCz5HrfffrvZoYlIKaW7wYtIqXD77bczdepUp22enp4mRSMipZ1GgESkVPD09KRatWpOj8qVKwP2y1OffPIJ3bp1w9vbm9q1a/PDDz84Hb9582ZuueUWvL29qVq1Ko8//jjp6elObaZMmULjxo3x9PQkJCSEwYMHO+1PTk7mrrvuwsfHh3r16jF79uzi7bSIFBslQCJSJowaNYrevXuzadMmHnjgAe677z62bdsGQEZGBl27dqVy5cqsX7+e77//nsWLFzslOJ988gmDBg3i8ccfZ/PmzcyePZu6des6vcarr77Kvffey99//0337t154IEHOH78+DXtp4gUkWK/3aqIyFXq37+/4erqalSoUMHp8eabbxqGYb9D+hNPPOF0TNu2bY0nn3zSMAzD+Pzzz43KlSsb6enpjv1z5swxXFxcjPj4eMMwDCM0NNR4+eWXLxgDYIwcOdLxPD093QCMefPmFVk/ReTaUQ2QiJQKnTp14pNPPnHaVqVKFcf/27Vr57SvXbt2xMbGArBt2zaaN29OhQoVHPs7dOiAzWZjx44dWCwWjhw5wq233nrRGJo1a+b4f4UKFfDz8yMxMfFKuyQiJlICJCKlQoUKFfJdkioq3t7el9XO3d3d6bnFYsFmsxVHSCJSzFQDJCJlwpo1a/I9b9iwIQANGzZk06ZNZGRkOPavXLkSFxcXIiMj8fX1JSIigpiYmGsas4iYRyNAIlIqZGdnEx8f77TNzc2NgIAAAL7//ntatWrFDTfcwDfffMO6deuYPHkyAA888ACjR4+mf//+jBkzhqSkJIYMGcJDDz1EcHAwAGPGjOGJJ54gKCiIbt26kZaWxsqVKxkyZMi17aiIXBNKgESkVJg/fz4hISFO2yIjI9m+fTtgn6E1Y8YMnnrqKUJCQvj2229p1KgRAD4+PixYsIBnnnmG1q1b4+PjQ+/evZkwYYLjXP379ycrK4v33nuP5557joCAAO6+++5r10ERuaYshmEYZgchInI1LBYLs2bNolevXmaHIiKlhGqAREREpNxRAiQiIiLljmqARKTU05V8ESksjQCJiIhIuaMESERERModJUAiIiJS7igBEhERkXJHCZCIiIiUO0qAREREpNxRAiQiIiLljhIgERERKXeUAImIiEi58/8U4zqe1kif2wAAAABJRU5ErkJggg==",
|
390 |
+
"text/plain": [
|
391 |
+
"<Figure size 640x480 with 1 Axes>"
|
392 |
+
]
|
393 |
+
},
|
394 |
+
"metadata": {},
|
395 |
+
"output_type": "display_data"
|
396 |
+
}
|
397 |
+
],
|
398 |
+
"source": [
|
399 |
+
"# plot the training history to visualize the learning over epochs:\n",
|
400 |
+
"import matplotlib.pyplot as plt\n",
|
401 |
+
"# Plotting training history\n",
|
402 |
+
"plt.plot(history.history['accuracy'], label='Accuracy')\n",
|
403 |
+
"plt.plot(history.history['val_accuracy'], label='Validation Accuracy')\n",
|
404 |
+
"plt.title('Model Accuracy')\n",
|
405 |
+
"plt.ylabel('Accuracy')\n",
|
406 |
+
"plt.xlabel('Epoch')\n",
|
407 |
+
"plt.legend()\n",
|
408 |
+
"plt.show()"
|
409 |
+
]
|
410 |
+
},
|
411 |
+
{
|
412 |
+
"cell_type": "markdown",
|
413 |
+
"id": "f1590396",
|
414 |
+
"metadata": {},
|
415 |
+
"source": [
|
416 |
+
"## Model Load\n",
|
417 |
+
"\n",
|
418 |
+
"- load the sentiment_model.h5 model from you dir "
|
419 |
+
]
|
420 |
+
},
|
421 |
+
{
|
422 |
+
"cell_type": "code",
|
423 |
+
"execution_count": 15,
|
424 |
+
"id": "57021426",
|
425 |
+
"metadata": {},
|
426 |
+
"outputs": [],
|
427 |
+
"source": [
|
428 |
+
"from tensorflow.keras.models import load_model\n",
|
429 |
+
"\n",
|
430 |
+
"# Load the model\n",
|
431 |
+
"model = load_model('sentiment_model.h5')"
|
432 |
+
]
|
433 |
+
},
|
434 |
+
{
|
435 |
+
"cell_type": "code",
|
436 |
+
"execution_count": 16,
|
437 |
+
"id": "9acdbe1f",
|
438 |
+
"metadata": {},
|
439 |
+
"outputs": [],
|
440 |
+
"source": [
|
441 |
+
"# Load tokenizer\n",
|
442 |
+
"with open('tokenizer.pkl', 'rb') as f:\n",
|
443 |
+
" tokenizer = pickle.load(f)"
|
444 |
+
]
|
445 |
+
},
|
446 |
+
{
|
447 |
+
"cell_type": "code",
|
448 |
+
"execution_count": 17,
|
449 |
+
"id": "b44fd582",
|
450 |
+
"metadata": {},
|
451 |
+
"outputs": [],
|
452 |
+
"source": [
|
453 |
+
"# from tensorflow.keras.preprocessing.text import Tokenizer\n",
|
454 |
+
"from tensorflow.keras.preprocessing.sequence import pad_sequences"
|
455 |
+
]
|
456 |
+
},
|
457 |
+
{
|
458 |
+
"cell_type": "markdown",
|
459 |
+
"id": "bbf51b83",
|
460 |
+
"metadata": {},
|
461 |
+
"source": [
|
462 |
+
"## Utility Functions for Text Preprocessing and Sentiment Prediction:\n",
|
463 |
+
"\n",
|
464 |
+
"- preprocess_text converts input texts into padded sequences suitable for model input, using the previously defined tokenizer.\n",
|
465 |
+
"- predict_sentiment processes texts, makes predictions with the trained model, and interprets the results as 'Positive' or 'Negative' based on the prediction score."
|
466 |
+
]
|
467 |
+
},
|
468 |
+
{
|
469 |
+
"cell_type": "code",
|
470 |
+
"execution_count": 18,
|
471 |
+
"id": "de6eac0b",
|
472 |
+
"metadata": {},
|
473 |
+
"outputs": [],
|
474 |
+
"source": [
|
475 |
+
"def preprocess_text(texts, tokenizer, max_length=250):\n",
|
476 |
+
" sequences = tokenizer.texts_to_sequences(texts)\n",
|
477 |
+
" padded_sequences = pad_sequences(sequences, maxlen=max_length, padding='post')\n",
|
478 |
+
" return padded_sequences\n",
|
479 |
+
"\n",
|
480 |
+
"def predict_sentiment(texts, model, tokenizer):\n",
|
481 |
+
" preprocessed_texts = preprocess_text(texts, tokenizer)\n",
|
482 |
+
" predictions = model.predict(preprocessed_texts)\n",
|
483 |
+
" print(\"predictions\",predictions)\n",
|
484 |
+
" sentiment_labels = ['Negative' if pred < 0.5 else 'Positive' for pred in predictions.flatten()]\n",
|
485 |
+
" return sentiment_labels"
|
486 |
+
]
|
487 |
+
},
|
488 |
+
{
|
489 |
+
"cell_type": "markdown",
|
490 |
+
"id": "a58a1314",
|
491 |
+
"metadata": {},
|
492 |
+
"source": [
|
493 |
+
"## Sentiment Prediction on New Reviews:\n",
|
494 |
+
"\n",
|
495 |
+
"- Lists new review texts to test the model.\n",
|
496 |
+
"- Calls predict_sentiment to determine the sentiment of each review.\n",
|
497 |
+
"- Prints out each review with its predicted sentiment, providing a practical demonstration of the model in action."
|
498 |
+
]
|
499 |
+
},
|
500 |
+
{
|
501 |
+
"cell_type": "code",
|
502 |
+
"execution_count": 20,
|
503 |
+
"id": "d95588b0",
|
504 |
+
"metadata": {
|
505 |
+
"scrolled": true
|
506 |
+
},
|
507 |
+
"outputs": [
|
508 |
+
{
|
509 |
+
"name": "stdout",
|
510 |
+
"output_type": "stream",
|
511 |
+
"text": [
|
512 |
+
"1/1 [==============================] - 0s 245ms/step\n",
|
513 |
+
"predictions [[0.9961173 ]\n",
|
514 |
+
" [0.00163375]\n",
|
515 |
+
" [0.5040343 ]\n",
|
516 |
+
" [0.9762217 ]\n",
|
517 |
+
" [0.00119857]\n",
|
518 |
+
" [0.15386383]\n",
|
519 |
+
" [0.98825365]]\n",
|
520 |
+
"Review: I absolutely loved this product, it worked wonders for me!\n",
|
521 |
+
"Sentiment: Positive\n",
|
522 |
+
"\n",
|
523 |
+
"Review: Horrible experience, it broke down the first time I used it.\n",
|
524 |
+
"Sentiment: Negative\n",
|
525 |
+
"\n",
|
526 |
+
"Review: Okay product, but I expected something better.\n",
|
527 |
+
"Sentiment: Positive\n",
|
528 |
+
"\n",
|
529 |
+
"Review: Perfect, just as described! Would buy again!\n",
|
530 |
+
"Sentiment: Positive\n",
|
531 |
+
"\n",
|
532 |
+
"Review: Not worth the money, very disappointing.\n",
|
533 |
+
"Sentiment: Negative\n",
|
534 |
+
"\n",
|
535 |
+
"Review: If you want to listen to El Duke , then it is better if you have access to his shower,this is not him, it is a gimmick,very well orchestrated.\n",
|
536 |
+
"Sentiment: Negative\n",
|
537 |
+
"\n",
|
538 |
+
"Review: Review of Kelly Club for Toddlers: For the price of 7.99, this PC game is WELL worth it, great graphics, colorful and lots to do! My four year old daughter is in love with the many tasks to complete in this game, including dressing and grooming wide variety of pets and decoration of numerous floats to show in your little one's very own parade.\n",
|
539 |
+
"Sentiment: Positive\n",
|
540 |
+
"\n"
|
541 |
+
]
|
542 |
+
}
|
543 |
+
],
|
544 |
+
"source": [
|
545 |
+
"# Example reviews\n",
|
546 |
+
"new_reviews = [\n",
|
547 |
+
" \"I absolutely loved this product, it worked wonders for me!\",\n",
|
548 |
+
" \"Horrible experience, it broke down the first time I used it.\",\n",
|
549 |
+
" \"Okay product, but I expected something better.\",\n",
|
550 |
+
" \"Perfect, just as described! Would buy again!\",\n",
|
551 |
+
" \"Not worth the money, very disappointing.\",\n",
|
552 |
+
" \"If you want to listen to El Duke , then it is better if you have access to his shower,this is not him, it is a gimmick,very well orchestrated.\",\n",
|
553 |
+
" \"Review of Kelly Club for Toddlers: For the price of 7.99, this PC game is WELL worth it, great graphics, colorful and lots to do! My four year old daughter is in love with the many tasks to complete in this game, including dressing and grooming wide variety of pets and decoration of numerous floats to show in your little one's very own parade.\"\n",
|
554 |
+
"]\n",
|
555 |
+
"\n",
|
556 |
+
"# Predict sentiments\n",
|
557 |
+
"sentiments = predict_sentiment(new_reviews, model, tokenizer)\n",
|
558 |
+
"# print(sentiments)\n",
|
559 |
+
"for review, sentiment in zip(new_reviews, sentiments):\n",
|
560 |
+
" print(f\"Review: {review}\\nSentiment: {sentiment}\\n\")"
|
561 |
+
]
|
562 |
+
},
|
563 |
+
{
|
564 |
+
"cell_type": "code",
|
565 |
+
"execution_count": 23,
|
566 |
+
"id": "6a3b88ac",
|
567 |
+
"metadata": {},
|
568 |
+
"outputs": [
|
569 |
+
{
|
570 |
+
"name": "stdout",
|
571 |
+
"output_type": "stream",
|
572 |
+
"text": [
|
573 |
+
"1/1 [==============================] - 0s 218ms/step\n",
|
574 |
+
"Prediction: [0.00290678]\n",
|
575 |
+
"Review: very bad product\n",
|
576 |
+
"Sentiment: Negative\n",
|
577 |
+
"\n"
|
578 |
+
]
|
579 |
+
}
|
580 |
+
],
|
581 |
+
"source": [
|
582 |
+
"def preprocess_text(text, tokenizer, max_length=250):\n",
|
583 |
+
" sequence = tokenizer.texts_to_sequences([text])\n",
|
584 |
+
" padded_sequence = pad_sequences(sequence, maxlen=max_length, padding='post')\n",
|
585 |
+
" return padded_sequence\n",
|
586 |
+
"\n",
|
587 |
+
"def predict_sentiment(text, model, tokenizer):\n",
|
588 |
+
" preprocessed_text = preprocess_text(text, tokenizer)\n",
|
589 |
+
" prediction = model.predict(preprocessed_text)[0]\n",
|
590 |
+
" print(\"Prediction:\", prediction)\n",
|
591 |
+
" sentiment_label = 'Negative' if prediction < 0.5 else 'Positive'\n",
|
592 |
+
" return sentiment_label\n",
|
593 |
+
"\n",
|
594 |
+
"# Example review\n",
|
595 |
+
"new_review = \"very bad product\"\n",
|
596 |
+
"\n",
|
597 |
+
"# Predict sentiment\n",
|
598 |
+
"sentiment = predict_sentiment(new_review, model, tokenizer)\n",
|
599 |
+
"print(f\"Review: {new_review}\\nSentiment: {sentiment}\\n\")"
|
600 |
+
]
|
601 |
+
},
|
602 |
+
{
|
603 |
+
"cell_type": "code",
|
604 |
+
"execution_count": null,
|
605 |
+
"id": "f35e0602",
|
606 |
+
"metadata": {},
|
607 |
+
"outputs": [],
|
608 |
+
"source": []
|
609 |
+
}
|
610 |
+
],
|
611 |
+
"metadata": {
|
612 |
+
"kernelspec": {
|
613 |
+
"display_name": "Python 3 (ipykernel)",
|
614 |
+
"language": "python",
|
615 |
+
"name": "python3"
|
616 |
+
},
|
617 |
+
"language_info": {
|
618 |
+
"codemirror_mode": {
|
619 |
+
"name": "ipython",
|
620 |
+
"version": 3
|
621 |
+
},
|
622 |
+
"file_extension": ".py",
|
623 |
+
"mimetype": "text/x-python",
|
624 |
+
"name": "python",
|
625 |
+
"nbconvert_exporter": "python",
|
626 |
+
"pygments_lexer": "ipython3",
|
627 |
+
"version": "3.10.13"
|
628 |
+
}
|
629 |
+
},
|
630 |
+
"nbformat": 4,
|
631 |
+
"nbformat_minor": 5
|
632 |
+
}
|
sentiment_model.h5
ADDED
@@ -0,0 +1,3 @@
|
|
|
|
|
|
|
|
|
1 |
+
version https://git-lfs.github.com/spec/v1
|
2 |
+
oid sha256:b3704b821e72953badc6928655fd75b99d50fe9cb64cd6927c750a1ed126f1e4
|
3 |
+
size 32258920
|
tokenizer.pkl
ADDED
@@ -0,0 +1,3 @@
|
|
|
|
|
|
|
|
|
1 |
+
version https://git-lfs.github.com/spec/v1
|
2 |
+
oid sha256:697f16502f305020782d15817603691b2e6d18cc12575a4b0e51587ea47f9042
|
3 |
+
size 5225266
|