Student: Mohamed Kamal Abdullah Hasan commited on
Commit
b27ae83
·
1 Parent(s): 35305f1

lastes touches

Browse files
notebooks/01_data_acquisition.ipynb CHANGED
@@ -37,8 +37,8 @@
37
  "name": "stdout",
38
  "output_type": "stream",
39
  "text": [
40
- "/mnt/d/career/digilians/sentiment-analysis-of-amazon-reviews-using-machine-learning/notebooks\n",
41
- "/mnt/d/career/digilians/sentiment-analysis-of-amazon-reviews-using-machine-learning\n"
42
  ]
43
  }
44
  ],
@@ -481,13 +481,13 @@
481
  "name": "stdout",
482
  "output_type": "stream",
483
  "text": [
484
- "Saved dataframe sample_train.csv to data/samples/sample_train.csv\n"
485
  ]
486
  },
487
  {
488
  "data": {
489
  "text/plain": [
490
- "{'csv': PosixPath('data/samples/sample_train.csv')}"
491
  ]
492
  },
493
  "execution_count": 10,
@@ -644,13 +644,13 @@
644
  "name": "stdout",
645
  "output_type": "stream",
646
  "text": [
647
- "Saved dataframe sample_valid.csv to data/samples/sample_valid.csv\n"
648
  ]
649
  },
650
  {
651
  "data": {
652
  "text/plain": [
653
- "{'csv': PosixPath('data/samples/sample_valid.csv')}"
654
  ]
655
  },
656
  "execution_count": 13,
@@ -936,13 +936,13 @@
936
  "name": "stdout",
937
  "output_type": "stream",
938
  "text": [
939
- "Saved dataframe sample_test.csv to data/samples/sample_test.csv\n"
940
  ]
941
  },
942
  {
943
  "data": {
944
  "text/plain": [
945
- "{'csv': PosixPath('data/samples/sample_test.csv')}"
946
  ]
947
  },
948
  "execution_count": 18,
@@ -957,7 +957,7 @@
957
  ],
958
  "metadata": {
959
  "kernelspec": {
960
- "display_name": "mlqueens",
961
  "language": "python",
962
  "name": "python3"
963
  },
@@ -971,7 +971,7 @@
971
  "name": "python",
972
  "nbconvert_exporter": "python",
973
  "pygments_lexer": "ipython3",
974
- "version": "3.12.12"
975
  }
976
  },
977
  "nbformat": 4,
 
37
  "name": "stdout",
38
  "output_type": "stream",
39
  "text": [
40
+ "e:\\AI_ML\\proj\\sentiment-analysis-of-amazon-reviews-using-machine-learning-ml-queens\\notebooks\n",
41
+ "E:\\AI_ML\\proj\\sentiment-analysis-of-amazon-reviews-using-machine-learning-ml-queens\n"
42
  ]
43
  }
44
  ],
 
481
  "name": "stdout",
482
  "output_type": "stream",
483
  "text": [
484
+ "Saved dataframe sample_train.csv to data\\samples\\sample_train.csv\n"
485
  ]
486
  },
487
  {
488
  "data": {
489
  "text/plain": [
490
+ "{'csv': WindowsPath('data/samples/sample_train.csv')}"
491
  ]
492
  },
493
  "execution_count": 10,
 
644
  "name": "stdout",
645
  "output_type": "stream",
646
  "text": [
647
+ "Saved dataframe sample_valid.csv to data\\samples\\sample_valid.csv\n"
648
  ]
649
  },
650
  {
651
  "data": {
652
  "text/plain": [
653
+ "{'csv': WindowsPath('data/samples/sample_valid.csv')}"
654
  ]
655
  },
656
  "execution_count": 13,
 
936
  "name": "stdout",
937
  "output_type": "stream",
938
  "text": [
939
+ "Saved dataframe sample_test.csv to data\\samples\\sample_test.csv\n"
940
  ]
941
  },
942
  {
943
  "data": {
944
  "text/plain": [
945
+ "{'csv': WindowsPath('data/samples/sample_test.csv')}"
946
  ]
947
  },
948
  "execution_count": 18,
 
957
  ],
958
  "metadata": {
959
  "kernelspec": {
960
+ "display_name": ".venv",
961
  "language": "python",
962
  "name": "python3"
963
  },
 
971
  "name": "python",
972
  "nbconvert_exporter": "python",
973
  "pygments_lexer": "ipython3",
974
+ "version": "3.13.11"
975
  }
976
  },
977
  "nbformat": 4,
notebooks/02_eda.ipynb CHANGED
The diff for this file is too large to render. See raw diff
 
notebooks/03_data_preprocessing.ipynb CHANGED
@@ -38,8 +38,8 @@
38
  "name": "stdout",
39
  "output_type": "stream",
40
  "text": [
41
- "/mnt/d/career/digilians/sentiment-analysis-of-amazon-reviews-using-machine-learning/notebooks\n",
42
- "/mnt/d/career/digilians/sentiment-analysis-of-amazon-reviews-using-machine-learning\n"
43
  ]
44
  }
45
  ],
@@ -201,6 +201,16 @@
201
  "balanced_sample_train.info()"
202
  ]
203
  },
 
 
 
 
 
 
 
 
 
 
204
  {
205
  "cell_type": "markdown",
206
  "id": "d5b9401e",
@@ -252,7 +262,7 @@
252
  " <td>I HAVE HAD THE DX6340 FOR ABOUT A YEAR.I LOVE ...</td>\n",
253
  " <td>586</td>\n",
254
  " <td>108</td>\n",
255
- " <td>dx6340 year love picture good 35m easy use unl...</td>\n",
256
  " </tr>\n",
257
  " <tr>\n",
258
  " <th>1</th>\n",
@@ -261,7 +271,7 @@
261
  " <td>I'm using this book in an introductory organic...</td>\n",
262
  " <td>570</td>\n",
263
  " <td>88</td>\n",
264
- " <td>using book introductory organic spectroscopy c...</td>\n",
265
  " </tr>\n",
266
  " <tr>\n",
267
  " <th>2</th>\n",
@@ -270,7 +280,7 @@
270
  " <td>I only read the first few chapters and was bom...</td>\n",
271
  " <td>214</td>\n",
272
  " <td>40</td>\n",
273
- " <td>read first chapter bombarded reference 199 end...</td>\n",
274
  " </tr>\n",
275
  " <tr>\n",
276
  " <th>3</th>\n",
@@ -279,7 +289,7 @@
279
  " <td>Feels cheaply made, the battery contacts were ...</td>\n",
280
  " <td>193</td>\n",
281
  " <td>34</td>\n",
282
- " <td>feel cheaply made battery contact rusted soon ...</td>\n",
283
  " </tr>\n",
284
  " <tr>\n",
285
  " <th>4</th>\n",
@@ -288,7 +298,7 @@
288
  " <td>I love these sheets! They are sleek &amp; smooth w...</td>\n",
289
  " <td>198</td>\n",
290
  " <td>38</td>\n",
291
- " <td>love sheet sleek smooth really cool feel perfe...</td>\n",
292
  " </tr>\n",
293
  " </tbody>\n",
294
  "</table>\n",
@@ -317,11 +327,11 @@
317
  "4 198 38 \n",
318
  "\n",
319
  " review_content_cleaned \n",
320
- "0 dx6340 year love picture good 35m easy use unl... \n",
321
- "1 using book introductory organic spectroscopy c... \n",
322
- "2 read first chapter bombarded reference 199 end... \n",
323
- "3 feel cheaply made battery contact rusted soon ... \n",
324
- "4 love sheet sleek smooth really cool feel perfe... "
325
  ]
326
  },
327
  "execution_count": 5,
@@ -331,139 +341,18 @@
331
  ],
332
  "source": [
333
  "processed_train = balanced_sample_train.copy()\n",
334
- "processed_train['review_content_cleaned'] = clean_text(processed_train['review_content'])\n",
335
  "processed_train.head()"
336
  ]
337
  },
