Spaces:
Sleeping
Sleeping
Student: Mohamed Kamal Abdullah Hasan commited on
Commit ·
b27ae83
1
Parent(s): 35305f1
lastes touches
Browse files- notebooks/01_data_acquisition.ipynb +10 -10
- notebooks/02_eda.ipynb +0 -0
- notebooks/03_data_preprocessing.ipynb +88 -288
- notebooks/04_feature_engineering.ipynb +0 -0
- notebooks/07_support_vector_machine.ipynb +0 -0
- notebooks/07_support_vector_machines.ipynb +0 -27
- notebooks/09_decision_trees.ipynb +0 -0
- notebooks/10_random_forest.ipynb +0 -0
- notebooks/11_stochastic_gradient_descent.ipynb +0 -0
- notebooks/12_xgboost.ipynb +0 -0
- notebooks/13_lightgbm.ipynb +664 -0
- notebooks/{12_comparsion.ipynb → 14_comparsion.ipynb} +0 -0
notebooks/01_data_acquisition.ipynb
CHANGED
|
@@ -37,8 +37,8 @@
|
|
| 37 |
"name": "stdout",
|
| 38 |
"output_type": "stream",
|
| 39 |
"text": [
|
| 40 |
-
"
|
| 41 |
-
"
|
| 42 |
]
|
| 43 |
}
|
| 44 |
],
|
|
@@ -481,13 +481,13 @@
|
|
| 481 |
"name": "stdout",
|
| 482 |
"output_type": "stream",
|
| 483 |
"text": [
|
| 484 |
-
"Saved dataframe sample_train.csv to data
|
| 485 |
]
|
| 486 |
},
|
| 487 |
{
|
| 488 |
"data": {
|
| 489 |
"text/plain": [
|
| 490 |
-
"{'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
|
| 648 |
]
|
| 649 |
},
|
| 650 |
{
|
| 651 |
"data": {
|
| 652 |
"text/plain": [
|
| 653 |
-
"{'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
|
| 940 |
]
|
| 941 |
},
|
| 942 |
{
|
| 943 |
"data": {
|
| 944 |
"text/plain": [
|
| 945 |
-
"{'csv':
|
| 946 |
]
|
| 947 |
},
|
| 948 |
"execution_count": 18,
|
|
@@ -957,7 +957,7 @@
|
|
| 957 |
],
|
| 958 |
"metadata": {
|
| 959 |
"kernelspec": {
|
| 960 |
-
"display_name": "
|
| 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.
|
| 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 |
-
"
|
| 42 |
-
"
|
| 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
|
| 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
|
| 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
|
| 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
|
| 283 |
" </tr>\n",
|
| 284 |
" <tr>\n",
|
| 285 |
" <th>4</th>\n",
|
|
@@ -288,7 +298,7 @@
|
|
| 288 |
" <td>I love these sheets! They are sleek & smooth w...</td>\n",
|
| 289 |
" <td>198</td>\n",
|
| 290 |
" <td>38</td>\n",
|
| 291 |
-
" <td>love sheet sleek smooth really
|
| 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
|
| 321 |
-
"1 using book introductory organic
|
| 322 |
-
"2 read first chapter
|
| 323 |
-
"3 feel cheaply made battery contact
|
| 324 |
-
"4 love sheet sleek smooth really
|
| 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": "
|
| 340 |
-
"
|
| 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 & 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 |
-
"
|
| 466 |
-
"
|
|
|
|
| 467 |
]
|
| 468 |
},
|
| 469 |
{
|
|
@@ -477,7 +366,7 @@
|
|
| 477 |
},
|
| 478 |
{
|
| 479 |
"cell_type": "code",
|
| 480 |
-
"execution_count":
|
| 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":
|
| 562 |
"metadata": {},
|
| 563 |
"output_type": "execute_result"
|
| 564 |
}
|
|
@@ -570,7 +459,7 @@
|
|
| 570 |
},
|
| 571 |
{
|
| 572 |
"cell_type": "code",
|
| 573 |
-
"execution_count":
|
| 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
|
| 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
|
| 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>
|
| 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
|
| 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
|
| 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
|
| 661 |
-
"1 carrier very cute
|
| 662 |
-
"2
|
| 663 |
-
"3 baby hooked dual output
|
| 664 |
-
"4 book very poorly written
|
| 665 |
]
|
| 666 |
},
|
| 667 |
-
"execution_count":
|
| 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": "
|
| 679 |
-
"
|
| 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 |
-
"
|
| 793 |
-
"
|
|
|
|
| 794 |
]
|
| 795 |
},
|
| 796 |
{
|
|
@@ -803,7 +583,7 @@
|
|
| 803 |
},
|
| 804 |
{
|
| 805 |
"cell_type": "code",
|
| 806 |
-
"execution_count":
|
| 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":
|
| 888 |
"metadata": {},
|
| 889 |
"output_type": "execute_result"
|
| 890 |
}
|
|
@@ -896,7 +676,7 @@
|
|
| 896 |
},
|
| 897 |
{
|
| 898 |
"cell_type": "code",
|
| 899 |
-
"execution_count":
|
| 900 |
"metadata": {},
|
| 901 |
"outputs": [
|
| 902 |
{
|
|
@@ -989,7 +769,7 @@
|
|
| 989 |
"4 although book touted several anusara web site ... "
|
| 990 |
]
|
| 991 |
},
|
| 992 |
-
"execution_count":
|
| 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":
|
| 1005 |
"id": "b5e64aec",
|
| 1006 |
"metadata": {},
|
| 1007 |
"outputs": [
|
|
@@ -1108,7 +898,7 @@
|
|
| 1108 |
"4 not anusara "
|
| 1109 |
]
|
| 1110 |
},
|
| 1111 |
-
"execution_count":
|
| 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":
|
| 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
|
| 1140 |
]
|
| 1141 |
},
|
| 1142 |
{
|
| 1143 |
"data": {
|
| 1144 |
"text/plain": [
|
| 1145 |
-
"{'csv':
|
| 1146 |
]
|
| 1147 |
},
|
| 1148 |
-
"execution_count":
|
| 1149 |
"metadata": {},
|
| 1150 |
"output_type": "execute_result"
|
| 1151 |
}
|
|
@@ -1156,7 +956,7 @@
|
|
| 1156 |
},
|
| 1157 |
{
|
| 1158 |
"cell_type": "code",
|
| 1159 |
-
"execution_count":
|
| 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
|
| 1168 |
]
|
| 1169 |
},
|
| 1170 |
{
|
| 1171 |
"data": {
|
| 1172 |
"text/plain": [
|
| 1173 |
-
"{'csv':
|
| 1174 |
]
|
| 1175 |
},
|
| 1176 |
-
"execution_count":
|
| 1177 |
"metadata": {},
|
| 1178 |
"output_type": "execute_result"
|
| 1179 |
}
|
|
@@ -1184,7 +984,7 @@
|
|
| 1184 |
},
|
| 1185 |
{
|
| 1186 |
"cell_type": "code",
|
| 1187 |
-
"execution_count":
|
| 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
|
| 1196 |
]
|
| 1197 |
},
|
| 1198 |
{
|
| 1199 |
"data": {
|
| 1200 |
"text/plain": [
|
| 1201 |
-
"{'csv':
|
| 1202 |
]
|
| 1203 |
},
|
| 1204 |
-
"execution_count":
|
| 1205 |
"metadata": {},
|
| 1206 |
"output_type": "execute_result"
|
| 1207 |
}
|
|
@@ -1213,7 +1013,7 @@
|
|
| 1213 |
],
|
| 1214 |
"metadata": {
|
| 1215 |
"kernelspec": {
|
| 1216 |
-
"display_name": "
|
| 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.
|
| 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 & 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/l6mTBl56623pHbt2uZxtJJuGTt2rLRo0cLt8TRId+zY0czTAD579mxTVbbWqVSpkuzevds83tSpU02Yf+GFF8zyoUOHys6dO818Db0J0SD92GOPmd/Hjx8vlStXlhMnTkjFihXF39/fVLhdm6Xr8507d675qVV9axtffPGFmf/GG2/IrFmzTAh/+eWXzXIN89u3bzfrJEYr6DpZoqOjE10fAAAAAJDBKt0nT56UmzdvOsOtCgwMNM2146NV3hs3bphA3bdvXxOUtVJs2bdvn6laaxjXJuZNmzY18zW0uqpfv/5dj3fs2DHnvBw5cpiwbtFQrE3OrXX0Z8OGDd22qbddtxEfbdJu0ab0yrX5e1xHjhyR2NhYE6T1SwNr0pYBeuysfXE9fnGfX0LCw8NN0LemoKCge94HAAAAAJDJBlJzpcEwIiJCvv76a9mwYYOpNE+ZMsWEUA3v2vdap4ULF5pm4xq29bYuSw+0Om/Rqra6c+dOgutrhT579uzmywT96cq1cp8SYWFhpkLvWukmeAMAAABAJqp060BkGkS1X7Ll0qVL8tNPPyV4H19fX1PN1qbj2v9b+ztrRfjHH380A4hNmjRJGjdubKrTCVWRtSl43MfT5uMWrZ7v3bvXeVuDvvbrttbRn9rX25XeDgkJSeGREDMgm1a1XVWvXt3M0+dRrlw5t8lqhq774nr84j6/hOhAdNqH3HUCAAAAAGSiSrdWa3UQMB3YrECBAlK4cGEz2Fi2bPF/D6CjdGsI1ebUOlK39gXXEF6yZElTMdbg+vbbb0v//v3NAGc6qFp8JkyYYB7vvvvuM49XsGBBefzxx53L9YuAl156yQR7bWqug5TpKOdW/3HdX+3/raFY+5evWbPGjEyuFfiU0lHatbK9ceNGM7K5Pj9tVt61a1czursO/KaP9+eff5p1tKm69g/X0du1abv2J2/Xrp18+eWX9+zPDQAAAADIIqOXa/NwrUxr9VoDbKNGjaRmzZrxrqv9qj/44AMTMjV0asjVwKsBWpuTayhftmyZqThrxVuDaHx0mY4+ro/z+++/m21oYLdo4B05cqS55Jg+ln45sHTpUudyDeg6gJluXwdD09HUdWCz0NDQFB8HHcFcvyzo1KmTeS6TJ08283W7Grp1pHTte66PraOua791pV8G6DHR/dGwriPAv/rqqyneDwAAAABA6vJy6AWwswBtjq6ji2uTcg3w8dHgPnjwYNOcPCvRPt06oNrpc+clH03NM4wCuX08vQsAAABAlhX9/zkqKioq0S67Hq10AwAAAACQmRG6AQAAAACwSZZpXo6E0bw8Y6J5OQAAAOA5NC8HAAAAACCrXjIM6U9gbh/xY3AuAAAAAEg19OkGAAAAAMAmhG4AAAAAAGxC6AYAAAAAwCaEbgAAAAAAbMJAanC6EnNLvGJucUTSuXw+3p7eBQAAAABJRKUbAAAAAACbELoBAAAAALAJoRsAAAAAAJsQugEAAAAAsAmhGwAAAAAAmxC6AQAAAACwCaEbAAAAAACbELrTudDQUBk4cKC8/PLLEhgYKEWKFJFx48Y5l589e1batWsnefPmFT8/P+nYsaP88ccfHt1nAAAAAMD/ELozgPnz50uePHlk165dMnnyZJkwYYJs2LBB7ty5YwL3xYsXZfPmzWbeqVOnpFOnToluLyYmRqKjo90mAAAAAEDqy2HDNpHKqlatKmPHjjW/BwcHy+zZs2Xjxo3m9pEjR+T06dMSFBRkbi9YsEAqV64se/bskdq1a8e7vfDwcBk/fjyvEwAAAADYjEp3BgndrooWLSrnz5+XY8eOmbBtBW4VEhIiAQEBZllCwsLCJCoqyjlFRkbauv8AAAAAkFVR6c4AvL293W57eXmZpuUp5ePjYyYAAAAAgL2odGdglSpVMlVq10r10aNH5fLly6biDQAAAADwLEJ3Bta8eXOpUqWKdO3aVfbv3y+7d++W7t27S9OmTaVWrVqe3j0AAAAAyPII3RmYNjNftWqV5M+fX5o0aWJCeJkyZWTp0qWe3jUAAAAAgOY2h8Ph4EhkbXrJMH9/f/nl/H/Ntb6RvuXzce/jDwAAAMBzOUoHp04sR1HpBgAAAADAJoRuAAAAAABsQugGAAAAAMAmXKcbbn2F6S8MAAAAAKmHSjcAAAAAADah0g2xBrDX0fcAAAAAAPdm5ad7XRCM0A25cOGCOQpBQUEcDQAAAABIhitXrphLhyWE0A0JDAw0R+Hs2bOJnizIet/c6RcxkZGRXL8dnBfg/QL8PwI+X4DPnXFohVsDd7FixSQxhG5Itmz/69qvgTuxi7oja9JzgvMCnBfg/QL8PwI+X4DPnXdLStGSgdQAAAAAALAJoRsAAAAAAJsQuiE+Pj4yduxY8xOwcF4gPpwX4LxAUvF+Ac4L8H7xP16Oe41vDgAAAAAAUoRKNwAAAAAANiF0AwAAAABgE0I3AAAAAAA2IXRncf/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
|