KarthikaRajagopal commited on
Commit
43bbc2e
·
verified ·
1 Parent(s): 71f8089

Upload Sentiment Analysis of Restaurant Reviews.ipynb

Browse files
Sentiment Analysis of Restaurant Reviews.ipynb ADDED
@@ -0,0 +1,776 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ {
2
+ "nbformat": 4,
3
+ "nbformat_minor": 0,
4
+ "metadata": {
5
+ "colab": {
6
+ "name": "Sentiment Analysis - Restaurant Reviews.ipynb",
7
+ "provenance": [],
8
+ "collapsed_sections": [],
9
+ "toc_visible": true
10
+ },
11
+ "kernelspec": {
12
+ "name": "python3",
13
+ "display_name": "Python 3"
14
+ }
15
+ },
16
+ "cells": [
17
+ {
18
+ "cell_type": "code",
19
+ "metadata": {
20
+ "id": "kh4udnC9fZyU",
21
+ "colab_type": "code",
22
+ "outputId": "677fbeb5-d5b2-49f7-99bf-92bd1f2fa44e",
23
+ "colab": {
24
+ "base_uri": "https://localhost:8080/",
25
+ "height": 34
26
+ }
27
+ },
28
+ "source": [
29
+ "# Connecting Google Drive with Google Colab\n",
30
+ "from google.colab import drive\n",
31
+ "drive.mount('/content/drive/')"
32
+ ],
33
+ "execution_count": 1,
34
+ "outputs": [
35
+ {
36
+ "output_type": "stream",
37
+ "text": [
38
+ "Drive already mounted at /content/drive/; to attempt to forcibly remount, call drive.mount(\"/content/drive/\", force_remount=True).\n"
39
+ ],
40
+ "name": "stdout"
41
+ }
42
+ ]
43
+ },
44
+ {
45
+ "cell_type": "code",
46
+ "metadata": {
47
+ "id": "wqtOguIVfysM",
48
+ "colab_type": "code",
49
+ "colab": {}
50
+ },
51
+ "source": [
52
+ "# Importing essential libraries\n",
53
+ "import numpy as np\n",
54
+ "import pandas as pd"
55
+ ],
56
+ "execution_count": 0,
57
+ "outputs": []
58
+ },
59
+ {
60
+ "cell_type": "code",
61
+ "metadata": {
62
+ "id": "FsZFCtjijekC",
63
+ "colab_type": "code",
64
+ "colab": {}
65
+ },
66
+ "source": [
67
+ "# Loading the dataset\n",
68
+ "df = pd.read_csv('/content/drive/My Drive/Colab Notebooks/Datasets/Restaurant_Reviews.tsv', delimiter='\\t', quoting=3)"
69
+ ],
70
+ "execution_count": 0,
71
+ "outputs": []
72
+ },
73
+ {
74
+ "cell_type": "code",
75
+ "metadata": {
76
+ "id": "zkdfWSlej05y",
77
+ "colab_type": "code",
78
+ "outputId": "26f108a7-5617-4abe-efae-0d64d31e8041",
79
+ "colab": {
80
+ "base_uri": "https://localhost:8080/",
81
+ "height": 34
82
+ }
83
+ },
84
+ "source": [
85
+ "df.shape"
86
+ ],
87
+ "execution_count": 4,
88
+ "outputs": [
89
+ {
90
+ "output_type": "execute_result",
91
+ "data": {
92
+ "text/plain": [
93
+ "(1000, 2)"
94
+ ]
95
+ },
96
+ "metadata": {
97
+ "tags": []
98
+ },
99
+ "execution_count": 4
100
+ }
101
+ ]
102
+ },
103
+ {
104
+ "cell_type": "code",
105
+ "metadata": {
106
+ "id": "SyYImhASubeb",
107
+ "colab_type": "code",
108
+ "outputId": "2c8efdb6-17a5-48da-8ac2-7c9d2c289b09",
109
+ "colab": {
110
+ "base_uri": "https://localhost:8080/",
111
+ "height": 34
112
+ }
113
+ },
114
+ "source": [
115
+ "df.columns"
116
+ ],
117
+ "execution_count": 5,
118
+ "outputs": [
119
+ {
120
+ "output_type": "execute_result",
121
+ "data": {
122
+ "text/plain": [
123
+ "Index(['Review', 'Liked'], dtype='object')"
124
+ ]
125
+ },
126
+ "metadata": {
127
+ "tags": []
128
+ },
129
+ "execution_count": 5
130
+ }
131
+ ]
132
+ },
133
+ {
134
+ "cell_type": "code",
135
+ "metadata": {
136
+ "id": "b5lzlG5DMNX9",
137
+ "colab_type": "code",
138
+ "outputId": "ab125608-7f10-479c-8dab-bb298fa7bbaf",
139
+ "colab": {
140
+ "base_uri": "https://localhost:8080/",
141
+ "height": 197
142
+ }
143
+ },
144
+ "source": [
145
+ "df.head()"
146
+ ],
147
+ "execution_count": 6,
148
+ "outputs": [
149
+ {
150
+ "output_type": "execute_result",
151
+ "data": {
152
+ "text/html": [
153
+ "<div>\n",
154
+ "<style scoped>\n",
155
+ " .dataframe tbody tr th:only-of-type {\n",
156
+ " vertical-align: middle;\n",
157
+ " }\n",
158
+ "\n",
159
+ " .dataframe tbody tr th {\n",
160
+ " vertical-align: top;\n",
161
+ " }\n",
162
+ "\n",
163
+ " .dataframe thead th {\n",
164
+ " text-align: right;\n",
165
+ " }\n",
166
+ "</style>\n",
167
+ "<table border=\"1\" class=\"dataframe\">\n",
168
+ " <thead>\n",
169
+ " <tr style=\"text-align: right;\">\n",
170
+ " <th></th>\n",
171
+ " <th>Review</th>\n",
172
+ " <th>Liked</th>\n",
173
+ " </tr>\n",
174
+ " </thead>\n",
175
+ " <tbody>\n",
176
+ " <tr>\n",
177
+ " <th>0</th>\n",
178
+ " <td>Wow... Loved this place.</td>\n",
179
+ " <td>1</td>\n",
180
+ " </tr>\n",
181
+ " <tr>\n",
182
+ " <th>1</th>\n",
183
+ " <td>Crust is not good.</td>\n",
184
+ " <td>0</td>\n",
185
+ " </tr>\n",
186
+ " <tr>\n",
187
+ " <th>2</th>\n",
188
+ " <td>Not tasty and the texture was just nasty.</td>\n",
189
+ " <td>0</td>\n",
190
+ " </tr>\n",
191
+ " <tr>\n",
192
+ " <th>3</th>\n",
193
+ " <td>Stopped by during the late May bank holiday of...</td>\n",
194
+ " <td>1</td>\n",
195
+ " </tr>\n",
196
+ " <tr>\n",
197
+ " <th>4</th>\n",
198
+ " <td>The selection on the menu was great and so wer...</td>\n",
199
+ " <td>1</td>\n",
200
+ " </tr>\n",
201
+ " </tbody>\n",
202
+ "</table>\n",
203
+ "</div>"
204
+ ],
205
+ "text/plain": [
206
+ " Review Liked\n",
207
+ "0 Wow... Loved this place. 1\n",
208
+ "1 Crust is not good. 0\n",
209
+ "2 Not tasty and the texture was just nasty. 0\n",
210
+ "3 Stopped by during the late May bank holiday of... 1\n",
211
+ "4 The selection on the menu was great and so wer... 1"
212
+ ]
213
+ },
214
+ "metadata": {
215
+ "tags": []
216
+ },
217
+ "execution_count": 6
218
+ }
219
+ ]
220
+ },
221
+ {
222
+ "cell_type": "markdown",
223
+ "metadata": {
224
+ "id": "38_tPfGAr0AL",
225
+ "colab_type": "text"
226
+ },
227
+ "source": [
228
+ "# **Data Preprocessing**"
229
+ ]
230
+ },
231
+ {
232
+ "cell_type": "code",
233
+ "metadata": {
234
+ "id": "gZpsSpUAkCyH",
235
+ "colab_type": "code",
236
+ "outputId": "81a672d9-a796-4789-e2e8-36d360f9e558",
237
+ "colab": {
238
+ "base_uri": "https://localhost:8080/",
239
+ "height": 52
240
+ }
241
+ },
242
+ "source": [
243
+ "# Importing essential libraries for performing Natural Language Processing on 'Restaurant_Reviews.tsv' dataset\n",
244
+ "import nltk\n",
245
+ "import re\n",
246
+ "nltk.download('stopwords')\n",
247
+ "from nltk.corpus import stopwords\n",
248
+ "from nltk.stem.porter import PorterStemmer"
249
+ ],
250
+ "execution_count": 7,
251
+ "outputs": [
252
+ {
253
+ "output_type": "stream",
254
+ "text": [
255
+ "[nltk_data] Downloading package stopwords to /root/nltk_data...\n",
256
+ "[nltk_data] Package stopwords is already up-to-date!\n"
257
+ ],
258
+ "name": "stdout"
259
+ }
260
+ ]
261
+ },
262
+ {
263
+ "cell_type": "code",
264
+ "metadata": {
265
+ "id": "tUnp7Dr7mFwn",
266
+ "colab_type": "code",
267
+ "colab": {}
268
+ },
269
+ "source": [
270
+ "# Cleaning the reviews\n",
271
+ "corpus = []\n",
272
+ "for i in range(0,1000):\n",
273
+ "\n",
274
+ " # Cleaning special character from the reviews\n",
275
+ " review = re.sub(pattern='[^a-zA-Z]',repl=' ', string=df['Review'][i])\n",
276
+ "\n",
277
+ " # Converting the entire review into lower case\n",
278
+ " review = review.lower()\n",
279
+ "\n",
280
+ " # Tokenizing the review by words\n",
281
+ " review_words = review.split()\n",
282
+ "\n",
283
+ " # Removing the stop words\n",
284
+ " review_words = [word for word in review_words if not word in set(stopwords.words('english'))]\n",
285
+ "\n",
286
+ " # Stemming the words\n",
287
+ " ps = PorterStemmer()\n",
288
+ " review = [ps.stem(word) for word in review_words]\n",
289
+ "\n",
290
+ " # Joining the stemmed words\n",
291
+ " review = ' '.join(review)\n",
292
+ "\n",
293
+ " # Creating a corpus\n",
294
+ " corpus.append(review)"
295
+ ],
296
+ "execution_count": 0,
297
+ "outputs": []
298
+ },
299
+ {
300
+ "cell_type": "code",
301
+ "metadata": {
302
+ "id": "6ewB2oNJ0rr9",
303
+ "colab_type": "code",
304
+ "outputId": "9f2c2e4b-adf7-4157-d573-f3383a16cee0",
305
+ "colab": {
306
+ "base_uri": "https://localhost:8080/",
307
+ "height": 194
308
+ }
309
+ },
310
+ "source": [
311
+ "corpus[0:10]"
312
+ ],
313
+ "execution_count": 9,
314
+ "outputs": [
315
+ {
316
+ "output_type": "execute_result",
317
+ "data": {
318
+ "text/plain": [
319
+ "['wow love place',\n",
320
+ " 'crust good',\n",
321
+ " 'tasti textur nasti',\n",
322
+ " 'stop late may bank holiday rick steve recommend love',\n",
323
+ " 'select menu great price',\n",
324
+ " 'get angri want damn pho',\n",
325
+ " 'honeslti tast fresh',\n",
326
+ " 'potato like rubber could tell made ahead time kept warmer',\n",
327
+ " 'fri great',\n",
328
+ " 'great touch']"
329
+ ]
330
+ },
331
+ "metadata": {
332
+ "tags": []
333
+ },
334
+ "execution_count": 9
335
+ }
336
+ ]
337
+ },
338
+ {
339
+ "cell_type": "code",
340
+ "metadata": {
341
+ "id": "spNHLhGs20LV",
342
+ "colab_type": "code",
343
+ "colab": {}
344
+ },
345
+ "source": [
346
+ "# Creating the Bag of Words model\n",
347
+ "from sklearn.feature_extraction.text import CountVectorizer\n",
348
+ "cv = CountVectorizer(max_features=1500)\n",
349
+ "X = cv.fit_transform(corpus).toarray()\n",
350
+ "y = df.iloc[:, 1].values"
351
+ ],
352
+ "execution_count": 0,
353
+ "outputs": []
354
+ },
355
+ {
356
+ "cell_type": "markdown",
357
+ "metadata": {
358
+ "id": "jYNkfBqJ42hs",
359
+ "colab_type": "text"
360
+ },
361
+ "source": [
362
+ "# **Model Building**"
363
+ ]
364
+ },
365
+ {
366
+ "cell_type": "code",
367
+ "metadata": {
368
+ "id": "sL6FOXMx45w0",
369
+ "colab_type": "code",
370
+ "colab": {}
371
+ },
372
+ "source": [
373
+ "from sklearn.model_selection import train_test_split\n",
374
+ "X_train, X_test, y_train, y_test = train_test_split(X, y, test_size = 0.20, random_state = 0)"
375
+ ],
376
+ "execution_count": 0,
377
+ "outputs": []
378
+ },
379
+ {
380
+ "cell_type": "code",
381
+ "metadata": {
382
+ "id": "KYTe6hjJDV8K",
383
+ "colab_type": "code",
384
+ "outputId": "56f78ef1-3f7f-40ce-cf1c-15a2b91b61c3",
385
+ "colab": {
386
+ "base_uri": "https://localhost:8080/",
387
+ "height": 34
388
+ }
389
+ },
390
+ "source": [
391
+ "# Fitting Naive Bayes to the Training set\n",
392
+ "from sklearn.naive_bayes import MultinomialNB\n",
393
+ "classifier = MultinomialNB()\n",
394
+ "classifier.fit(X_train, y_train)"
395
+ ],
396
+ "execution_count": 12,
397
+ "outputs": [
398
+ {
399
+ "output_type": "execute_result",
400
+ "data": {
401
+ "text/plain": [
402
+ "MultinomialNB(alpha=1.0, class_prior=None, fit_prior=True)"
403
+ ]
404
+ },
405
+ "metadata": {
406
+ "tags": []
407
+ },
408
+ "execution_count": 12
409
+ }
410
+ ]
411
+ },
412
+ {
413
+ "cell_type": "code",
414
+ "metadata": {
415
+ "id": "CjXrDsEyDbD7",
416
+ "colab_type": "code",
417
+ "colab": {}
418
+ },
419
+ "source": [
420
+ "# Predicting the Test set results\n",
421
+ "y_pred = classifier.predict(X_test)"
422
+ ],
423
+ "execution_count": 0,
424
+ "outputs": []
425
+ },
426
+ {
427
+ "cell_type": "code",
428
+ "metadata": {
429
+ "id": "CcRU4PabPDY-",
430
+ "colab_type": "code",
431
+ "outputId": "4985115a-e9be-4447-9a22-026c59045ec9",
432
+ "colab": {
433
+ "base_uri": "https://localhost:8080/",
434
+ "height": 87
435
+ }
436
+ },
437
+ "source": [
438
+ "# Accuracy, Precision and Recall\n",
439
+ "from sklearn.metrics import accuracy_score\n",
440
+ "from sklearn.metrics import precision_score\n",
441
+ "from sklearn.metrics import recall_score\n",
442
+ "score1 = accuracy_score(y_test,y_pred)\n",
443
+ "score2 = precision_score(y_test,y_pred)\n",
444
+ "score3= recall_score(y_test,y_pred)\n",
445
+ "print(\"---- Scores ----\")\n",
446
+ "print(\"Accuracy score is: {}%\".format(round(score1*100,2)))\n",
447
+ "print(\"Precision score is: {}\".format(round(score2,2)))\n",
448
+ "print(\"Recall score is: {}\".format(round(score3,2)))"
449
+ ],
450
+ "execution_count": 14,
451
+ "outputs": [
452
+ {
453
+ "output_type": "stream",
454
+ "text": [
455
+ "---- Scores ----\n",
456
+ "Accuracy score is: 76.5%\n",
457
+ "Precision score is: 0.76\n",
458
+ "Recall score is: 0.79\n"
459
+ ],
460
+ "name": "stdout"
461
+ }
462
+ ]
463
+ },
464
+ {
465
+ "cell_type": "code",
466
+ "metadata": {
467
+ "id": "-77oRRHjDgwr",
468
+ "colab_type": "code",
469
+ "colab": {}
470
+ },
471
+ "source": [
472
+ "# Making the Confusion Matrix\n",
473
+ "from sklearn.metrics import confusion_matrix\n",
474
+ "cm = confusion_matrix(y_test, y_pred)"
475
+ ],
476
+ "execution_count": 0,
477
+ "outputs": []
478
+ },
479
+ {
480
+ "cell_type": "code",
481
+ "metadata": {
482
+ "id": "9lRKOJ-zjv3F",
483
+ "colab_type": "code",
484
+ "colab": {
485
+ "base_uri": "https://localhost:8080/",
486
+ "height": 52
487
+ },
488
+ "outputId": "b5c14f34-e062-4cf6-b899-31a5d583d62c"
489
+ },
490
+ "source": [
491
+ "cm"
492
+ ],
493
+ "execution_count": 16,
494
+ "outputs": [
495
+ {
496
+ "output_type": "execute_result",
497
+ "data": {
498
+ "text/plain": [
499
+ "array([[72, 25],\n",
500
+ " [22, 81]])"
501
+ ]
502
+ },
503
+ "metadata": {
504
+ "tags": []
505
+ },
506
+ "execution_count": 16
507
+ }
508
+ ]
509
+ },
510
+ {
511
+ "cell_type": "code",
512
+ "metadata": {
513
+ "id": "hYd9LdXmDkKb",
514
+ "colab_type": "code",
515
+ "outputId": "30c403fb-f204-42ff-a19c-eb2ecbdf8cd5",
516
+ "colab": {
517
+ "base_uri": "https://localhost:8080/",
518
+ "height": 461
519
+ }
520
+ },
521
+ "source": [
522
+ "# Plotting the confusion matrix\n",
523
+ "import matplotlib.pyplot as plt\n",
524
+ "import seaborn as sns\n",
525
+ "%matplotlib inline\n",
526
+ "\n",
527
+ "plt.figure(figsize = (10,6))\n",
528
+ "sns.heatmap(cm, annot=True, cmap=\"YlGnBu\", xticklabels=['Negative', 'Positive'], yticklabels=['Negative', 'Positive'])\n",
529
+ "plt.xlabel('Predicted values')\n",
530
+ "plt.ylabel('Actual values')"
531
+ ],
532
+ "execution_count": 17,
533
+ "outputs": [
534
+ {
535
+ "output_type": "stream",
536
+ "text": [
537
+ "/usr/local/lib/python3.6/dist-packages/statsmodels/tools/_testing.py:19: FutureWarning: pandas.util.testing is deprecated. Use the functions in the public API at pandas.testing instead.\n",
538
+ " import pandas.util.testing as tm\n"
539
+ ],
540
+ "name": "stderr"
541
+ },
542
+ {
543
+ "output_type": "execute_result",
544
+ "data": {
545
+ "text/plain": [
546
+ "Text(69.0, 0.5, 'Actual values')"
547
+ ]
548
+ },
549
+ "metadata": {
550
+ "tags": []
551
+ },
552
+ "execution_count": 17
553
+ },
554
+ {
555
+ "output_type": "display_data",
556
+ "data": {
557
+ "image/png": "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\n",
558
+ "text/plain": [
559
+ "<Figure size 720x432 with 2 Axes>"
560
+ ]
561
+ },
562
+ "metadata": {
563
+ "tags": [],
564
+ "needs_background": "light"
565
+ }
566
+ }
567
+ ]
568
+ },
569
+ {
570
+ "cell_type": "code",
571
+ "metadata": {
572
+ "id": "LJbZKcc9jWcV",
573
+ "colab_type": "code",
574
+ "colab": {
575
+ "base_uri": "https://localhost:8080/",
576
+ "height": 230
577
+ },
578
+ "outputId": "654b7fc8-9c8e-452b-c14c-dd57c87d82ec"
579
+ },
580
+ "source": [
581
+ "# Hyperparameter tuning the Naive Bayes Classifier\n",
582
+ "best_accuracy = 0.0\n",
583
+ "alpha_val = 0.0\n",
584
+ "for i in np.arange(0.1,1.1,0.1):\n",
585
+ " temp_classifier = MultinomialNB(alpha=i)\n",
586
+ " temp_classifier.fit(X_train, y_train)\n",
587
+ " temp_y_pred = temp_classifier.predict(X_test)\n",
588
+ " score = accuracy_score(y_test, temp_y_pred)\n",
589
+ " print(\"Accuracy score for alpha={} is: {}%\".format(round(i,1), round(score*100,2)))\n",
590
+ " if score>best_accuracy:\n",
591
+ " best_accuracy = score\n",
592
+ " alpha_val = i\n",
593
+ "print('--------------------------------------------')\n",
594
+ "print('The best accuracy is {}% with alpha value as {}'.format(round(best_accuracy*100, 2), round(alpha_val,1)))"
595
+ ],
596
+ "execution_count": 18,
597
+ "outputs": [
598
+ {
599
+ "output_type": "stream",
600
+ "text": [
601
+ "Accuracy score for alpha=0.1 is: 78.0%\n",
602
+ "Accuracy score for alpha=0.2 is: 78.5%\n",
603
+ "Accuracy score for alpha=0.3 is: 78.0%\n",
604
+ "Accuracy score for alpha=0.4 is: 78.0%\n",
605
+ "Accuracy score for alpha=0.5 is: 77.5%\n",
606
+ "Accuracy score for alpha=0.6 is: 77.5%\n",
607
+ "Accuracy score for alpha=0.7 is: 77.5%\n",
608
+ "Accuracy score for alpha=0.8 is: 77.0%\n",
609
+ "Accuracy score for alpha=0.9 is: 76.5%\n",
610
+ "Accuracy score for alpha=1.0 is: 76.5%\n",
611
+ "--------------------------------------------\n",
612
+ "The best accuracy is 78.5% with alpha value as 0.2\n"
613
+ ],
614
+ "name": "stdout"
615
+ }
616
+ ]
617
+ },
618
+ {
619
+ "cell_type": "code",
620
+ "metadata": {
621
+ "id": "9BNR7SfKkDsL",
622
+ "colab_type": "code",
623
+ "colab": {
624
+ "base_uri": "https://localhost:8080/",
625
+ "height": 34
626
+ },
627
+ "outputId": "0ebe229f-009d-46fa-852c-90b758d548b6"
628
+ },
629
+ "source": [
630
+ "classifier = MultinomialNB(alpha=0.2)\n",
631
+ "classifier.fit(X_train, y_train)"
632
+ ],
633
+ "execution_count": 19,
634
+ "outputs": [
635
+ {
636
+ "output_type": "execute_result",
637
+ "data": {
638
+ "text/plain": [
639
+ "MultinomialNB(alpha=0.2, class_prior=None, fit_prior=True)"
640
+ ]
641
+ },
642
+ "metadata": {
643
+ "tags": []
644
+ },
645
+ "execution_count": 19
646
+ }
647
+ ]
648
+ },
649
+ {
650
+ "cell_type": "markdown",
651
+ "metadata": {
652
+ "id": "iYQVSu17MWgV",
653
+ "colab_type": "text"
654
+ },
655
+ "source": [
656
+ "# **Predictions**"
657
+ ]
658
+ },
659
+ {
660
+ "cell_type": "code",
661
+ "metadata": {
662
+ "id": "mYbh9DFvwmW1",
663
+ "colab_type": "code",
664
+ "colab": {}
665
+ },
666
+ "source": [
667
+ "def predict_sentiment(sample_review):\n",
668
+ " sample_review = re.sub(pattern='[^a-zA-Z]',repl=' ', string = sample_review)\n",
669
+ " sample_review = sample_review.lower()\n",
670
+ " sample_review_words = sample_review.split()\n",
671
+ " sample_review_words = [word for word in sample_review_words if not word in set(stopwords.words('english'))]\n",
672
+ " ps = PorterStemmer()\n",
673
+ " final_review = [ps.stem(word) for word in sample_review_words]\n",
674
+ " final_review = ' '.join(final_review)\n",
675
+ "\n",
676
+ " temp = cv.transform([final_review]).toarray()\n",
677
+ " return classifier.predict(temp)"
678
+ ],
679
+ "execution_count": 0,
680
+ "outputs": []
681
+ },
682
+ {
683
+ "cell_type": "code",
684
+ "metadata": {
685
+ "id": "Os0d_BZELC95",
686
+ "colab_type": "code",
687
+ "outputId": "3478b8c9-55a9-454f-aaae-b42ccc28d609",
688
+ "colab": {
689
+ "base_uri": "https://localhost:8080/",
690
+ "height": 34
691
+ }
692
+ },
693
+ "source": [
694
+ "# Predicting values\n",
695
+ "sample_review = 'The food is really good here.'\n",
696
+ "\n",
697
+ "if predict_sentiment(sample_review):\n",
698
+ " print('This is a POSITIVE review.')\n",
699
+ "else:\n",
700
+ " print('This is a NEGATIVE review!')"
701
+ ],
702
+ "execution_count": 21,
703
+ "outputs": [
704
+ {
705
+ "output_type": "stream",
706
+ "text": [
707
+ "This is a POSITIVE review.\n"
708
+ ],
709
+ "name": "stdout"
710
+ }
711
+ ]
712
+ },
713
+ {
714
+ "cell_type": "code",
715
+ "metadata": {
716
+ "id": "A88ILf9PNAKY",
717
+ "colab_type": "code",
718
+ "outputId": "d1fe224e-373f-4e98-9c05-da96980d4f49",
719
+ "colab": {
720
+ "base_uri": "https://localhost:8080/",
721
+ "height": 34
722
+ }
723
+ },
724
+ "source": [
725
+ "# Predicting values\n",
726
+ "sample_review = 'Food was pretty bad and the service was very slow.'\n",
727
+ "\n",
728
+ "if predict_sentiment(sample_review):\n",
729
+ " print('This is a POSITIVE review.')\n",
730
+ "else:\n",
731
+ " print('This is a NEGATIVE review!')"
732
+ ],
733
+ "execution_count": 22,
734
+ "outputs": [
735
+ {
736
+ "output_type": "stream",
737
+ "text": [
738
+ "This is a NEGATIVE review!\n"
739
+ ],
740
+ "name": "stdout"
741
+ }
742
+ ]
743
+ },
744
+ {
745
+ "cell_type": "code",
746
+ "metadata": {
747
+ "id": "UXgRRzafOX3d",
748
+ "colab_type": "code",
749
+ "outputId": "f913faa2-38b5-48c6-f6fa-456ab807a01c",
750
+ "colab": {
751
+ "base_uri": "https://localhost:8080/",
752
+ "height": 34
753
+ }
754
+ },
755
+ "source": [
756
+ "# Predicting values\n",
757
+ "sample_review = 'The food was absolutely wonderful, from preparation to presentation, very pleasing.'\n",
758
+ "\n",
759
+ "if predict_sentiment(sample_review):\n",
760
+ " print('This is a POSITIVE review.')\n",
761
+ "else:\n",
762
+ " print('This is a NEGATIVE review!')"
763
+ ],
764
+ "execution_count": 23,
765
+ "outputs": [
766
+ {
767
+ "output_type": "stream",
768
+ "text": [
769
+ "This is a POSITIVE review.\n"
770
+ ],
771
+ "name": "stdout"
772
+ }
773
+ ]
774
+ }
775
+ ]
776
+ }