338
  {
339
- "cell_type": "code",
340
- "execution_count": 6,
341
- "id": "b251cec2",
342
  "metadata": {},
343
- "outputs": [
344
- {
345
- "data": {
346
- "text/html": [
347
- "<div>\n",
348
- "<style scoped>\n",
349
- " .dataframe tbody tr th:only-of-type {\n",
350
- " vertical-align: middle;\n",
351
- " }\n",
352
- "\n",
353
- " .dataframe tbody tr th {\n",
354
- " vertical-align: top;\n",
355
- " }\n",
356
- "\n",
357
- " .dataframe thead th {\n",
358
- " text-align: right;\n",
359
- " }\n",
360
- "</style>\n",
361
- "<table border=\"1\" class=\"dataframe\">\n",
362
- " <thead>\n",
363
- " <tr style=\"text-align: right;\">\n",
364
- " <th></th>\n",
365
- " <th>review_target</th>\n",
366
- " <th>review_title</th>\n",
367
- " <th>review_content</th>\n",
368
- " <th>review_content_char_count</th>\n",
369
- " <th>review_content_word_count</th>\n",
370
- " <th>review_content_cleaned</th>\n",
371
- " <th>review_title_cleaned</th>\n",
372
- " </tr>\n",
373
- " </thead>\n",
374
- " <tbody>\n",
375
- " <tr>\n",
376
- " <th>0</th>\n",
377
- " <td>2</td>\n",
378
- " <td>GREAT CAMRA</td>\n",
379
- " <td>I HAVE HAD THE DX6340 FOR ABOUT A YEAR.I LOVE ...</td>\n",
380
- " <td>586</td>\n",
381
- " <td>108</td>\n",
382
- " <td>dx6340 year love picture good 35m easy use unl...</td>\n",
383
- " <td>great camra</td>\n",
384
- " </tr>\n",
385
- " <tr>\n",
386
- " <th>1</th>\n",
387
- " <td>1</td>\n",
388
- " <td>not so great</td>\n",
389
- " <td>I'm using this book in an introductory organic...</td>\n",
390
- " <td>570</td>\n",
391
- " <td>88</td>\n",
392
- " <td>using book introductory organic spectroscopy c...</td>\n",
393
- " <td>not great</td>\n",
394
- " </tr>\n",
395
- " <tr>\n",
396
- " <th>2</th>\n",
397
- " <td>1</td>\n",
398
- " <td>Inaccurate and disappointing</td>\n",
399
- " <td>I only read the first few chapters and was bom...</td>\n",
400
- " <td>214</td>\n",
401
- " <td>40</td>\n",
402
- " <td>read first chapter bombarded reference 199 end...</td>\n",
403
- " <td>inaccurate disappointing</td>\n",
404
- " </tr>\n",
405
- " <tr>\n",
406
- " <th>3</th>\n",
407
- " <td>1</td>\n",
408
- " <td>Equus 3340</td>\n",
409
- " <td>Feels cheaply made, the battery contacts were ...</td>\n",
410
- " <td>193</td>\n",
411
- " <td>34</td>\n",
412
- " <td>feel cheaply made battery contact rusted soon ...</td>\n",
413
- " <td>equus 3340</td>\n",
414
- " </tr>\n",
415
- " <tr>\n",
416
- " <th>4</th>\n",
417
- " <td>2</td>\n",
418
- " <td>awesome sheets!</td>\n",
419
- " <td>I love these sheets! They are sleek &amp; smooth w...</td>\n",
420
- " <td>198</td>\n",
421
- " <td>38</td>\n",
422
- " <td>love sheet sleek smooth really cool feel perfe...</td>\n",
423
- " <td>awesome sheet</td>\n",
424
- " </tr>\n",
425
- " </tbody>\n",
426
- "</table>\n",
427
- "</div>"
428
- ],
429
- "text/plain": [
430
- " review_target review_title \\\n",
431
- "0 2 GREAT CAMRA \n",
432
- "1 1 not so great \n",
433
- "2 1 Inaccurate and disappointing \n",
434
- "3 1 Equus 3340 \n",
435
- "4 2 awesome sheets! \n",
436
- "\n",
437
- " review_content \\\n",
438
- "0 I HAVE HAD THE DX6340 FOR ABOUT A YEAR.I LOVE ... \n",
439
- "1 I'm using this book in an introductory organic... \n",
440
- "2 I only read the first few chapters and was bom... \n",
441
- "3 Feels cheaply made, the battery contacts were ... \n",
442
- "4 I love these sheets! They are sleek & smooth w... \n",
443
- "\n",
444
- " review_content_char_count review_content_word_count \\\n",
445
- "0 586 108 \n",
446
- "1 570 88 \n",
447
- "2 214 40 \n",
448
- "3 193 34 \n",
449
- "4 198 38 \n",
450
- "\n",
451
- " review_content_cleaned review_title_cleaned \n",
452
- "0 dx6340 year love picture good 35m easy use unl... great camra \n",
453
- "1 using book introductory organic spectroscopy c... not great \n",
454
- "2 read first chapter bombarded reference 199 end... inaccurate disappointing \n",
455
- "3 feel cheaply made battery contact rusted soon ... equus 3340 \n",
456
- "4 love sheet sleek smooth really cool feel perfe... awesome sheet "
457
- ]
458
- },
459
- "execution_count": 6,
460
- "metadata": {},
461
- "output_type": "execute_result"
462
- }
463
- ],
464
  "source": [
465
- "processed_train['review_title_cleaned'] = clean_text(processed_train['review_title'])\n",
466
- "processed_train.head()"
 
467
  ]
468
  },
469
  {
@@ -477,7 +366,7 @@
477
  },
478
  {
479
  "cell_type": "code",
480
- "execution_count": 7,
481
  "id": "9f585815",
482
  "metadata": {},
483
  "outputs": [
@@ -558,7 +447,7 @@
558
  "4 This book is very poorly written and lacks of ... "
559
  ]
560
  },
561
- "execution_count": 7,
562
  "metadata": {},
563
  "output_type": "execute_result"
564
  }
@@ -570,7 +459,7 @@
570
  },
571
  {
572
  "cell_type": "code",
573
- "execution_count": 8,
574
  "id": "07d9f22d",
575
  "metadata": {},
576
  "outputs": [
@@ -607,35 +496,35 @@
607
  " <td>2</td>\n",
608
  " <td>Everything you need</td>\n",
609
  " <td>This is a wonderful book. It may have been mea...</td>\n",
610
- " <td>wonderful book may meant clergy even though pr...</td>\n",
611
  " </tr>\n",
612
  " <tr>\n",
613
  " <th>1</th>\n",
614
  " <td>1</td>\n",
615
  " <td>Important note about carrier</td>\n",
616
  " <td>The carrier is very cute, and lightweight...ho...</td>\n",
617
- " <td>carrier very cute lightweight however frisky c...</td>\n",
618
  " </tr>\n",
619
  " <tr>\n",
620
  " <th>2</th>\n",
621
  " <td>1</td>\n",
622
  " <td>Not a musical instrument -cannot be played</td>\n",
623
  " <td>I bought (elsewhere) one of these harps for my...</td>\n",
624
- " <td>bought elsewhere one harp daughter heart broke...</td>\n",
625
  " </tr>\n",
626
  " <tr>\n",
627
  " <th>3</th>\n",
628
  " <td>2</td>\n",
629
  " <td>Do I Iike this monitor? Well... I have 2!</td>\n",
630
  " <td>I have 2 of these babies hooked up to a dual-o...</td>\n",
631
- " <td>baby hooked dual output digital 256mb graphic ...</td>\n",
632
  " </tr>\n",
633
  " <tr>\n",
634
  " <th>4</th>\n",
635
  " <td>1</td>\n",
636
  " <td>Very disappointing</td>\n",
637
  " <td>This book is very poorly written and lacks of ...</td>\n",
638
- " <td>book very poorly written lack useful informati...</td>\n",
639
  " </tr>\n",
640
  " </tbody>\n",
641
  "</table>\n",
@@ -657,140 +546,31 @@
657
  "4 This book is very poorly written and lacks of ... \n",
658
  "\n",
659
  " review_content_cleaned \n",
660
- "0 wonderful book may meant clergy even though pr... \n",
661
- "1 carrier very cute lightweight however frisky c... \n",
662
- "2 bought elsewhere one harp daughter heart broke... \n",
663
- "3 baby hooked dual output digital 256mb graphic ... \n",
664
- "4 book very poorly written lack useful informati... "
665
  ]
666
  },
667
- "execution_count": 8,
668
  "metadata": {},
669
  "output_type": "execute_result"
670
  }
671
  ],
672
  "source": [
673
- "processed_valid['review_content_cleaned'] = clean_text(processed_valid['review_content'])\n",
674
  "processed_valid.head()\n"
675
  ]
676
  },
677
  {
678
- "cell_type": "code",
679
- "execution_count": 9,
680
- "id": "2a416581",
681
  "metadata": {},
682
- "outputs": [
683
- {
684
- "data": {
685
- "text/html": [
686
- "<div>\n",
687
- "<style scoped>\n",
688
- " .dataframe tbody tr th:only-of-type {\n",
689
- " vertical-align: middle;\n",
690
- " }\n",
691
- "\n",
692
- " .dataframe tbody tr th {\n",
693
- " vertical-align: top;\n",
694
- " }\n",
695
- "\n",
696
- " .dataframe thead th {\n",
697
- " text-align: right;\n",
698
- " }\n",
699
- "</style>\n",
700
- "<table border=\"1\" class=\"dataframe\">\n",
701
- " <thead>\n",
702
- " <tr style=\"text-align: right;\">\n",
703
- " <th></th>\n",
704
- " <th>review_target</th>\n",
705
- " <th>review_title</th>\n",
706
- " <th>review_content</th>\n",
707
- " <th>review_content_cleaned</th>\n",
708
- " <th>review_title_cleaned</th>\n",
709
- " </tr>\n",
710
- " </thead>\n",
711
- " <tbody>\n",
712
- " <tr>\n",
713
- " <th>0</th>\n",
714
- " <td>2</td>\n",
715
- " <td>Everything you need</td>\n",
716
- " <td>This is a wonderful book. It may have been mea...</td>\n",
717
- " <td>wonderful book may meant clergy even though pr...</td>\n",
718
- " <td>everything need</td>\n",
719
- " </tr>\n",
720
- " <tr>\n",
721
- " <th>1</th>\n",
722
- " <td>1</td>\n",
723
- " <td>Important note about carrier</td>\n",
724
- " <td>The carrier is very cute, and lightweight...ho...</td>\n",
725
- " <td>carrier very cute lightweight however frisky c...</td>\n",
726
- " <td>important note carrier</td>\n",
727
- " </tr>\n",
728
- " <tr>\n",
729
- " <th>2</th>\n",
730
- " <td>1</td>\n",
731
- " <td>Not a musical instrument -cannot be played</td>\n",
732
- " <td>I bought (elsewhere) one of these harps for my...</td>\n",
733
- " <td>bought elsewhere one harp daughter heart broke...</td>\n",
734
- " <td>not musical instrument cannot played</td>\n",
735
- " </tr>\n",
736
- " <tr>\n",
737
- " <th>3</th>\n",
738
- " <td>2</td>\n",
739
- " <td>Do I Iike this monitor? Well... I have 2!</td>\n",
740
- " <td>I have 2 of these babies hooked up to a dual-o...</td>\n",
741
- " <td>baby hooked dual output digital 256mb graphic ...</td>\n",
742
- " <td>iike monitor well</td>\n",
743
- " </tr>\n",
744
- " <tr>\n",
745
- " <th>4</th>\n",
746
- " <td>1</td>\n",
747
- " <td>Very disappointing</td>\n",
748
- " <td>This book is very poorly written and lacks of ...</td>\n",
749
- " <td>book very poorly written lack useful informati...</td>\n",
750
- " <td>very disappointing</td>\n",
751
- " </tr>\n",
752
- " </tbody>\n",
753
- "</table>\n",
754
- "</div>"
755
- ],
756
- "text/plain": [
757
- " review_target review_title \\\n",
758
- "0 2 Everything you need \n",
759
- "1 1 Important note about carrier \n",
760
- "2 1 Not a musical instrument -cannot be played \n",
761
- "3 2 Do I Iike this monitor? Well... I have 2! \n",
762
- "4 1 Very disappointing \n",
763
- "\n",
764
- " review_content \\\n",
765
- "0 This is a wonderful book. It may have been mea... \n",
766
- "1 The carrier is very cute, and lightweight...ho... \n",
767
- "2 I bought (elsewhere) one of these harps for my... \n",
768
- "3 I have 2 of these babies hooked up to a dual-o... \n",
769
- "4 This book is very poorly written and lacks of ... \n",
770
- "\n",
771
- " review_content_cleaned \\\n",
772
- "0 wonderful book may meant clergy even though pr... \n",
773
- "1 carrier very cute lightweight however frisky c... \n",
774
- "2 bought elsewhere one harp daughter heart broke... \n",
775
- "3 baby hooked dual output digital 256mb graphic ... \n",
776
- "4 book very poorly written lack useful informati... \n",
777
- "\n",
778
- " review_title_cleaned \n",
779
- "0 everything need \n",
780
- "1 important note carrier \n",
781
- "2 not musical instrument cannot played \n",
782
- "3 iike monitor well \n",
783
- "4 very disappointing "
784
- ]
785
- },
786
- "execution_count": 9,
787
- "metadata": {},
788
- "output_type": "execute_result"
789
- }
790
- ],
791
  "source": [
792
- "processed_valid['review_title_cleaned'] = clean_text(processed_valid['review_title'])\n",
793
- "processed_valid.head()"
 
794
  ]
795
  },
796
  {
@@ -803,7 +583,7 @@
803
  },
804
  {
805
  "cell_type": "code",
806
- "execution_count": 10,
807
  "id": "5eb6491f",
808
  "metadata": {},
809
  "outputs": [
@@ -884,7 +664,7 @@
884
  "4 Although this book is touted on several Anusar... "
885
  ]
886
  },
887
- "execution_count": 10,
888
  "metadata": {},
889
  "output_type": "execute_result"
890
  }
@@ -896,7 +676,7 @@
896
  },
897
  {
898
  "cell_type": "code",
899
- "execution_count": 11,
900
  "metadata": {},
901
  "outputs": [
902
  {
@@ -989,7 +769,7 @@
989
  "4 although book touted several anusara web site ... "
990
  ]
991
  },
992
- "execution_count": 11,
993
  "metadata": {},
994
  "output_type": "execute_result"
995
  }
@@ -999,9 +779,19 @@
999
  "processed_test.head()"
1000
  ]
1001
  },
 
 
 
 
 
 
 
 
 
 
1002
  {
1003
  "cell_type": "code",
1004
- "execution_count": 12,
1005
  "id": "b5e64aec",
1006
  "metadata": {},
1007
  "outputs": [
@@ -1108,7 +898,7 @@
1108
  "4 not anusara "
1109
  ]
1110
  },
1111
- "execution_count": 12,
1112
  "metadata": {},
1113
  "output_type": "execute_result"
1114
  }
@@ -1118,6 +908,16 @@
1118
  "processed_test.head()"
1119
  ]
1120
  },
 
 
 
 
 
 
 
 
 
 
1121
  {
1122
  "cell_type": "markdown",
1123
  "id": "d037f992",
@@ -1128,7 +928,7 @@
1128
  },
1129
  {
1130
  "cell_type": "code",
1131
- "execution_count": 14,
1132
  "id": "2c4e029b",
1133
  "metadata": {},
1134
  "outputs": [
@@ -1136,16 +936,16 @@
1136
  "name": "stdout",
1137
  "output_type": "stream",
1138
  "text": [
1139
- "Saved dataframe processed_train.csv to data/processed/processed_train.csv\n"
1140
  ]
1141
  },
1142
  {
1143
  "data": {
1144
  "text/plain": [
1145
- "{'csv': PosixPath('data/processed/processed_train.csv')}"
1146
  ]
1147
  },
1148
- "execution_count": 14,
1149
  "metadata": {},
1150
  "output_type": "execute_result"
1151
  }
@@ -1156,7 +956,7 @@
1156
  },
1157
  {
1158
  "cell_type": "code",
1159
- "execution_count": 15,
1160
  "id": "6403bd9f",
1161
  "metadata": {},
1162
  "outputs": [
@@ -1164,16 +964,16 @@
1164
  "name": "stdout",
1165
  "output_type": "stream",
1166
  "text": [
1167
- "Saved dataframe processed_valid.csv to data/processed/processed_valid.csv\n"
1168
  ]
1169
  },
1170
  {
1171
  "data": {
1172
  "text/plain": [
1173
- "{'csv': PosixPath('data/processed/processed_valid.csv')}"
1174
  ]
1175
  },
1176
- "execution_count": 15,
1177
  "metadata": {},
1178
  "output_type": "execute_result"
1179
  }
@@ -1184,7 +984,7 @@
1184
  },
1185
  {
1186
  "cell_type": "code",
1187
- "execution_count": 16,
1188
  "id": "659e619f",
1189
  "metadata": {},
1190
  "outputs": [
@@ -1192,16 +992,16 @@
1192
  "name": "stdout",
1193
  "output_type": "stream",
1194
  "text": [
1195
- "Saved dataframe processed_test.csv to data/processed/processed_test.csv\n"
1196
  ]
1197
  },
1198
  {
1199
  "data": {
1200
  "text/plain": [
1201
- "{'csv': PosixPath('data/processed/processed_test.csv')}"
1202
  ]
1203
  },
1204
- "execution_count": 16,
1205
  "metadata": {},
1206
  "output_type": "execute_result"
1207
  }
@@ -1213,7 +1013,7 @@
1213
  ],
1214
  "metadata": {
1215
  "kernelspec": {
1216
- "display_name": "mlqueens",
1217
  "language": "python",
1218
  "name": "python3"
1219
  },
@@ -1227,7 +1027,7 @@
1227
  "name": "python",
1228
  "nbconvert_exporter": "python",
1229
  "pygments_lexer": "ipython3",
1230
- "version": "3.12.12"
1231
  }
1232
  },
1233
  "nbformat": 4,
 
38
  "name": "stdout",
39
  "output_type": "stream",
40
  "text": [
41
+ "e:\\AI_ML\\proj\\sentiment-analysis-of-amazon-reviews-using-machine-learning-ml-queens\\notebooks\n",
42
+ "E:\\AI_ML\\proj\\sentiment-analysis-of-amazon-reviews-using-machine-learning-ml-queens\n"
43
  ]
44
  }
45
  ],
 
201
  "balanced_sample_train.info()"
202
  ]
203
  },
204
+ {
205
+ "cell_type": "markdown",
206
+ "id": "524acdc6",
207
+ "metadata": {},
208
+ "source": [
209
+ "## Dataset Overview\n",
210
+ "\n",
211
+ "The balanced training dataset contains a mix of positive and negative reviews, ensuring the model won't be biased towards one sentiment class. The columns include review content, titles, and targets, providing rich text data for sentiment analysis. This balanced approach is crucial for training reliable classifiers."
212
+ ]
213
+ },
214
  {
215
  "cell_type": "markdown",
216
  "id": "d5b9401e",
 
262
  " <td>I HAVE HAD THE DX6340 FOR ABOUT A YEAR.I LOVE ...</td>\n",
263
  " <td>586</td>\n",
264
  " <td>108</td>\n",
265
+ " <td>great camra dx6340 year love picture good 35m ...</td>\n",
266
  " </tr>\n",
267
  " <tr>\n",
268
  " <th>1</th>\n",
 
271
  " <td>I'm using this book in an introductory organic...</td>\n",
272
  " <td>570</td>\n",
273
  " <td>88</td>\n",
274
+ " <td>not great using book introductory organic spec...</td>\n",
275
  " </tr>\n",
276
  " <tr>\n",
277
  " <th>2</th>\n",
 
280
  " <td>I only read the first few chapters and was bom...</td>\n",
281
  " <td>214</td>\n",
282
  " <td>40</td>\n",
283
+ " <td>inaccurate disappointing read first chapter bo...</td>\n",
284
  " </tr>\n",
285
  " <tr>\n",
286
  " <th>3</th>\n",
 
289
  " <td>Feels cheaply made, the battery contacts were ...</td>\n",
290
  " <td>193</td>\n",
291
  " <td>34</td>\n",
292
+ " <td>equus 3340 feel cheaply made battery contact r...</td>\n",
293
  " </tr>\n",
294
  " <tr>\n",
295
  " <th>4</th>\n",
 
298
  " <td>I love these sheets! They are sleek &amp; smooth w...</td>\n",
299
  " <td>198</td>\n",
300
  " <td>38</td>\n",
301
+ " <td>awesome sheet love sheet sleek smooth really c...</td>\n",
302
  " </tr>\n",
303
  " </tbody>\n",
304
  "</table>\n",
 
327
  "4 198 38 \n",
328
  "\n",
329
  " review_content_cleaned \n",
330
+ "0 great camra dx6340 year love picture good 35m ... \n",
331
+ "1 not great using book introductory organic spec... \n",
332
+ "2 inaccurate disappointing read first chapter bo... \n",
333
+ "3 equus 3340 feel cheaply made battery contact r... \n",
334
+ "4 awesome sheet love sheet sleek smooth really c... "
335
  ]
336
  },
337
  "execution_count": 5,
 
341
  ],
342
  "source": [
343
  "processed_train = balanced_sample_train.copy()\n",
344
+ "processed_train['review_content_cleaned'] = clean_text(processed_train['review_title'].fillna('') + ' ' + processed_train['review_content'].fillna(''))\n",
345
  "processed_train.head()"
346
  ]
347
  },
348
  {
349
+ "cell_type": "markdown",
350
+ "id": "0be1b03e",
 
351
  "metadata": {},
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
352
  "source": [
353
+ "## Text Cleaning on Training Data\n",
354
+ "\n",
355
+ "The cleaning process combines review titles and content, then removes HTML tags, converts to lowercase, and strips punctuation. This standardization ensures consistency across reviews and prevents the model from learning irrelevant patterns like capitalization or formatting differences. The cleaned text is now ready for vectorization."
356
  ]
357
  },
358
  {
 
366
  },
367
  {
368
  "cell_type": "code",
369
+ "execution_count": 6,
370
  "id": "9f585815",
371
  "metadata": {},
372
  "outputs": [
 
447
  "4 This book is very poorly written and lacks of ... "
448
  ]
449
  },
450
+ "execution_count": 6,
451
  "metadata": {},
452
  "output_type": "execute_result"
453
  }
 
459
  },
460
  {
461
  "cell_type": "code",
462
+ "execution_count": 7,
463
  "id": "07d9f22d",
464
  "metadata": {},
465
  "outputs": [
 
496
  " <td>2</td>\n",
497
  " <td>Everything you need</td>\n",
498
  " <td>This is a wonderful book. It may have been mea...</td>\n",
499
+ " <td>everything need wonderful book may meant clerg...</td>\n",
500
  " </tr>\n",
501
  " <tr>\n",
502
  " <th>1</th>\n",
503
  " <td>1</td>\n",
504
  " <td>Important note about carrier</td>\n",
505
  " <td>The carrier is very cute, and lightweight...ho...</td>\n",
506
+ " <td>important note carrier carrier very cute light...</td>\n",
507
  " </tr>\n",
508
  " <tr>\n",
509
  " <th>2</th>\n",
510
  " <td>1</td>\n",
511
  " <td>Not a musical instrument -cannot be played</td>\n",
512
  " <td>I bought (elsewhere) one of these harps for my...</td>\n",
513
+ " <td>not musical instrument cannot played bought el...</td>\n",
514
  " </tr>\n",
515
  " <tr>\n",
516
  " <th>3</th>\n",
517
  " <td>2</td>\n",
518
  " <td>Do I Iike this monitor? Well... I have 2!</td>\n",
519
  " <td>I have 2 of these babies hooked up to a dual-o...</td>\n",
520
+ " <td>iike monitor well baby hooked dual output digi...</td>\n",
521
  " </tr>\n",
522
  " <tr>\n",
523
  " <th>4</th>\n",
524
  " <td>1</td>\n",
525
  " <td>Very disappointing</td>\n",
526
  " <td>This book is very poorly written and lacks of ...</td>\n",
527
+ " <td>very disappointing book very poorly written la...</td>\n",
528
  " </tr>\n",
529
  " </tbody>\n",
530
  "</table>\n",
 
546
  "4 This book is very poorly written and lacks of ... \n",
547
  "\n",
548
  " review_content_cleaned \n",
549
+ "0 everything need wonderful book may meant clerg... \n",
550
+ "1 important note carrier carrier very cute light... \n",
551
+ "2 not musical instrument cannot played bought el... \n",
552
+ "3 iike monitor well baby hooked dual output digi... \n",
553
+ "4 very disappointing book very poorly written la... "
554
  ]
555
  },
556
+ "execution_count": 7,
557
  "metadata": {},
558
  "output_type": "execute_result"
559
  }
560
  ],
561
  "source": [
562
+ "processed_valid['review_content_cleaned'] = clean_text(processed_valid['review_title'].fillna('') + ' ' + processed_valid['review_content'].fillna(''))\n",
563
  "processed_valid.head()\n"
564
  ]
565
  },
566
  {
567
+ "cell_type": "markdown",
568
+ "id": "cc1443d5",
 
569
  "metadata": {},
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
570
  "source": [
571
+ "## Text Cleaning on Validation Data\n",
572
+ "\n",
573
+ "Applying the same cleaning pipeline to validation data ensures consistency between training and validation sets. This prevents data leakage and maintains the integrity of model evaluation. The cleaned validation data will be used to tune hyperparameters and assess model performance."
574
  ]
575
  },
576
  {
 
583
  },
584
  {
585
  "cell_type": "code",
586
+ "execution_count": 8,
587
  "id": "5eb6491f",
588
  "metadata": {},
589
  "outputs": [
 
664
  "4 Although this book is touted on several Anusar... "
665
  ]
666
  },
667
+ "execution_count": 8,
668
  "metadata": {},
669
  "output_type": "execute_result"
670
  }
 
676
  },
677
  {
678
  "cell_type": "code",
679
+ "execution_count": 9,
680
  "metadata": {},
681
  "outputs": [
682
  {
 
769
  "4 although book touted several anusara web site ... "
770
  ]
771
  },
772
+ "execution_count": 9,
773
  "metadata": {},
774
  "output_type": "execute_result"
775
  }
 
779
  "processed_test.head()"
780
  ]
781
  },
782
+ {
783
+ "cell_type": "markdown",
784
+ "id": "f3636ef3",
785
+ "metadata": {},
786
+ "source": [
787
+ "## Text Cleaning on Test Content\n",
788
+ "\n",
789
+ "Cleaning the test review content follows the same preprocessing steps as training data. This ensures the model receives input in the expected format during final evaluation. Separate cleaning of content and title allows for different feature engineering approaches if needed."
790
+ ]
791
+ },
792
  {
793
  "cell_type": "code",
794
+ "execution_count": 10,
795
  "id": "b5e64aec",
796
  "metadata": {},
797
  "outputs": [
 
898
  "4 not anusara "
899
  ]
900
  },
901
+ "execution_count": 10,
902
  "metadata": {},
903
  "output_type": "execute_result"
904
  }
 
908
  "processed_test.head()"
909
  ]
910
  },
911
+ {
912
+ "cell_type": "markdown",
913
+ "id": "b0bc2de8",
914
+ "metadata": {},
915
+ "source": [
916
+ "## Text Cleaning on Test Titles\n",
917
+ "\n",
918
+ "Review titles often contain condensed sentiment information. Cleaning them separately allows for targeted feature extraction from titles, which can be more indicative of overall sentiment than full content. This completes the preprocessing pipeline for all datasets."
919
+ ]
920
+ },
921
  {
922
  "cell_type": "markdown",
923
  "id": "d037f992",
 
928
  },
929
  {
930
  "cell_type": "code",
931
+ "execution_count": 11,
932
  "id": "2c4e029b",
933
  "metadata": {},
934
  "outputs": [
 
936
  "name": "stdout",
937
  "output_type": "stream",
938
  "text": [
939
+ "Saved dataframe processed_train.csv to data\\processed\\processed_train.csv\n"
940
  ]
941
  },
942
  {
943
  "data": {
944
  "text/plain": [
945
+ "{'csv': WindowsPath('data/processed/processed_train.csv')}"
946
  ]
947
  },
948
+ "execution_count": 11,
949
  "metadata": {},
950
  "output_type": "execute_result"
951
  }
 
956
  },
957
  {
958
  "cell_type": "code",
959
+ "execution_count": 12,
960
  "id": "6403bd9f",
961
  "metadata": {},
962
  "outputs": [
 
964
  "name": "stdout",
965
  "output_type": "stream",
966
  "text": [
967
+ "Saved dataframe processed_valid.csv to data\\processed\\processed_valid.csv\n"
968
  ]
969
  },
970
  {
971
  "data": {
972
  "text/plain": [
973
+ "{'csv': WindowsPath('data/processed/processed_valid.csv')}"
974
  ]
975
  },
976
+ "execution_count": 12,
977
  "metadata": {},
978
  "output_type": "execute_result"
979
  }
 
984
  },
985
  {
986
  "cell_type": "code",
987
+ "execution_count": 13,
988
  "id": "659e619f",
989
  "metadata": {},
990
  "outputs": [
 
992
  "name": "stdout",
993
  "output_type": "stream",
994
  "text": [
995
+ "Saved dataframe processed_test.csv to data\\processed\\processed_test.csv\n"
996
  ]
997
  },
998
  {
999
  "data": {
1000
  "text/plain": [
1001
+ "{'csv': WindowsPath('data/processed/processed_test.csv')}"
1002
  ]
1003
  },
1004
+ "execution_count": 13,
1005
  "metadata": {},
1006
  "output_type": "execute_result"
1007
  }
 
1013
  ],
1014
  "metadata": {
1015
  "kernelspec": {
1016
+ "display_name": ".venv",
1017
  "language": "python",
1018
  "name": "python3"
1019
  },
 
1027
  "name": "python",
1028
  "nbconvert_exporter": "python",
1029
  "pygments_lexer": "ipython3",
1030
+ "version": "3.13.11"
1031
  }
1032
  },
1033
  "nbformat": 4,
notebooks/04_feature_engineering.ipynb CHANGED
The diff for this file is too large to render. See raw diff
 
notebooks/07_support_vector_machine.ipynb ADDED
The diff for this file is too large to render. See raw diff
 
notebooks/07_support_vector_machines.ipynb DELETED
@@ -1,27 +0,0 @@
1
- {
2
- "cells": [
3
- {
4
- "cell_type": "markdown",
5
- "id": "eec16dfe",
6
- "metadata": {},
7
- "source": [
8
- "# Support Vector Machines (SVM)"
9
- ]
10
- },
11
- {
12
- "cell_type": "markdown",
13
- "id": "a478dc96",
14
- "metadata": {},
15
- "source": [
16
- "# "
17
- ]
18
- }
19
- ],
20
- "metadata": {
21
- "language_info": {
22
- "name": "python"
23
- }
24
- },
25
- "nbformat": 4,
26
- "nbformat_minor": 5
27
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
notebooks/09_decision_trees.ipynb CHANGED
The diff for this file is too large to render. See raw diff
 
notebooks/10_random_forest.ipynb CHANGED
The diff for this file is too large to render. See raw diff
 
notebooks/11_stochastic_gradient_descent.ipynb CHANGED
The diff for this file is too large to render. See raw diff
 
notebooks/12_xgboost.ipynb ADDED
The diff for this file is too large to render. See raw diff
 
notebooks/13_lightgbm.ipynb ADDED
@@ -0,0 +1,664 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ {
2
+ "cells": [
3
+ {
4
+ "cell_type": "markdown",
5
+ "id": "1",
6
+ "metadata": {
7
+ "id": "1"
8
+ },
9
+ "source": [
10
+ "# LightGBM"
11
+ ]
12
+ },
13
+ {
14
+ "cell_type": "code",
15
+ "execution_count": 1,
16
+ "id": "2",
17
+ "metadata": {
18
+ "colab": {
19
+ "base_uri": "https://localhost:8080/"
20
+ },
21
+ "id": "2",
22
+ "outputId": "3be246e4-4957-40b6-b832-01b7ab3f84de"
23
+ },
24
+ "outputs": [
25
+ {
26
+ "name": "stdout",
27
+ "output_type": "stream",
28
+ "text": [
29
+ "LightGBM version: 4.6.0\n"
30
+ ]
31
+ }
32
+ ],
33
+ "source": [
34
+ "import pandas as pd\n",
35
+ "import numpy as np\n",
36
+ "import matplotlib.pyplot as plt\n",
37
+ "import seaborn as sns\n",
38
+ "import scipy.sparse as sp\n",
39
+ "from sklearn.feature_extraction.text import TfidfVectorizer\n",
40
+ "from sklearn.model_selection import train_test_split\n",
41
+ "from sklearn.metrics import accuracy_score, precision_score, recall_score, f1_score, confusion_matrix, classification_report\n",
42
+ "import lightgbm as lgb\n",
43
+ "from lightgbm import log_evaluation\n",
44
+ "import time\n",
45
+ "import re\n",
46
+ "import joblib\n",
47
+ "import nltk\n",
48
+ "from nltk.corpus import stopwords\n",
49
+ "from nltk.tokenize import word_tokenize\n",
50
+ "import warnings\n",
51
+ "warnings.filterwarnings('ignore')\n",
52
+ "# Download NLTK data\n",
53
+ "nltk.download('punkt', quiet=True)\n",
54
+ "nltk.download('stopwords', quiet=True)\n",
55
+ "print(f\"LightGBM version: {lgb.__version__}\")"
56
+ ]
57
+ },
58
+ {
59
+ "cell_type": "markdown",
60
+ "id": "5e639bb2",
61
+ "metadata": {},
62
+ "source": [
63
+ "back to root to call functions from helpers.py file"
64
+ ]
65
+ },
66
+ {
67
+ "cell_type": "code",
68
+ "execution_count": 2,
69
+ "id": "b75cb7a0",
70
+ "metadata": {},
71
+ "outputs": [
72
+ {
73
+ "name": "stdout",
74
+ "output_type": "stream",
75
+ "text": [
76
+ "e:\\AI_ML\\proj\\sentiment-analysis-of-amazon-reviews-using-machine-learning-ml-queens\\notebooks\n",
77
+ "E:\\AI_ML\\proj\\sentiment-analysis-of-amazon-reviews-using-machine-learning-ml-queens\n"
78
+ ]
79
+ }
80
+ ],
81
+ "source": [
82
+ "import os\n",
83
+ "from pathlib import Path\n",
84
+ "print(Path.cwd())\n",
85
+ "os.chdir(Path('..').resolve())\n",
86
+ "from src.utils.helpers import save\n",
87
+ "print(Path.cwd())"
88
+ ]
89
+ },
90
+ {
91
+ "cell_type": "markdown",
92
+ "id": "441eb410",
93
+ "metadata": {},
94
+ "source": [
95
+ "## Data Acquisition"
96
+ ]
97
+ },
98
+ {
99
+ "cell_type": "markdown",
100
+ "id": "72a150bf",
101
+ "metadata": {},
102
+ "source": [
103
+ "load dataset"
104
+ ]
105
+ },
106
+ {
107
+ "cell_type": "code",
108
+ "execution_count": 3,
109
+ "id": "f39fa229",
110
+ "metadata": {},
111
+ "outputs": [
112
+ {
113
+ "name": "stdout",
114
+ "output_type": "stream",
115
+ "text": [
116
+ "X_train shape: (79972, 50000)\n",
117
+ "y_train shape: (79972,)\n"
118
+ ]
119
+ }
120
+ ],
121
+ "source": [
122
+ "X_train_tfidf = sp.load_npz('data/vectorizers/X_train_tfidf.npz')\n",
123
+ "print(f\"X_train shape: {X_train_tfidf.shape}\")\n",
124
+ "y_train = pd.read_csv('data/processed/y_train.csv').squeeze()\n",
125
+ "print(f\"y_train shape: {y_train.shape}\")"
126
+ ]
127
+ },
128
+ {
129
+ "cell_type": "code",
130
+ "execution_count": 4,
131
+ "id": "8d1d2ac4",
132
+ "metadata": {},
133
+ "outputs": [
134
+ {
135
+ "name": "stdout",
136
+ "output_type": "stream",
137
+ "text": [
138
+ "X_valid shape: (20000, 50000)\n",
139
+ "y_valid shape: (20000,)\n"
140
+ ]
141
+ }
142
+ ],
143
+ "source": [
144
+ "X_valid = sp.load_npz('data/vectorizers/X_valid_tfidf.npz')\n",
145
+ "print(f\"X_valid shape: {X_valid.shape}\")\n",
146
+ "y_valid = pd.read_csv('data/processed/y_valid.csv').squeeze()\n",
147
+ "print(f\"y_valid shape: {y_valid.shape}\")"
148
+ ]
149
+ },
150
+ {
151
+ "cell_type": "code",
152
+ "execution_count": 5,
153
+ "id": "1e32f8e0",
154
+ "metadata": {},
155
+ "outputs": [
156
+ {
157
+ "name": "stdout",
158
+ "output_type": "stream",
159
+ "text": [
160
+ "X_test shape: (20000, 50000)\n",
161
+ "y_test shape: (20000,)\n"
162
+ ]
163
+ }
164
+ ],
165
+ "source": [
166
+ "X_test_tfidf = sp.load_npz('data/vectorizers/X_test_tfidf.npz')\n",
167
+ "print(f\"X_test shape: {X_test_tfidf.shape}\")\n",
168
+ "y_test = pd.read_csv('data/processed/y_test.csv').squeeze()\n",
169
+ "print(f\"y_test shape: {y_test.shape}\")"
170
+ ]
171
+ },
172
+ {
173
+ "cell_type": "code",
174
+ "execution_count": 6,
175
+ "id": "87fcafdd",
176
+ "metadata": {},
177
+ "outputs": [],
178
+ "source": [
179
+ "# Convert sparse matrices to dense for XGBoost\n",
180
+ "X_train_dense = X_train_tfidf.toarray()\n",
181
+ "X_test_dense = X_test_tfidf.toarray()\n",
182
+ "# Convert [1, 2] labels to [0, 1]\n",
183
+ "y_train = y_train.astype(int) - 1\n",
184
+ "y_test = y_test.astype(int) - 1"
185
+ ]
186
+ },
187
+ {
188
+ "cell_type": "markdown",
189
+ "id": "11",
190
+ "metadata": {
191
+ "id": "11"
192
+ },
193
+ "source": [
194
+ "## 5: LightGBM Model Training"
195
+ ]
196
+ },
197
+ {
198
+ "cell_type": "code",
199
+ "execution_count": 7,
200
+ "id": "12",
201
+ "metadata": {
202
+ "colab": {
203
+ "base_uri": "https://localhost:8080/"
204
+ },
205
+ "id": "12",
206
+ "outputId": "a44ef59b-85fd-4e86-e414-1d73d408ff80"
207
+ },
208
+ "outputs": [
209
+ {
210
+ "name": "stdout",
211
+ "output_type": "stream",
212
+ "text": [
213
+ "Training LightGBM Classifier...\n",
214
+ "Training completed in 72.0527 seconds\n"
215
+ ]
216
+ }
217
+ ],
218
+ "source": [
219
+ "# Train LightGBM Classifier\n",
220
+ "print(\"Training LightGBM Classifier...\")\n",
221
+ "start_time = time.time()\n",
222
+ "lgb_classifier = lgb.LGBMClassifier(\n",
223
+ " n_estimators=200,\n",
224
+ " max_depth=6,\n",
225
+ " learning_rate=0.1,\n",
226
+ " subsample=0.8,\n",
227
+ " colsample_bytree=0.8,\n",
228
+ " num_leaves=31,\n",
229
+ " min_child_samples=20,\n",
230
+ " reg_alpha=0,\n",
231
+ " reg_lambda=1,\n",
232
+ " random_state=42,\n",
233
+ " n_jobs=-1,\n",
234
+ " verbose=-1,\n",
235
+ " metric='binary_logloss'\n",
236
+ ")\n",
237
+ "lgb_classifier.fit(\n",
238
+ " X_train_dense, y_train,\n",
239
+ " eval_set=[(X_test_dense, y_test)], # Optional: for logging\n",
240
+ " callbacks=[log_evaluation(period=0)] # Equivalent to verbose=False\n",
241
+ ")\n",
242
+ "training_time = time.time() - start_time\n",
243
+ "print(f\"Training completed in {training_time:.4f} seconds\")"
244
+ ]
245
+ },
246
+ {
247
+ "cell_type": "markdown",
248
+ "id": "13",
249
+ "metadata": {
250
+ "id": "13"
251
+ },
252
+ "source": [
253
+ "## 6: Model Evaluation"
254
+ ]
255
+ },
256
+ {
257
+ "cell_type": "code",
258
+ "execution_count": 8,
259
+ "id": "14",
260
+ "metadata": {
261
+ "colab": {
262
+ "base_uri": "https://localhost:8080/"
263
+ },
264
+ "id": "14",
265
+ "outputId": "ee6ad901-6f82-4126-d9a8-7fa66ce54d3c"
266
+ },
267
+ "outputs": [
268
+ {
269
+ "name": "stdout",
270
+ "output_type": "stream",
271
+ "text": [
272
+ "LIGHTGBM CLASSIFIER - PERFORMANCE METRICS\n",
273
+ "Accuracy: 0.8267\n",
274
+ "Precision: 0.8148\n",
275
+ "Recall: 0.8471\n",
276
+ "F1-Score: 0.8306\n",
277
+ "Training Time: 72.0527 seconds\n"
278
+ ]
279
+ }
280
+ ],
281
+ "source": [
282
+ "# Make predictions\n",
283
+ "y_pred = lgb_classifier.predict(X_test_dense)\n",
284
+ "# Calculate metrics\n",
285
+ "accuracy = accuracy_score(y_test, y_pred)\n",
286
+ "precision = precision_score(y_test, y_pred)\n",
287
+ "recall = recall_score(y_test, y_pred)\n",
288
+ "f1 = f1_score(y_test, y_pred)\n",
289
+ "# Print results\n",
290
+ "print(\"LIGHTGBM CLASSIFIER - PERFORMANCE METRICS\")\n",
291
+ "print(f\"Accuracy: {accuracy:.4f}\")\n",
292
+ "print(f\"Precision: {precision:.4f}\")\n",
293
+ "print(f\"Recall: {recall:.4f}\")\n",
294
+ "print(f\"F1-Score: {f1:.4f}\")\n",
295
+ "print(f\"Training Time: {training_time:.4f} seconds\")"
296
+ ]
297
+ },
298
+ {
299
+ "cell_type": "markdown",
300
+ "id": "15",
301
+ "metadata": {
302
+ "id": "15"
303
+ },
304
+ "source": [
305
+ "## 7: Classification Report"
306
+ ]
307
+ },
308
+ {
309
+ "cell_type": "code",
310
+ "execution_count": 9,
311
+ "id": "16",
312
+ "metadata": {
313
+ "colab": {
314
+ "base_uri": "https://localhost:8080/"
315
+ },
316
+ "id": "16",
317
+ "outputId": "f5a4cb17-e06c-47b1-8b72-4d430672fd80"
318
+ },
319
+ "outputs": [
320
+ {
321
+ "name": "stdout",
322
+ "output_type": "stream",
323
+ "text": [
324
+ "Classification Report:\n",
325
+ " precision recall f1-score support\n",
326
+ "\n",
327
+ " Negative 0.84 0.81 0.82 9966\n",
328
+ " Positive 0.81 0.85 0.83 10034\n",
329
+ "\n",
330
+ " accuracy 0.83 20000\n",
331
+ " macro avg 0.83 0.83 0.83 20000\n",
332
+ "weighted avg 0.83 0.83 0.83 20000\n",
333
+ "\n"
334
+ ]
335
+ }
336
+ ],
337
+ "source": [
338
+ "print(\"Classification Report:\")\n",
339
+ "print(classification_report(y_test, y_pred, target_names=['Negative', 'Positive']))"
340
+ ]
341
+ },
342
+ {
343
+ "cell_type": "markdown",
344
+ "id": "17",
345
+ "metadata": {
346
+ "id": "17"
347
+ },
348
+ "source": [
349
+ "## 8: Confusion Matrix Visualization"
350
+ ]
351
+ },
352
+ {
353
+ "cell_type": "code",
354
+ "execution_count": 10,
355
+ "id": "18",
356
+ "metadata": {
357
+ "colab": {
358
+ "base_uri": "https://localhost:8080/",
359
+ "height": 746
360
+ },
361
+ "id": "18",
362
+ "outputId": "1a92f645-c179-46c4-ea65-3ecf02a14242"
363
+ },
364
+ "outputs": [
365
+ {
366
+ "data": {
367
+ "image/png": "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SkhIiFy4cMFvP6tdzxMA4H8EAgBsQRus2tjUJWnSpFKgQAEZOnSo3L592+ev/c0338ibb75py0Zxnjx5ZMyYMX55LQCAszChGADbqF27tkyePFlu3LghCxculI4dO5oJ3/r373/Hvjdv3jQBQ3xIly5dvBwHAICEhIwAANsICwuTLFmySO7cuaVDhw5SvXp1+e6777y6uLz11luSLVs2KVy4sFn/559/yvPPPy9p0qQxDfqnn35a/vjjD/cxIyIipEePHmZ7+vTppU+fPuJyubxeN2rXIA1E+vbtKzlz5jTnpNmJTz/91By3SpUqZp+0adOazICel4qMjJQRI0ZI3rx5JTw8XB5++GH5+uuvvV5Hg5tChQqZ7Xocz/O8F/qztW7d2v2aek3Gjh0b7b5DhgyRjBkzSqpUqaR9+/YmkLLE5twBAMGHjAAA29JG6dmzZ93Ply1bZhqyS5cuNc9v3boltWrVkvLly8vPP/8siRMnlmHDhpnMwrZt20zG4L333pMpU6bIZ599JkWLFjXP586dK1WrVo3xdVu0aCFr166VcePGmUbxoUOH5K+//jKBwZw5c6RRo0ayd+9ecy56jkob0l988YVMmjRJChYsKD/99JM0a9bMNL6feOIJE7A0bNjQZDnatWsnGzdulJ49e97X9dEGfI4cOWT27NkmyFmzZo05dtasWU1w5HndkiVLZro1afDx8ssvm/01qIrNuQMAgpQLAGygZcuWrqeffto8joyMdC1dutQVFhbm6tWrl3t75syZXTdu3HB/z+eff+4qXLiw2d+i28PDw11Lliwxz7NmzeoaOXKke/utW7dcOXLkcL+WeuKJJ1xdu3Y1j/fu3avpAvP60VmxYoXZfv78efe669evu5InT+5as2aN176tW7d2vfjii+Zx//79XcWKFfPa3rdv3zuOFVXu3Lldo0ePdsVWx44dXY0aNXI/1+uWLl0615UrV9zrJk6c6EqZMqUrIiIiVuce3c8MAEj4yAgAsI358+dLypQpzZ1+vdvdpEkTGTx4sHt78eLFveoCtm7dKgcOHJAHHnjA6zjXr1+X33//XS5evCgnTpyQsmXLurdp1uCRRx65o3uQZcuWLZIoUaI43QnXc7h69arUqFHDa712vylVqpR5vHv3bq/zUJrJuF8ffvihyXYcOXJErl27Zl6zZMmSXvtoViN58uRer3v58mWTpdCv/3buAIDgRCAAwDa03/zEiRNNY1/rALTR7ilFihRez7URW6ZMGZk+ffodx9JuLffC6uoTF3oeasGCBZI9e3avbVpj4CszZ86UXr16me5O2rjXgGjUqFGybt062587ACDwCAQA2IY29LUwN7ZKly4tX331lWTKlMn014+O9pfXhnHlypXNcx2OdNOmTeZ7o6NZB81GrFq1yhQrR2VlJLRQ11KsWDHTaNa78jFlErQ+wSp8tvz6669yP1avXi0VKlSQV1991b1OMyFRaeZEswVWkKOvq5kXrXnQAut/O3cAQHBi1CAACVbTpk0lQ4YMZqQgLRbWol4tiO3SpYscPXrU7NO1a1d5++23Zd68ebJnzx7TaL7bHAA6bn/Lli2lVatW5nusY86aNcts1xGNdLQg7cZ05swZc0dd78Trnfnu3bvL1KlTTWN88+bNMn78ePNc6Ug9+/fvl969e5tC4xkzZpgi5tg4duyY6bLkuZw/f94U9mrR8ZIlS2Tfvn0ycOBA2bBhwx3fr918dHShXbt2mZGL3njjDenUqZOEhobG6twBAMGJQABAgqX93nWEm1y5cpkRefSuuzZ4tUbAyhDoyDzNmzc3jXur+8wzzzxz1+Nq96Rnn33WBA1FihSRtm3bypUrV8w27T6jQ3H269dPMmfObBrUSick04a4jsCj56EjF2l3Gx2SU+k56ohDGlxon30doWf48OGx+jnfffdd01/fc9Fjv/LKK+bnfuGFF0z9gY6w5JkdsFSrVs0EDZoV0X2feuopr9qLfzt3AEBwCtGK4UCfBAAAAAD/IiMAAAAAOBCBAAAAAOBABAIAAACAAxEIAAAAAA5EIAAAAAA4EIEAAAAA4EAEAgAAAIADEQgAAAAADkQgAAAAADgQgQAAAADgQAQCAAAAgAMRCAAAAADiPP8H8LOeqVEUfVMAAAAASUVORK5CYII=",
368
+ "text/plain": [
369
+ "<Figure size 800x600 with 2 Axes>"
370
+ ]
371
+ },
372
+ "metadata": {},
373
+ "output_type": "display_data"
374
+ },
375
+ {
376
+ "name": "stdout",
377
+ "output_type": "stream",
378
+ "text": [
379
+ "Confusion Matrix:\n",
380
+ "[[8034 1932]\n",
381
+ " [1534 8500]]\n",
382
+ "\n",
383
+ "True Negatives: 8034\n",
384
+ "False Positives: 1932\n",
385
+ "False Negatives: 1534\n",
386
+ "True Positives: 8500\n"
387
+ ]
388
+ }
389
+ ],
390
+ "source": [
391
+ "# Compute confusion matrix\n",
392
+ "cm = confusion_matrix(y_test, y_pred)\n",
393
+ "# Plot confusion matrix\n",
394
+ "plt.figure(figsize=(8, 6))\n",
395
+ "sns.heatmap(cm, annot=True, fmt='d', cmap='BuGn',\n",
396
+ " xticklabels=['Negative', 'Positive'],\n",
397
+ " yticklabels=['Negative', 'Positive'],\n",
398
+ " cbar_kws={'label': 'Count'})\n",
399
+ "plt.title('Confusion Matrix - LightGBM Classifier')\n",
400
+ "plt.ylabel('True Label')\n",
401
+ "plt.xlabel('Predicted Label')\n",
402
+ "plt.tight_layout()\n",
403
+ "plt.savefig('lightgbm_confusion_matrix.png', dpi=300, bbox_inches='tight')\n",
404
+ "plt.show()\n",
405
+ "print(f\"Confusion Matrix:\\n{cm}\")\n",
406
+ "print(f\"\\nTrue Negatives: {cm[0,0]}\")\n",
407
+ "print(f\"False Positives: {cm[0,1]}\")\n",
408
+ "print(f\"False Negatives: {cm[1,0]}\")\n",
409
+ "print(f\"True Positives: {cm[1,1]}\")"
410
+ ]
411
+ },
412
+ {
413
+ "cell_type": "markdown",
414
+ "id": "19",
415
+ "metadata": {
416
+ "id": "19"
417
+ },
418
+ "source": [
419
+ "## 9: Feature Importance"
420
+ ]
421
+ },
422
+ {
423
+ "cell_type": "code",
424
+ "execution_count": 11,
425
+ "id": "20",
426
+ "metadata": {
427
+ "colab": {
428
+ "base_uri": "https://localhost:8080/",
429
+ "height": 1000
430
+ },
431
+ "id": "20",
432
+ "outputId": "2c9ef579-54b5-4b2d-bb56-1c0b55c615be"
433
+ },
434
+ "outputs": [
435
+ {
436
+ "data": {
437
+ "image/png": "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QEBqbQ4e8O8nhiQ6AAAAAAAAIA0q3W+++aYsXbrUebtjx45SoEABKV68uBw6dCglmwQAAAAAINNJUeh+7733JCgoyPy+YcMGM61fv15at24tI0aMSO19BAAAAAAg6zQv//33352he+3atabS/cgjj0ipUqWkbt26qb2PAAAAAABknUp3/vz5JTIy0vz+xRdfSPPmzc3vDodDYmNjU3cPAQAAAADISpXu9u3bS5cuXSQ4OFguXLhgmpWrAwcOSLly5VJ7H5FGhq3/UHLm9uV44y7/avscRwUAAABIq9A9Y8YM05Rcq92TJ0+WvHnzmvnnzp2TF154ISWbBAAAAAAg00lR6Pb29pbhw4ffNX/IkCGpsU8AAAAAAGTdPt3qo48+kkaNGkmxYsXk559/NvNmzpwpq1atSs39AwAAAAAga4Xud999V4YOHWr6cl++fNk5eFpAQIAJ3rjbvHnzzPGxjBs3Th588EEOFQAAAABkYikK3W+//bZ88MEH8sorr0j27Nmd82vVqiVHjhxJzf3D3wj2AAAAAIAMGLpPnz4t1atXv2u+j4+PXLt2LTX2CwAAAACArBm6S5cuLQcPHrxrvl6zu1KlSpJe3blzR8LDw83++/r6SrVq1eTTTz811xfXa423bNnS/K4uXrwo999/v4wZM8Z5/zVr1kjt2rUlV65cUrBgQXniiSecy2JiYszgcsWLF5c8efJI3bp1ZdOmTcnavzlz5pjjp9uvWLGivPPOO85lZ86cES8vL/nss8+kWbNmkjt3brP/O3bsMMv1sXr16iVRUVFmPZ20CTsAAAAAIIONXq79uV988UX566+/TEjdvXu3LF682ARaDY7ple7fxx9/LO+99565xvh3330n3bp1k0KFCsn8+fOlSpUq8tZbb8mgQYOkf//+JkBbofvzzz83IVub1C9YsEBu3rwp69atc257wIABcvToUVmyZIkZXG7FihXSqlUr09xeH+teFi5caB5r9uzZphWBXvO8b9++JsD36NHDuZ4+/tSpU8029fenn35aTpw4IQ0aNDD96XUbERERZl3rUm4AAAAAgAwUuvv06WMqxa+++qpcv35dunTpYoLmrFmzpHPnzpIeaSX6jTfekK+//lrq169v5pUpU0a2bt0q77//vixatMj87N69u/z+++8mUGvwzZHjf4fo9ddfN89t/Pjxzm1qpVmd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o0YNyZUrl5QpU0bGjx8vt2/fdq7r5eUl7777rvzjH/+QPHnyyGuvvSblypWTqVOnum3z4MGDZt0TJ06kxVMDAAAAACSC0J0GnnrqKblw4YJ8++23znkXL16UL774Qrp27SpbtmyR7t27y6BBg+To0aPy/vvvy7x58+T111932864cePkiSeekCNHjkjv3r1NYJ87d67bOnq7SZMmJpADAAAAADyL0J0G8ufPL61bt5ZFixY553366adSsGBBadasmalqjxo1Snr06GGq3C1atJCJEyea8O2qS5cu0qtXL7NOiRIlpGfPnhIRESG7d+92NjnXx7Cq5wmJiYmR6OhotwkAAAAAkPoI3WlEK9rLly83gVctXLhQOnfuLNmyZZNDhw7JhAkTJG/evM6pb9++cu7cObl+/bpzG7Vq1XLbpjZZf+yxx+TDDz80t9esWWO2r5X1xISHh4u/v79zCgoKsuU5AwAAAEBWR+hOI23bthWHwyGff/65REZGmiblGsTV1atXTbVb+2NbkzYhP378uOnjbdG+3HH16dNHlixZIjdu3DBNyzt16iS5c+dOdF/CwsIkKirKOen+AAAAAABSXw4btol4aHhu3769qXDrIGcVKlQwA6cp/anNxFPSD/vRRx81YVwHWdM+4t9999097+Pj42MmAAAAAIC9CN1pSCvbbdq0kR9++EG6devmnD9mzBgzX/tpP/nkk84m599//70ZpTwx2bNnN327tXodHBws9evXT4NnAgAAAABICpqXp6GHHnpIAgMDTVVbB0WztGzZUtauXStfffWV1K5dW+rVqyczZsyQkiVLJmm7OpL5zZs3zSBrAAAAAID0g0p3GtIK9m+//RbvMg3eOiVE+4Mn5NdffxVvb29z2TEAAAAAQPpB6M7AdKTyP//801y/W0csv++++zy9SwAAAAAAFzQvz8AWL15smqBfvnxZJk+e7OndAQAAAADEQejOwHQAtdjYWNm3b58UL17c07sDAAAAAIiD0A0AAAAAgE3o0w2nR4Orip+fH0cEAAAAAFIJlW4AAAAAAGxC6AYAAAAAwCaEbgAAAAAAbELoBgAAAADAJgykBqftkSclT758HJEspHGJcp7eBQAAACBTo9INAAAAAIBNCN0AAAAAANiE0A0AAAAAgE0I3QAAAAAA2ITQ7UGhoaEyePDgVN3mpk2bxMvLSy5f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Z3rZrxo1asg///lPqVu3rmk63qlTJzMi+dNPP22q3uvXrzf3zZ07t/z4448yf/58uXDhghnV/MUXX5TnnnvO7TH0smM68rmGbgAAAABA+kCf7kwU7PWyY4cPH05xXwRGL8+46NMNAAAApC1GL88irl69agZRmz17trz00kue3h0AAAAAgAsuGZbB6TW99XJjoaGhNC0HAAAAgHSG5uWgeXkmQPNyAAAAIG3RvBwAAAAAAA9j9HI4FcuXR/zy5eGIAAAAAEAqoU83AAAAAAA2IXQDAAAAAGATQjcAAAAAADYhdAMAAAAAYBMGUoPTxesxcitHDEckgyiQ28fTuwAAAADgHqh0AwAAAABgE0I3AAAAAAA2IXQDAAAAAJBVQndoaKgMHjzY/F6qVCmZOXOmZDReXl6ycuVKjzz2vHnzJCAgwCOPDQAAAADIQAOp7dmzR/LkySMZzblz5yR//vzJCsr6RcPly5dt3S8AAAAAQNpK16G7UKFCkhEVKVLE07sAAAAAAMjqzcuvXbsm3bt3l7x580rRokVl2rRpbstdm5c7HA4ZN26clChRQnx8fKRYsWIycOBA57offfSR1KpVS/Lly2dCb5cuXeT8+fPO5Zs2bTLNvj///HOpWrWq5MqVS+rVqyfff//9XU2ztWl4cHCwWadly5YSGRnptl/vvvuulC1bVnLmzCkVKlQwj51Q8/IzZ86Y25999pk0a9ZMcufOLdWqVZMdO3Y496tXr14SFRVl1tNJn6eKiYmR4cOHS/HixU3Fv27dumZ9V7rPekx0u0888YRcuHDhb78uAAAAAIBMELpHjBghmzdvllWrVslXX31lAuX+/fvjXXf58uUyY8YMef/99+X48eMm1FapUsW5/NatWzJx4kQ5dOiQWaZht2fPnvE+poZ7bbqulfS2bdua+1quX78ur7/+uixYsEC2bdtmmnx37tzZuXzFihUyaNAgGTZsmAnszz33nAnN3377baLP9ZVXXjEB+uDBg1K+fHl5+umn5fbt29KgQQPzxYKfn59plq6TrqcGDBhgwvmSJUvk8OHD8tRTT0mrVq3M81e7du2S3r17m/V0uxrqX3vttRS8EgAAAACATNW8/OrVq/Kf//xHPv74Y3n44YfNvPnz58v9998f7/pnz541FezmzZuLt7e3qe7WqVPHufzZZ591/l6mTBl56623pHbt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e41vDgAAAAAAUoRKNwAAAAAANiF0AwAAAABgE0I3AAAAAAA2IXRncf/617+kVKlSkitXLqlbt67s3r3b07uENDRu3Djx8vJymypWrOhc/tdff8mLL74oBQoUkLx580qHDh3kjz/+4DXKZL777jtp27atFCtWzJwDK1eudFuuQ3+MGTNGihYtKr6+vtK8eXM5fvy42zoXL16Url27mmu6BwQESO/eveXq1atp/EyQludFz54973r/aNWqlds6nBeZT3h4uNSuXVvy5csnhQsXlscff1wiIiLc1knK/x1nz56Vxx57THLnzm22M2LECLl9+3YaPxuk5XkRGhp613tG//793dbhvMhc3n33Xalatar5bKBT/fr1Zf369VnyvYLQnYUtXbpUhg4dakYu379/v1SrVk1atmwp58+f9/SuIQ1VrlxZzp0755y2bt3qXDZkyBBZs2aNLFu2TDZv3iy//fabtG/fntcnk7l27Zr5+9cv4eIzefJkeeutt+S9996TXbt2SZ48ecx7hf5nadHA/cMPP8iGDRtk7dq1JrD169cvDZ8F0vq8UBqyXd8/Fi9e7Lac8yLz0f8L9EPyzp07zd/7rVu35JFHHjHnS1L/74iNjTUfom/evCnbt2+X+fPny7x588yXe8i854Xq27ev23uG/v9i4bzIfO6//36ZNGmS7Nu3T/bu3SsPPfSQtGvXznxeyHLvFTp6ObKmOnXqOF588UXn7djYWEexYsUc4eHhHt0vpJ2xY8c6qlWrFu+yy5cvO7y9vR3Lli1zzjt27Jhe7cCxY8eONNxLpCV9fVesWOG8fefOHUeRIkUcU6ZMcTs3fHx8HIsXLza3jx49au63Z88e5zrr1693eHl5OX799VdewEx4XqgePXo42rVrl+B9OC+yhvPnz5vzY/PmzUn+v2PdunWObNmyOX7//XfnOu+++67Dz8/PERMT44FnAbvPC9W0aVPHoEGDErwP50XWkD9/fsecOXOy3HsFle4sSr8x0m+dtJmoJVu2bOb2jh07PLpvSFvaTFibj5YpU8ZUpbQZj9LzQ7+pdj1HtOl5iRIlOEeykNOnT8vvv//udh74+/ub7ijWe4X+1CbltWrVcq6j6+t7ilbGkXlt2rTJNPerUKGCPP/883LhwgXnMs6LrCEqKsr8DAwMTPL/HfqzSpUqct999znX0dYz0dHRzgoY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",
438
+ "text/plain": [
439
+ "<Figure size 1000x600 with 1 Axes>"
440
+ ]
441
+ },
442
+ "metadata": {},
443
+ "output_type": "display_data"
444
+ },
445
+ {
446
+ "name": "stdout",
447
+ "output_type": "stream",
448
+ "text": [
449
+ "\n",
450
+ "Top 20 Important Features:\n",
451
+ " feature importance\n",
452
+ " not 302\n",
453
+ " but 152\n",
454
+ " great 116\n",
455
+ " good 98\n",
456
+ " best 79\n",
457
+ " book 63\n",
458
+ " love 58\n",
459
+ " would 53\n",
460
+ " well 51\n",
461
+ " excellent 51\n",
462
+ " one 51\n",
463
+ " however 50\n",
464
+ " like 50\n",
465
+ " very 48\n",
466
+ " bad 47\n",
467
+ " worst 46\n",
468
+ " boring 44\n",
469
+ " easy 42\n",
470
+ "disappointed 41\n",
471
+ " no 40\n"
472
+ ]
473
+ }
474
+ ],
475
+ "source": [
476
+ "# Get feature importance\n",
477
+ "tfidf_vectorizer = joblib.load('data/vectorizers/tfidf_vectorizer.joblib')\n",
478
+ "feature_names = tfidf_vectorizer.get_feature_names_out()\n",
479
+ "importances = lgb_classifier.feature_importances_\n",
480
+ "# Create DataFrame for better visualization\n",
481
+ "importance_df = pd.DataFrame({\n",
482
+ " 'feature': feature_names,\n",
483
+ " 'importance': importances\n",
484
+ "}).sort_values('importance', ascending=False).head(20)\n",
485
+ "# Plot top features\n",
486
+ "plt.figure(figsize=(10, 6))\n",
487
+ "sns.barplot(data=importance_df, x='importance', y='feature', palette='BuGn_r')\n",
488
+ "plt.title('Top 20 Important Features - LightGBM (Gain)')\n",
489
+ "plt.xlabel('Importance Score')\n",
490
+ "plt.ylabel('Features')\n",
491
+ "plt.tight_layout()\n",
492
+ "plt.savefig('lightgbm_feature_importance.png', dpi=300, bbox_inches='tight')\n",
493
+ "plt.show()\n",
494
+ "print(\"\\nTop 20 Important Features:\")\n",
495
+ "print(importance_df.to_string(index=False))"
496
+ ]
497
+ },
498
+ {
499
+ "cell_type": "markdown",
500
+ "id": "21",
501
+ "metadata": {
502
+ "id": "21"
503
+ },
504
+ "source": [
505
+ "## 10: Feature Importance by Type"
506
+ ]
507
+ },
508
+ {
509
+ "cell_type": "code",
510
+ "execution_count": 12,
511
+ "id": "22",
512
+ "metadata": {
513
+ "colab": {
514
+ "base_uri": "https://localhost:8080/"
515
+ },
516
+ "id": "22",
517
+ "outputId": "2e8515ce-af66-46d9-bc01-32f28250913a"
518
+ },
519
+ "outputs": [
520
+ {
521
+ "name": "stdout",
522
+ "output_type": "stream",
523
+ "text": [
524
+ "Top 10 Features by Split Count (How often used for splitting):\n",
525
+ " feature split_count\n",
526
+ " not 302\n",
527
+ " but 152\n",
528
+ " great 116\n",
529
+ " good 98\n",
530
+ " best 79\n",
531
+ " book 63\n",
532
+ " love 58\n",
533
+ " would 53\n",
534
+ " well 51\n",
535
+ "excellent 51\n"
536
+ ]
537
+ }
538
+ ],
539
+ "source": [
540
+ "# Get feature importance by split (how many times feature is used for splitting)\n",
541
+ "split_importance = lgb_classifier.booster_.feature_importance(importance_type='split')\n",
542
+ "# Create DataFrame\n",
543
+ "split_df = pd.DataFrame({\n",
544
+ " 'feature': feature_names,\n",
545
+ " 'split_count': split_importance\n",
546
+ "}).sort_values('split_count', ascending=False).head(10)\n",
547
+ "print(\"Top 10 Features by Split Count (How often used for splitting):\")\n",
548
+ "print(split_df.to_string(index=False))"
549
+ ]
550
+ },
551
+ {
552
+ "cell_type": "markdown",
553
+ "id": "23",
554
+ "metadata": {
555
+ "id": "23"
556
+ },
557
+ "source": [
558
+ "## 11: Model Summary"
559
+ ]
560
+ },
561
+ {
562
+ "cell_type": "code",
563
+ "execution_count": 13,
564
+ "id": "24",
565
+ "metadata": {
566
+ "colab": {
567
+ "base_uri": "https://localhost:8080/"
568
+ },
569
+ "id": "24",
570
+ "outputId": "eb874124-aef9-47dc-9527-7994bcda5789"
571
+ },
572
+ "outputs": [
573
+ {
574
+ "name": "stdout",
575
+ "output_type": "stream",
576
+ "text": [
577
+ "LIGHTGBM MODEL SUMMARY\n",
578
+ "\n",
579
+ "Model Parameters:\n",
580
+ " - Number of Estimators: 200\n",
581
+ " - Max Depth: 6\n",
582
+ " - Learning Rate: 0.1\n",
583
+ " - Num Leaves: 31\n",
584
+ " - Min Child Samples: 20\n",
585
+ " - Subsample: 0.8\n",
586
+ " - Colsample by Tree: 0.8\n",
587
+ "\n",
588
+ "Feature Engineering:\n",
589
+ " - Vectorizer: TF-IDF\n",
590
+ " - Max Features: 5000\n",
591
+ " - N-gram Range: (1, 2)\n",
592
+ " - Min Document Frequency: 5\n",
593
+ " - Max Document Frequency: 0.8\n",
594
+ "\n",
595
+ "Performance:\n",
596
+ " - Accuracy: 0.8267\n",
597
+ " - Precision: 0.8148\n",
598
+ " - Recall: 0.8471\n",
599
+ " - F1-Score: 0.8306\n",
600
+ " - Training Time: 72.0527 seconds\n",
601
+ "\n",
602
+ "Model Characteristics:\n",
603
+ " - Boosting Type: gbdt (Gradient Boosting Decision Tree)\n",
604
+ " - Tree Learner: serial\n",
605
+ " - Objective: binary_logloss\n",
606
+ " - Speed Advantage: Fastest among tree-based models\n"
607
+ ]
608
+ }
609
+ ],
610
+ "source": [
611
+ "print(\"LIGHTGBM MODEL SUMMARY\")\n",
612
+ "print(f\"\\nModel Parameters:\")\n",
613
+ "print(f\" - Number of Estimators: {lgb_classifier.n_estimators}\")\n",
614
+ "print(f\" - Max Depth: {lgb_classifier.max_depth}\")\n",
615
+ "print(f\" - Learning Rate: {lgb_classifier.learning_rate}\")\n",
616
+ "print(f\" - Num Leaves: {lgb_classifier.num_leaves}\")\n",
617
+ "print(f\" - Min Child Samples: {lgb_classifier.min_child_samples}\")\n",
618
+ "print(f\" - Subsample: {lgb_classifier.subsample}\")\n",
619
+ "print(f\" - Colsample by Tree: {lgb_classifier.colsample_bytree}\")\n",
620
+ "print(f\"\\nFeature Engineering:\")\n",
621
+ "print(f\" - Vectorizer: TF-IDF\")\n",
622
+ "print(f\" - Max Features: 5000\")\n",
623
+ "print(f\" - N-gram Range: (1, 2)\")\n",
624
+ "print(f\" - Min Document Frequency: 5\")\n",
625
+ "print(f\" - Max Document Frequency: 0.8\")\n",
626
+ "print(f\"\\nPerformance:\")\n",
627
+ "print(f\" - Accuracy: {accuracy:.4f}\")\n",
628
+ "print(f\" - Precision: {precision:.4f}\")\n",
629
+ "print(f\" - Recall: {recall:.4f}\")\n",
630
+ "print(f\" - F1-Score: {f1:.4f}\")\n",
631
+ "print(f\" - Training Time: {training_time:.4f} seconds\")\n",
632
+ "print(f\"\\nModel Characteristics:\")\n",
633
+ "print(f\" - Boosting Type: gbdt (Gradient Boosting Decision Tree)\")\n",
634
+ "print(f\" - Tree Learner: serial\")\n",
635
+ "print(f\" - Objective: binary_logloss\")\n",
636
+ "print(f\" - Speed Advantage: Fastest among tree-based models\")"
637
+ ]
638
+ }
639
+ ],
640
+ "metadata": {
641
+ "colab": {
642
+ "provenance": []
643
+ },
644
+ "kernelspec": {
645
+ "display_name": ".venv",
646
+ "language": "python",
647
+ "name": "python3"
648
+ },
649
+ "language_info": {
650
+ "codemirror_mode": {
651
+ "name": "ipython",
652
+ "version": 3
653
+ },
654
+ "file_extension": ".py",
655
+ "mimetype": "text/x-python",
656
+ "name": "python",
657
+ "nbconvert_exporter": "python",
658
+ "pygments_lexer": "ipython3",
659
+ "version": "3.13.11"
660
+ }
661
+ },
662
+ "nbformat": 4,
663
+ "nbformat_minor": 5
664
+ }
notebooks/{12_comparsion.ipynb → 14_comparsion.ipynb} RENAMED
File without changes