{
  "nbformat": 4,
  "nbformat_minor": 0,
  "metadata": {
    "colab": {
      "provenance": [],
      "collapsed_sections": [
        "rR4yeBk1uD85",
        "RV4a40eiuXG1",
        "3e_SHcpnuuW4",
        "Pn6XezJuu1_I",
        "_fulCDIYu7fH",
        "Y5rU1UOQvCet",
        "yk9t4oE-vJX8",
        "K1SB96jovfLD",
        "2F4wttgWvkZ9",
        "UIMOWkt8z1Sn",
        "DYzurMvMwJhZ",
        "_O6BZ_yvwP3r",
        "HwyV8WMnxgov",
        "N-BzCg5XyEZH",
        "f4_HOJ2sySPW"
      ]
    },
    "kernelspec": {
      "name": "python3",
      "display_name": "Python 3"
    },
    "language_info": {
      "name": "python"
    }
  },
  "cells": [
    {
      "cell_type": "markdown",
      "source": [
        "# Imports"
      ],
      "metadata": {
        "id": "rR4yeBk1uD85"
      }
    },
    {
      "cell_type": "code",
      "source": [
        "import pandas as pd\n",
        "import numpy as np\n",
        "import re\n",
        "\n",
        "from nltk.corpus import stopwords\n",
        "from nltk.tokenize import word_tokenize\n",
        "\n",
        "from sklearn.model_selection import train_test_split, GridSearchCV\n",
        "from sklearn.metrics import accuracy_score, precision_score, recall_score, f1_score, confusion_matrix, classification_report\n",
        "\n",
        "import matplotlib.pyplot as plt\n",
        "import seaborn as sns\n",
        "\n",
        "from sklearn.feature_extraction.text import CountVectorizer, TfidfVectorizer\n",
        "from sklearn.linear_model import LogisticRegression\n",
        "from sklearn.ensemble import RandomForestClassifier\n",
        "from sklearn.tree import DecisionTreeClassifier\n",
        "from sklearn.svm import SVC\n",
        "import nltk\n",
        "nltk.download(\"punkt\")\n",
        "nltk.download(\"stopwords\")\n"
      ],
      "metadata": {
        "colab": {
          "base_uri": "https://localhost:8080/"
        },
        "id": "7zv0APBouJky",
        "outputId": "4999c76d-1fcb-4183-c922-78c6264f60e4"
      },
      "execution_count": 44,
      "outputs": [
        {
          "output_type": "stream",
          "name": "stderr",
          "text": [
            "[nltk_data] Downloading package punkt to /root/nltk_data...\n",
            "[nltk_data]   Package punkt is already up-to-date!\n",
            "[nltk_data] Downloading package stopwords to /root/nltk_data...\n",
            "[nltk_data]   Package stopwords is already up-to-date!\n"
          ]
        },
        {
          "output_type": "execute_result",
          "data": {
            "text/plain": [
              "True"
            ]
          },
          "metadata": {},
          "execution_count": 44
        }
      ]
    },
    {
      "cell_type": "markdown",
      "source": [
        "# Load Dataset"
      ],
      "metadata": {
        "id": "RV4a40eiuXG1"
      }
    },
    {
      "cell_type": "code",
      "source": [
        "df = pd.read_csv(\"/content/all_kindle_review .csv\")\n",
        "df.head()"
      ],
      "metadata": {
        "colab": {
          "base_uri": "https://localhost:8080/",
          "height": 206
        },
        "id": "LgIlTG7ouQdC",
        "outputId": "ad75619a-9d3e-442f-9fa4-5ec4537d3a1d"
      },
      "execution_count": 45,
      "outputs": [
        {
          "output_type": "execute_result",
          "data": {
            "text/plain": [
              "   Unnamed: 0.1  Unnamed: 0        asin  helpful  rating  \\\n",
              "0             0       11539  B0033UV8HI  [8, 10]       3   \n",
              "1             1        5957  B002HJV4DE   [1, 1]       5   \n",
              "2             2        9146  B002ZG96I4   [0, 0]       3   \n",
              "3             3        7038  B002QHWOEU   [1, 3]       3   \n",
              "4             4        1776  B001A06VJ8   [0, 1]       4   \n",
              "\n",
              "                                          reviewText   reviewTime  \\\n",
              "0  Jace Rankin may be short, but he's nothing to ...   09 2, 2010   \n",
              "1  Great short read.  I didn't want to put it dow...   10 8, 2013   \n",
              "2  I'll start by saying this is the first of four...  04 11, 2014   \n",
              "3  Aggie is Angela Lansbury who carries pocketboo...   07 5, 2014   \n",
              "4  I did not expect this type of book to be in li...  12 31, 2012   \n",
              "\n",
              "       reviewerID  reviewerName                   summary  unixReviewTime  \n",
              "0  A3HHXRELK8BHQG        Ridley  Entertaining But Average      1283385600  \n",
              "1  A2RGNZ0TRF578I  Holly Butler   Terrific menage scenes!      1381190400  \n",
              "2  A3S0H2HV6U1I7F       Merissa          Snapdragon Alley      1397174400  \n",
              "3   AC4OQW3GZ919J    Cleargrace    very light murder cozy      1404518400  \n",
              "4  A3C9V987IQHOQD      Rjostler                      Book      1356912000  "
            ],
            "text/html": [
              "\n",
              "  <div id=\"df-221c44f6-2d46-42dd-8e97-bea7a5edf658\" class=\"colab-df-container\">\n",
              "    <div>\n",
              "<style scoped>\n",
              "    .dataframe tbody tr th:only-of-type {\n",
              "        vertical-align: middle;\n",
              "    }\n",
              "\n",
              "    .dataframe tbody tr th {\n",
              "        vertical-align: top;\n",
              "    }\n",
              "\n",
              "    .dataframe thead th {\n",
              "        text-align: right;\n",
              "    }\n",
              "</style>\n",
              "<table border=\"1\" class=\"dataframe\">\n",
              "  <thead>\n",
              "    <tr style=\"text-align: right;\">\n",
              "      <th></th>\n",
              "      <th>Unnamed: 0.1</th>\n",
              "      <th>Unnamed: 0</th>\n",
              "      <th>asin</th>\n",
              "      <th>helpful</th>\n",
              "      <th>rating</th>\n",
              "      <th>reviewText</th>\n",
              "      <th>reviewTime</th>\n",
              "      <th>reviewerID</th>\n",
              "      <th>reviewerName</th>\n",
              "      <th>summary</th>\n",
              "      <th>unixReviewTime</th>\n",
              "    </tr>\n",
              "  </thead>\n",
              "  <tbody>\n",
              "    <tr>\n",
              "      <th>0</th>\n",
              "      <td>0</td>\n",
              "      <td>11539</td>\n",
              "      <td>B0033UV8HI</td>\n",
              "      <td>[8, 10]</td>\n",
              "      <td>3</td>\n",
              "      <td>Jace Rankin may be short, but he's nothing to ...</td>\n",
              "      <td>09 2, 2010</td>\n",
              "      <td>A3HHXRELK8BHQG</td>\n",
              "      <td>Ridley</td>\n",
              "      <td>Entertaining But Average</td>\n",
              "      <td>1283385600</td>\n",
              "    </tr>\n",
              "    <tr>\n",
              "      <th>1</th>\n",
              "      <td>1</td>\n",
              "      <td>5957</td>\n",
              "      <td>B002HJV4DE</td>\n",
              "      <td>[1, 1]</td>\n",
              "      <td>5</td>\n",
              "      <td>Great short read.  I didn't want to put it dow...</td>\n",
              "      <td>10 8, 2013</td>\n",
              "      <td>A2RGNZ0TRF578I</td>\n",
              "      <td>Holly Butler</td>\n",
              "      <td>Terrific menage scenes!</td>\n",
              "      <td>1381190400</td>\n",
              "    </tr>\n",
              "    <tr>\n",
              "      <th>2</th>\n",
              "      <td>2</td>\n",
              "      <td>9146</td>\n",
              "      <td>B002ZG96I4</td>\n",
              "      <td>[0, 0]</td>\n",
              "      <td>3</td>\n",
              "      <td>I'll start by saying this is the first of four...</td>\n",
              "      <td>04 11, 2014</td>\n",
              "      <td>A3S0H2HV6U1I7F</td>\n",
              "      <td>Merissa</td>\n",
              "      <td>Snapdragon Alley</td>\n",
              "      <td>1397174400</td>\n",
              "    </tr>\n",
              "    <tr>\n",
              "      <th>3</th>\n",
              "      <td>3</td>\n",
              "      <td>7038</td>\n",
              "      <td>B002QHWOEU</td>\n",
              "      <td>[1, 3]</td>\n",
              "      <td>3</td>\n",
              "      <td>Aggie is Angela Lansbury who carries pocketboo...</td>\n",
              "      <td>07 5, 2014</td>\n",
              "      <td>AC4OQW3GZ919J</td>\n",
              "      <td>Cleargrace</td>\n",
              "      <td>very light murder cozy</td>\n",
              "      <td>1404518400</td>\n",
              "    </tr>\n",
              "    <tr>\n",
              "      <th>4</th>\n",
              "      <td>4</td>\n",
              "      <td>1776</td>\n",
              "      <td>B001A06VJ8</td>\n",
              "      <td>[0, 1]</td>\n",
              "      <td>4</td>\n",
              "      <td>I did not expect this type of book to be in li...</td>\n",
              "      <td>12 31, 2012</td>\n",
              "      <td>A3C9V987IQHOQD</td>\n",
              "      <td>Rjostler</td>\n",
              "      <td>Book</td>\n",
              "      <td>1356912000</td>\n",
              "    </tr>\n",
              "  </tbody>\n",
              "</table>\n",
              "</div>\n",
              "    <div class=\"colab-df-buttons\">\n",
              "\n",
              "  <div class=\"colab-df-container\">\n",
              "    <button class=\"colab-df-convert\" onclick=\"convertToInteractive('df-221c44f6-2d46-42dd-8e97-bea7a5edf658')\"\n",
              "            title=\"Convert this dataframe to an interactive table.\"\n",
              "            style=\"display:none;\">\n",
              "\n",
              "  <svg xmlns=\"http://www.w3.org/2000/svg\" height=\"24px\" viewBox=\"0 -960 960 960\">\n",
              "    <path d=\"M120-120v-720h720v720H120Zm60-500h600v-160H180v160Zm220 220h160v-160H400v160Zm0 220h160v-160H400v160ZM180-400h160v-160H180v160Zm440 0h160v-160H620v160ZM180-180h160v-160H180v160Zm440 0h160v-160H620v160Z\"/>\n",
              "  </svg>\n",
              "    </button>\n",
              "\n",
              "  <style>\n",
              "    .colab-df-container {\n",
              "      display:flex;\n",
              "      gap: 12px;\n",
              "    }\n",
              "\n",
              "    .colab-df-convert {\n",
              "      background-color: #E8F0FE;\n",
              "      border: none;\n",
              "      border-radius: 50%;\n",
              "      cursor: pointer;\n",
              "      display: none;\n",
              "      fill: #1967D2;\n",
              "      height: 32px;\n",
              "      padding: 0 0 0 0;\n",
              "      width: 32px;\n",
              "    }\n",
              "\n",
              "    .colab-df-convert:hover {\n",
              "      background-color: #E2EBFA;\n",
              "      box-shadow: 0px 1px 2px rgba(60, 64, 67, 0.3), 0px 1px 3px 1px rgba(60, 64, 67, 0.15);\n",
              "      fill: #174EA6;\n",
              "    }\n",
              "\n",
              "    .colab-df-buttons div {\n",
              "      margin-bottom: 4px;\n",
              "    }\n",
              "\n",
              "    [theme=dark] .colab-df-convert {\n",
              "      background-color: #3B4455;\n",
              "      fill: #D2E3FC;\n",
              "    }\n",
              "\n",
              "    [theme=dark] .colab-df-convert:hover {\n",
              "      background-color: #434B5C;\n",
              "      box-shadow: 0px 1px 3px 1px rgba(0, 0, 0, 0.15);\n",
              "      filter: drop-shadow(0px 1px 2px rgba(0, 0, 0, 0.3));\n",
              "      fill: #FFFFFF;\n",
              "    }\n",
              "  </style>\n",
              "\n",
              "    <script>\n",
              "      const buttonEl =\n",
              "        document.querySelector('#df-221c44f6-2d46-42dd-8e97-bea7a5edf658 button.colab-df-convert');\n",
              "      buttonEl.style.display =\n",
              "        google.colab.kernel.accessAllowed ? 'block' : 'none';\n",
              "\n",
              "      async function convertToInteractive(key) {\n",
              "        const element = document.querySelector('#df-221c44f6-2d46-42dd-8e97-bea7a5edf658');\n",
              "        const dataTable =\n",
              "          await google.colab.kernel.invokeFunction('convertToInteractive',\n",
              "                                                    [key], {});\n",
              "        if (!dataTable) return;\n",
              "\n",
              "        const docLinkHtml = 'Like what you see? Visit the ' +\n",
              "          '<a target=\"_blank\" href=https://colab.research.google.com/notebooks/data_table.ipynb>data table notebook</a>'\n",
              "          + ' to learn more about interactive tables.';\n",
              "        element.innerHTML = '';\n",
              "        dataTable['output_type'] = 'display_data';\n",
              "        await google.colab.output.renderOutput(dataTable, element);\n",
              "        const docLink = document.createElement('div');\n",
              "        docLink.innerHTML = docLinkHtml;\n",
              "        element.appendChild(docLink);\n",
              "      }\n",
              "    </script>\n",
              "  </div>\n",
              "\n",
              "\n",
              "    <div id=\"df-76388317-9323-479f-b14d-3240c193fa42\">\n",
              "      <button class=\"colab-df-quickchart\" onclick=\"quickchart('df-76388317-9323-479f-b14d-3240c193fa42')\"\n",
              "                title=\"Suggest charts\"\n",
              "                style=\"display:none;\">\n",
              "\n",
              "<svg xmlns=\"http://www.w3.org/2000/svg\" height=\"24px\"viewBox=\"0 0 24 24\"\n",
              "     width=\"24px\">\n",
              "    <g>\n",
              "        <path d=\"M19 3H5c-1.1 0-2 .9-2 2v14c0 1.1.9 2 2 2h14c1.1 0 2-.9 2-2V5c0-1.1-.9-2-2-2zM9 17H7v-7h2v7zm4 0h-2V7h2v10zm4 0h-2v-4h2v4z\"/>\n",
              "    </g>\n",
              "</svg>\n",
              "      </button>\n",
              "\n",
              "<style>\n",
              "  .colab-df-quickchart {\n",
              "      --bg-color: #E8F0FE;\n",
              "      --fill-color: #1967D2;\n",
              "      --hover-bg-color: #E2EBFA;\n",
              "      --hover-fill-color: #174EA6;\n",
              "      --disabled-fill-color: #AAA;\n",
              "      --disabled-bg-color: #DDD;\n",
              "  }\n",
              "\n",
              "  [theme=dark] .colab-df-quickchart {\n",
              "      --bg-color: #3B4455;\n",
              "      --fill-color: #D2E3FC;\n",
              "      --hover-bg-color: #434B5C;\n",
              "      --hover-fill-color: #FFFFFF;\n",
              "      --disabled-bg-color: #3B4455;\n",
              "      --disabled-fill-color: #666;\n",
              "  }\n",
              "\n",
              "  .colab-df-quickchart {\n",
              "    background-color: var(--bg-color);\n",
              "    border: none;\n",
              "    border-radius: 50%;\n",
              "    cursor: pointer;\n",
              "    display: none;\n",
              "    fill: var(--fill-color);\n",
              "    height: 32px;\n",
              "    padding: 0;\n",
              "    width: 32px;\n",
              "  }\n",
              "\n",
              "  .colab-df-quickchart:hover {\n",
              "    background-color: var(--hover-bg-color);\n",
              "    box-shadow: 0 1px 2px rgba(60, 64, 67, 0.3), 0 1px 3px 1px rgba(60, 64, 67, 0.15);\n",
              "    fill: var(--button-hover-fill-color);\n",
              "  }\n",
              "\n",
              "  .colab-df-quickchart-complete:disabled,\n",
              "  .colab-df-quickchart-complete:disabled:hover {\n",
              "    background-color: var(--disabled-bg-color);\n",
              "    fill: var(--disabled-fill-color);\n",
              "    box-shadow: none;\n",
              "  }\n",
              "\n",
              "  .colab-df-spinner {\n",
              "    border: 2px solid var(--fill-color);\n",
              "    border-color: transparent;\n",
              "    border-bottom-color: var(--fill-color);\n",
              "    animation:\n",
              "      spin 1s steps(1) infinite;\n",
              "  }\n",
              "\n",
              "  @keyframes spin {\n",
              "    0% {\n",
              "      border-color: transparent;\n",
              "      border-bottom-color: var(--fill-color);\n",
              "      border-left-color: var(--fill-color);\n",
              "    }\n",
              "    20% {\n",
              "      border-color: transparent;\n",
              "      border-left-color: var(--fill-color);\n",
              "      border-top-color: var(--fill-color);\n",
              "    }\n",
              "    30% {\n",
              "      border-color: transparent;\n",
              "      border-left-color: var(--fill-color);\n",
              "      border-top-color: var(--fill-color);\n",
              "      border-right-color: var(--fill-color);\n",
              "    }\n",
              "    40% {\n",
              "      border-color: transparent;\n",
              "      border-right-color: var(--fill-color);\n",
              "      border-top-color: var(--fill-color);\n",
              "    }\n",
              "    60% {\n",
              "      border-color: transparent;\n",
              "      border-right-color: var(--fill-color);\n",
              "    }\n",
              "    80% {\n",
              "      border-color: transparent;\n",
              "      border-right-color: var(--fill-color);\n",
              "      border-bottom-color: var(--fill-color);\n",
              "    }\n",
              "    90% {\n",
              "      border-color: transparent;\n",
              "      border-bottom-color: var(--fill-color);\n",
              "    }\n",
              "  }\n",
              "</style>\n",
              "\n",
              "      <script>\n",
              "        async function quickchart(key) {\n",
              "          const quickchartButtonEl =\n",
              "            document.querySelector('#' + key + ' button');\n",
              "          quickchartButtonEl.disabled = true;  // To prevent multiple clicks.\n",
              "          quickchartButtonEl.classList.add('colab-df-spinner');\n",
              "          try {\n",
              "            const charts = await google.colab.kernel.invokeFunction(\n",
              "                'suggestCharts', [key], {});\n",
              "          } catch (error) {\n",
              "            console.error('Error during call to suggestCharts:', error);\n",
              "          }\n",
              "          quickchartButtonEl.classList.remove('colab-df-spinner');\n",
              "          quickchartButtonEl.classList.add('colab-df-quickchart-complete');\n",
              "        }\n",
              "        (() => {\n",
              "          let quickchartButtonEl =\n",
              "            document.querySelector('#df-76388317-9323-479f-b14d-3240c193fa42 button');\n",
              "          quickchartButtonEl.style.display =\n",
              "            google.colab.kernel.accessAllowed ? 'block' : 'none';\n",
              "        })();\n",
              "      </script>\n",
              "    </div>\n",
              "\n",
              "    </div>\n",
              "  </div>\n"
            ],
            "application/vnd.google.colaboratory.intrinsic+json": {
              "type": "dataframe",
              "variable_name": "df",
              "summary": "{\n  \"name\": \"df\",\n  \"rows\": 12000,\n  \"fields\": [\n    {\n      \"column\": \"Unnamed: 0.1\",\n      \"properties\": {\n        \"dtype\": \"number\",\n        \"std\": 3464,\n        \"min\": 0,\n        \"max\": 11999,\n        \"num_unique_values\": 12000,\n        \"samples\": [\n          1935,\n          6494,\n          1720\n        ],\n        \"semantic_type\": \"\",\n        \"description\": \"\"\n      }\n    },\n    {\n      \"column\": \"Unnamed: 0\",\n      \"properties\": {\n        \"dtype\": \"number\",\n        \"std\": 10502,\n        \"min\": 0,\n        \"max\": 47770,\n        \"num_unique_values\": 12000,\n        \"samples\": [\n          14172,\n          26105,\n          11888\n        ],\n        \"semantic_type\": \"\",\n        \"description\": \"\"\n      }\n    },\n    {\n      \"column\": \"asin\",\n      \"properties\": {\n        \"dtype\": \"category\",\n        \"num_unique_values\": 2114,\n        \"samples\": [\n          \"B00309SCW6\",\n          \"B00381B94O\",\n          \"B00332F4YE\"\n        ],\n        \"semantic_type\": \"\",\n        \"description\": \"\"\n      }\n    },\n    {\n      \"column\": \"helpful\",\n      \"properties\": {\n        \"dtype\": \"category\",\n        \"num_unique_values\": 393,\n        \"samples\": [\n          \"[7, 12]\",\n          \"[36, 43]\",\n          \"[13, 15]\"\n        ],\n        \"semantic_type\": \"\",\n        \"description\": \"\"\n      }\n    },\n    {\n      \"column\": \"rating\",\n      \"properties\": {\n        \"dtype\": \"number\",\n        \"std\": 1,\n        \"min\": 1,\n        \"max\": 5,\n        \"num_unique_values\": 5,\n        \"samples\": [\n          5,\n          1,\n          4\n        ],\n        \"semantic_type\": \"\",\n        \"description\": \"\"\n      }\n    },\n    {\n      \"column\": \"reviewText\",\n      \"properties\": {\n        \"dtype\": \"string\",\n        \"num_unique_values\": 12000,\n        \"samples\": [\n          \"Was a really great read just wish there would have been more of it. Hope to find more by this author.\",\n          \"Nope. I tried. Can't read it. I will take the greatest delight in deleting this from my Kindle. A total waste of time.\",\n          \"The story line just drug on and on. I did not like this book very much and if you are a mystery fan I would not tell you it is worth reading.\"\n        ],\n        \"semantic_type\": \"\",\n        \"description\": \"\"\n      }\n    },\n    {\n      \"column\": \"reviewTime\",\n      \"properties\": {\n        \"dtype\": \"object\",\n        \"num_unique_values\": 1953,\n        \"samples\": [\n          \"12 25, 2011\",\n          \"06 7, 2008\",\n          \"07 14, 2014\"\n        ],\n        \"semantic_type\": \"\",\n        \"description\": \"\"\n      }\n    },\n    {\n      \"column\": \"reviewerID\",\n      \"properties\": {\n        \"dtype\": \"string\",\n        \"num_unique_values\": 7614,\n        \"samples\": [\n          \"A1EKFH7U0YZ02I\",\n          \"A2LNVIYOP4RTO5\",\n          \"A11PZSMLJVJ3WP\"\n        ],\n        \"semantic_type\": \"\",\n        \"description\": \"\"\n      }\n    },\n    {\n      \"column\": \"reviewerName\",\n      \"properties\": {\n        \"dtype\": \"string\",\n        \"num_unique_values\": 6735,\n        \"samples\": [\n          \"Sandra \\\"Sam\\\"\",\n          \"Amazon Customer \\\"fulltimer\\\"\",\n          \"M. M. Robinson \\\"voracious reader\\\"\"\n        ],\n        \"semantic_type\": \"\",\n        \"description\": \"\"\n      }\n    },\n    {\n      \"column\": \"summary\",\n      \"properties\": {\n        \"dtype\": \"string\",\n        \"num_unique_values\": 10126,\n        \"samples\": [\n          \"She wasn't the only one, redeemed.\",\n          \"You Get What You Pay For\",\n          \"What a misleading title\"\n        ],\n        \"semantic_type\": \"\",\n        \"description\": \"\"\n      }\n    },\n    {\n      \"column\": \"unixReviewTime\",\n      \"properties\": {\n        \"dtype\": \"number\",\n        \"std\": 43693742,\n        \"min\": 960249600,\n        \"max\": 1405814400,\n        \"num_unique_values\": 1953,\n        \"samples\": [\n          1324771200,\n          1212796800,\n          1405296000\n        ],\n        \"semantic_type\": \"\",\n        \"description\": \"\"\n      }\n    }\n  ]\n}"
            }
          },
          "metadata": {},
          "execution_count": 45
        }
      ]
    },
    {
      "cell_type": "code",
      "source": [
        "print(df.shape)\n",
        "print(df.columns)\n",
        "df.isna().sum()"
      ],
      "metadata": {
        "colab": {
          "base_uri": "https://localhost:8080/",
          "height": 516
        },
        "id": "_7_hJ_llukBT",
        "outputId": "999718bb-e69a-47d8-ed71-e3310bae1745"
      },
      "execution_count": 46,
      "outputs": [
        {
          "output_type": "stream",
          "name": "stdout",
          "text": [
            "(12000, 11)\n",
            "Index(['Unnamed: 0.1', 'Unnamed: 0', 'asin', 'helpful', 'rating', 'reviewText',\n",
            "       'reviewTime', 'reviewerID', 'reviewerName', 'summary',\n",
            "       'unixReviewTime'],\n",
            "      dtype='object')\n"
          ]
        },
        {
          "output_type": "execute_result",
          "data": {
            "text/plain": [
              "Unnamed: 0.1       0\n",
              "Unnamed: 0         0\n",
              "asin               0\n",
              "helpful            0\n",
              "rating             0\n",
              "reviewText         0\n",
              "reviewTime         0\n",
              "reviewerID         0\n",
              "reviewerName      38\n",
              "summary            2\n",
              "unixReviewTime     0\n",
              "dtype: int64"
            ],
            "text/html": [
              "<div>\n",
              "<style scoped>\n",
              "    .dataframe tbody tr th:only-of-type {\n",
              "        vertical-align: middle;\n",
              "    }\n",
              "\n",
              "    .dataframe tbody tr th {\n",
              "        vertical-align: top;\n",
              "    }\n",
              "\n",
              "    .dataframe thead th {\n",
              "        text-align: right;\n",
              "    }\n",
              "</style>\n",
              "<table border=\"1\" class=\"dataframe\">\n",
              "  <thead>\n",
              "    <tr style=\"text-align: right;\">\n",
              "      <th></th>\n",
              "      <th>0</th>\n",
              "    </tr>\n",
              "  </thead>\n",
              "  <tbody>\n",
              "    <tr>\n",
              "      <th>Unnamed: 0.1</th>\n",
              "      <td>0</td>\n",
              "    </tr>\n",
              "    <tr>\n",
              "      <th>Unnamed: 0</th>\n",
              "      <td>0</td>\n",
              "    </tr>\n",
              "    <tr>\n",
              "      <th>asin</th>\n",
              "      <td>0</td>\n",
              "    </tr>\n",
              "    <tr>\n",
              "      <th>helpful</th>\n",
              "      <td>0</td>\n",
              "    </tr>\n",
              "    <tr>\n",
              "      <th>rating</th>\n",
              "      <td>0</td>\n",
              "    </tr>\n",
              "    <tr>\n",
              "      <th>reviewText</th>\n",
              "      <td>0</td>\n",
              "    </tr>\n",
              "    <tr>\n",
              "      <th>reviewTime</th>\n",
              "      <td>0</td>\n",
              "    </tr>\n",
              "    <tr>\n",
              "      <th>reviewerID</th>\n",
              "      <td>0</td>\n",
              "    </tr>\n",
              "    <tr>\n",
              "      <th>reviewerName</th>\n",
              "      <td>38</td>\n",
              "    </tr>\n",
              "    <tr>\n",
              "      <th>summary</th>\n",
              "      <td>2</td>\n",
              "    </tr>\n",
              "    <tr>\n",
              "      <th>unixReviewTime</th>\n",
              "      <td>0</td>\n",
              "    </tr>\n",
              "  </tbody>\n",
              "</table>\n",
              "</div><br><label><b>dtype:</b> int64</label>"
            ]
          },
          "metadata": {},
          "execution_count": 46
        }
      ]
    },
    {
      "cell_type": "markdown",
      "source": [
        "# Data Preprocessing"
      ],
      "metadata": {
        "id": "3e_SHcpnuuW4"
      }
    },
    {
      "cell_type": "markdown",
      "source": [
        "## Create binary sentiment from rating"
      ],
      "metadata": {
        "id": "Pn6XezJuu1_I"
      }
    },
    {
      "cell_type": "code",
      "source": [
        "def rating_to_binary_sentiment(r):\n",
        "    return \"positive\" if r >= 4 else \"negative\"\n",
        "\n",
        "# Optional (recommended): drop neutral rating=3\n",
        "df = df[df[\"rating\"] != 3].copy()\n",
        "\n",
        "df[\"sentiment\"] = df[\"rating\"].apply(rating_to_binary_sentiment)\n",
        "\n",
        "print(df[\"sentiment\"].value_counts())\n",
        "print((df[\"sentiment\"].value_counts(normalize=True)*100).round(2))\n"
      ],
      "metadata": {
        "colab": {
          "base_uri": "https://localhost:8080/"
        },
        "id": "qXNLxcPhu4E6",
        "outputId": "f021b60a-66c2-4c86-a7ad-e54ab3b58c7b"
      },
      "execution_count": 47,
      "outputs": [
        {
          "output_type": "stream",
          "name": "stdout",
          "text": [
            "sentiment\n",
            "positive    6000\n",
            "negative    4000\n",
            "Name: count, dtype: int64\n",
            "sentiment\n",
            "positive    60.0\n",
            "negative    40.0\n",
            "Name: proportion, dtype: float64\n"
          ]
        }
      ]
    },
    {
      "cell_type": "markdown",
      "source": [
        "## Combine text fields"
      ],
      "metadata": {
        "id": "_fulCDIYu7fH"
      }
    },
    {
      "cell_type": "code",
      "source": [
        "df[\"text\"] = df[\"summary\"].fillna(\"\") + \" \" + df[\"reviewText\"].fillna(\"\")\n",
        "df = df.dropna(subset=[\"text\", \"sentiment\"]).copy()\n",
        "df[[\"text\", \"sentiment\"]].head()\n"
      ],
      "metadata": {
        "colab": {
          "base_uri": "https://localhost:8080/",
          "height": 206
        },
        "id": "6ysKqE7Ou-2l",
        "outputId": "8245c79d-7d65-477f-b918-3672e1e3c977"
      },
      "execution_count": 48,
      "outputs": [
        {
          "output_type": "execute_result",
          "data": {
            "text/plain": [
              "                                                text sentiment\n",
              "1  Terrific menage scenes! Great short read.  I d...  positive\n",
              "4  Book I did not expect this type of book to be ...  positive\n",
              "5  A story of a little girl with big dreams. Aisl...  positive\n",
              "6  This story has potential but ultimately disapp...  negative\n",
              "7  Good thriller I got this because I like collab...  positive"
            ],
            "text/html": [
              "\n",
              "  <div id=\"df-83fdcaf7-8ef4-4d22-8909-9bdcb0d96f4d\" class=\"colab-df-container\">\n",
              "    <div>\n",
              "<style scoped>\n",
              "    .dataframe tbody tr th:only-of-type {\n",
              "        vertical-align: middle;\n",
              "    }\n",
              "\n",
              "    .dataframe tbody tr th {\n",
              "        vertical-align: top;\n",
              "    }\n",
              "\n",
              "    .dataframe thead th {\n",
              "        text-align: right;\n",
              "    }\n",
              "</style>\n",
              "<table border=\"1\" class=\"dataframe\">\n",
              "  <thead>\n",
              "    <tr style=\"text-align: right;\">\n",
              "      <th></th>\n",
              "      <th>text</th>\n",
              "      <th>sentiment</th>\n",
              "    </tr>\n",
              "  </thead>\n",
              "  <tbody>\n",
              "    <tr>\n",
              "      <th>1</th>\n",
              "      <td>Terrific menage scenes! Great short read.  I d...</td>\n",
              "      <td>positive</td>\n",
              "    </tr>\n",
              "    <tr>\n",
              "      <th>4</th>\n",
              "      <td>Book I did not expect this type of book to be ...</td>\n",
              "      <td>positive</td>\n",
              "    </tr>\n",
              "    <tr>\n",
              "      <th>5</th>\n",
              "      <td>A story of a little girl with big dreams. Aisl...</td>\n",
              "      <td>positive</td>\n",
              "    </tr>\n",
              "    <tr>\n",
              "      <th>6</th>\n",
              "      <td>This story has potential but ultimately disapp...</td>\n",
              "      <td>negative</td>\n",
              "    </tr>\n",
              "    <tr>\n",
              "      <th>7</th>\n",
              "      <td>Good thriller I got this because I like collab...</td>\n",
              "      <td>positive</td>\n",
              "    </tr>\n",
              "  </tbody>\n",
              "</table>\n",
              "</div>\n",
              "    <div class=\"colab-df-buttons\">\n",
              "\n",
              "  <div class=\"colab-df-container\">\n",
              "    <button class=\"colab-df-convert\" onclick=\"convertToInteractive('df-83fdcaf7-8ef4-4d22-8909-9bdcb0d96f4d')\"\n",
              "            title=\"Convert this dataframe to an interactive table.\"\n",
              "            style=\"display:none;\">\n",
              "\n",
              "  <svg xmlns=\"http://www.w3.org/2000/svg\" height=\"24px\" viewBox=\"0 -960 960 960\">\n",
              "    <path d=\"M120-120v-720h720v720H120Zm60-500h600v-160H180v160Zm220 220h160v-160H400v160Zm0 220h160v-160H400v160ZM180-400h160v-160H180v160Zm440 0h160v-160H620v160ZM180-180h160v-160H180v160Zm440 0h160v-160H620v160Z\"/>\n",
              "  </svg>\n",
              "    </button>\n",
              "\n",
              "  <style>\n",
              "    .colab-df-container {\n",
              "      display:flex;\n",
              "      gap: 12px;\n",
              "    }\n",
              "\n",
              "    .colab-df-convert {\n",
              "      background-color: #E8F0FE;\n",
              "      border: none;\n",
              "      border-radius: 50%;\n",
              "      cursor: pointer;\n",
              "      display: none;\n",
              "      fill: #1967D2;\n",
              "      height: 32px;\n",
              "      padding: 0 0 0 0;\n",
              "      width: 32px;\n",
              "    }\n",
              "\n",
              "    .colab-df-convert:hover {\n",
              "      background-color: #E2EBFA;\n",
              "      box-shadow: 0px 1px 2px rgba(60, 64, 67, 0.3), 0px 1px 3px 1px rgba(60, 64, 67, 0.15);\n",
              "      fill: #174EA6;\n",
              "    }\n",
              "\n",
              "    .colab-df-buttons div {\n",
              "      margin-bottom: 4px;\n",
              "    }\n",
              "\n",
              "    [theme=dark] .colab-df-convert {\n",
              "      background-color: #3B4455;\n",
              "      fill: #D2E3FC;\n",
              "    }\n",
              "\n",
              "    [theme=dark] .colab-df-convert:hover {\n",
              "      background-color: #434B5C;\n",
              "      box-shadow: 0px 1px 3px 1px rgba(0, 0, 0, 0.15);\n",
              "      filter: drop-shadow(0px 1px 2px rgba(0, 0, 0, 0.3));\n",
              "      fill: #FFFFFF;\n",
              "    }\n",
              "  </style>\n",
              "\n",
              "    <script>\n",
              "      const buttonEl =\n",
              "        document.querySelector('#df-83fdcaf7-8ef4-4d22-8909-9bdcb0d96f4d button.colab-df-convert');\n",
              "      buttonEl.style.display =\n",
              "        google.colab.kernel.accessAllowed ? 'block' : 'none';\n",
              "\n",
              "      async function convertToInteractive(key) {\n",
              "        const element = document.querySelector('#df-83fdcaf7-8ef4-4d22-8909-9bdcb0d96f4d');\n",
              "        const dataTable =\n",
              "          await google.colab.kernel.invokeFunction('convertToInteractive',\n",
              "                                                    [key], {});\n",
              "        if (!dataTable) return;\n",
              "\n",
              "        const docLinkHtml = 'Like what you see? Visit the ' +\n",
              "          '<a target=\"_blank\" href=https://colab.research.google.com/notebooks/data_table.ipynb>data table notebook</a>'\n",
              "          + ' to learn more about interactive tables.';\n",
              "        element.innerHTML = '';\n",
              "        dataTable['output_type'] = 'display_data';\n",
              "        await google.colab.output.renderOutput(dataTable, element);\n",
              "        const docLink = document.createElement('div');\n",
              "        docLink.innerHTML = docLinkHtml;\n",
              "        element.appendChild(docLink);\n",
              "      }\n",
              "    </script>\n",
              "  </div>\n",
              "\n",
              "\n",
              "    <div id=\"df-c572fc63-66af-4819-b0a9-606f0b0233c2\">\n",
              "      <button class=\"colab-df-quickchart\" onclick=\"quickchart('df-c572fc63-66af-4819-b0a9-606f0b0233c2')\"\n",
              "                title=\"Suggest charts\"\n",
              "                style=\"display:none;\">\n",
              "\n",
              "<svg xmlns=\"http://www.w3.org/2000/svg\" height=\"24px\"viewBox=\"0 0 24 24\"\n",
              "     width=\"24px\">\n",
              "    <g>\n",
              "        <path d=\"M19 3H5c-1.1 0-2 .9-2 2v14c0 1.1.9 2 2 2h14c1.1 0 2-.9 2-2V5c0-1.1-.9-2-2-2zM9 17H7v-7h2v7zm4 0h-2V7h2v10zm4 0h-2v-4h2v4z\"/>\n",
              "    </g>\n",
              "</svg>\n",
              "      </button>\n",
              "\n",
              "<style>\n",
              "  .colab-df-quickchart {\n",
              "      --bg-color: #E8F0FE;\n",
              "      --fill-color: #1967D2;\n",
              "      --hover-bg-color: #E2EBFA;\n",
              "      --hover-fill-color: #174EA6;\n",
              "      --disabled-fill-color: #AAA;\n",
              "      --disabled-bg-color: #DDD;\n",
              "  }\n",
              "\n",
              "  [theme=dark] .colab-df-quickchart {\n",
              "      --bg-color: #3B4455;\n",
              "      --fill-color: #D2E3FC;\n",
              "      --hover-bg-color: #434B5C;\n",
              "      --hover-fill-color: #FFFFFF;\n",
              "      --disabled-bg-color: #3B4455;\n",
              "      --disabled-fill-color: #666;\n",
              "  }\n",
              "\n",
              "  .colab-df-quickchart {\n",
              "    background-color: var(--bg-color);\n",
              "    border: none;\n",
              "    border-radius: 50%;\n",
              "    cursor: pointer;\n",
              "    display: none;\n",
              "    fill: var(--fill-color);\n",
              "    height: 32px;\n",
              "    padding: 0;\n",
              "    width: 32px;\n",
              "  }\n",
              "\n",
              "  .colab-df-quickchart:hover {\n",
              "    background-color: var(--hover-bg-color);\n",
              "    box-shadow: 0 1px 2px rgba(60, 64, 67, 0.3), 0 1px 3px 1px rgba(60, 64, 67, 0.15);\n",
              "    fill: var(--button-hover-fill-color);\n",
              "  }\n",
              "\n",
              "  .colab-df-quickchart-complete:disabled,\n",
              "  .colab-df-quickchart-complete:disabled:hover {\n",
              "    background-color: var(--disabled-bg-color);\n",
              "    fill: var(--disabled-fill-color);\n",
              "    box-shadow: none;\n",
              "  }\n",
              "\n",
              "  .colab-df-spinner {\n",
              "    border: 2px solid var(--fill-color);\n",
              "    border-color: transparent;\n",
              "    border-bottom-color: var(--fill-color);\n",
              "    animation:\n",
              "      spin 1s steps(1) infinite;\n",
              "  }\n",
              "\n",
              "  @keyframes spin {\n",
              "    0% {\n",
              "      border-color: transparent;\n",
              "      border-bottom-color: var(--fill-color);\n",
              "      border-left-color: var(--fill-color);\n",
              "    }\n",
              "    20% {\n",
              "      border-color: transparent;\n",
              "      border-left-color: var(--fill-color);\n",
              "      border-top-color: var(--fill-color);\n",
              "    }\n",
              "    30% {\n",
              "      border-color: transparent;\n",
              "      border-left-color: var(--fill-color);\n",
              "      border-top-color: var(--fill-color);\n",
              "      border-right-color: var(--fill-color);\n",
              "    }\n",
              "    40% {\n",
              "      border-color: transparent;\n",
              "      border-right-color: var(--fill-color);\n",
              "      border-top-color: var(--fill-color);\n",
              "    }\n",
              "    60% {\n",
              "      border-color: transparent;\n",
              "      border-right-color: var(--fill-color);\n",
              "    }\n",
              "    80% {\n",
              "      border-color: transparent;\n",
              "      border-right-color: var(--fill-color);\n",
              "      border-bottom-color: var(--fill-color);\n",
              "    }\n",
              "    90% {\n",
              "      border-color: transparent;\n",
              "      border-bottom-color: var(--fill-color);\n",
              "    }\n",
              "  }\n",
              "</style>\n",
              "\n",
              "      <script>\n",
              "        async function quickchart(key) {\n",
              "          const quickchartButtonEl =\n",
              "            document.querySelector('#' + key + ' button');\n",
              "          quickchartButtonEl.disabled = true;  // To prevent multiple clicks.\n",
              "          quickchartButtonEl.classList.add('colab-df-spinner');\n",
              "          try {\n",
              "            const charts = await google.colab.kernel.invokeFunction(\n",
              "                'suggestCharts', [key], {});\n",
              "          } catch (error) {\n",
              "            console.error('Error during call to suggestCharts:', error);\n",
              "          }\n",
              "          quickchartButtonEl.classList.remove('colab-df-spinner');\n",
              "          quickchartButtonEl.classList.add('colab-df-quickchart-complete');\n",
              "        }\n",
              "        (() => {\n",
              "          let quickchartButtonEl =\n",
              "            document.querySelector('#df-c572fc63-66af-4819-b0a9-606f0b0233c2 button');\n",
              "          quickchartButtonEl.style.display =\n",
              "            google.colab.kernel.accessAllowed ? 'block' : 'none';\n",
              "        })();\n",
              "      </script>\n",
              "    </div>\n",
              "\n",
              "    </div>\n",
              "  </div>\n"
            ],
            "application/vnd.google.colaboratory.intrinsic+json": {
              "type": "dataframe",
              "summary": "{\n  \"name\": \"df[[\\\"text\\\", \\\"sentiment\\\"]]\",\n  \"rows\": 5,\n  \"fields\": [\n    {\n      \"column\": \"text\",\n      \"properties\": {\n        \"dtype\": \"string\",\n        \"num_unique_values\": 5,\n        \"samples\": [\n          \"Book I did not expect this type of book to be in library was pleased to find it price was right\",\n          \"Good thriller I got this because I like collaborated short stories. Alot of times when two good writers put their heads together, the results turn out well. This is the case with this short story. The writers take an age old lesson and turn it into a good read. It begins with, as they call it, Crazy #1 who is picking up a hitchhiker and from there it gets graphic and a little much for my taste. Then it cuts to Nutcase #2 who is hitchhiking. They inevitably get together and the results are suspenseful. The ending I felt was well deserved on both accounts.I also watched the video of the two authors on how they decided to break this short story up and the idea was cool. One wrote their side for scenario 1 and the other did scenario 2 without talking with each other about how tier side was going. Then, when it came for them to bring the two pieces together, they made them fit perfectly. I think it took great talent for two authors to take their two seperate stories and merge them as well as they did.The story does have some pretty graphic details which is forwarned, but if you don't mind a little detail for a short story, then definitely pick this one up.\",\n          \"A story of a little girl with big dreams. Aislinn is a little girl with big dreams. After the death of her older brother, she decides to follow in his footsteps and become a lady knight. Her quest for knighthood brings many challenges and the temptation of forbidden love. Aislinn learns that being a knight means putting the Kingdom in front of personal concerns and helping those that cannot help themselves. In a journey is fraught with danger and filled with adventure, Aislinn is forced to grow up fast. She must stay strong and develop the skills necessary to realize her lifelong dream.With sword fights, passionate love, mythical creatures, and courtly games, Woman of Honor is my kind of book. I love the idea of incorporating real history in fantasy, and Ms. Zoltack's book is based on the real life story of a group of female knights. Blending history with fiction, her writing is full of plot and adventure and her characters are strong and believable. Most of all, I grew to love all of them and cared about their hardships and successes.Aislinn is quite the main protagonist. She's tenacious and bold, beautiful and strong. The romance that blooms between her and the prince is well developed after years of solid friendship and teasing. I enjoyed reading about their secret courtship and had no idea how their romance would turn out! Ms. Zoltack has a few twists in store that will shock and startle as well as please.In conclusion, I thoroughly recommend this book for everyone that enjoys fantasy, romance and adventure! I will be eagerly awaiting the sequel, Knight of Glory.\"\n        ],\n        \"semantic_type\": \"\",\n        \"description\": \"\"\n      }\n    },\n    {\n      \"column\": \"sentiment\",\n      \"properties\": {\n        \"dtype\": \"category\",\n        \"num_unique_values\": 2,\n        \"samples\": [\n          \"negative\",\n          \"positive\"\n        ],\n        \"semantic_type\": \"\",\n        \"description\": \"\"\n      }\n    }\n  ]\n}"
            }
          },
          "metadata": {},
          "execution_count": 48
        }
      ]
    },
    {
      "cell_type": "markdown",
      "source": [
        "## Clean text"
      ],
      "metadata": {
        "id": "Y5rU1UOQvCet"
      }
    },
    {
      "cell_type": "code",
      "source": [
        "stop_words = set(stopwords.words(\"english\"))\n",
        "\n",
        "def preprocess_text(text):\n",
        "    text = text.lower()\n",
        "    text = re.sub(r\"http\\S+|www\\S+\", \"\", text)          # remove urls\n",
        "    text = re.sub(r\"<.*?>\", \"\", text)                  # remove html\n",
        "    text = re.sub(r\"[^a-zA-Z\\s]\", \" \", text)           # keep letters only\n",
        "    tokens = word_tokenize(text)\n",
        "    tokens = [w for w in tokens if w not in stop_words]\n",
        "    return \" \".join(tokens)\n",
        "\n",
        "df[\"clean_text\"] = df[\"text\"].apply(preprocess_text)\n",
        "df = df.dropna(subset=[\"clean_text\"]).copy()\n",
        "df[\"clean_text\"].head()\n"
      ],
      "metadata": {
        "colab": {
          "base_uri": "https://localhost:8080/",
          "height": 241
        },
        "id": "-HHbW6u-vF5q",
        "outputId": "ffea48ae-9760-4f35-d0e2-5dca9868298d"
      },
      "execution_count": 49,
      "outputs": [
        {
          "output_type": "execute_result",
          "data": {
            "text/plain": [
              "1    terrific menage scenes great short read want p...\n",
              "4    book expect type book library pleased find pri...\n",
              "5    story little girl big dreams aislinn little gi...\n",
              "6    story potential ultimately disappoints makings...\n",
              "7    good thriller got like collaborated short stor...\n",
              "Name: clean_text, dtype: object"
            ],
            "text/html": [
              "<div>\n",
              "<style scoped>\n",
              "    .dataframe tbody tr th:only-of-type {\n",
              "        vertical-align: middle;\n",
              "    }\n",
              "\n",
              "    .dataframe tbody tr th {\n",
              "        vertical-align: top;\n",
              "    }\n",
              "\n",
              "    .dataframe thead th {\n",
              "        text-align: right;\n",
              "    }\n",
              "</style>\n",
              "<table border=\"1\" class=\"dataframe\">\n",
              "  <thead>\n",
              "    <tr style=\"text-align: right;\">\n",
              "      <th></th>\n",
              "      <th>clean_text</th>\n",
              "    </tr>\n",
              "  </thead>\n",
              "  <tbody>\n",
              "    <tr>\n",
              "      <th>1</th>\n",
              "      <td>terrific menage scenes great short read want p...</td>\n",
              "    </tr>\n",
              "    <tr>\n",
              "      <th>4</th>\n",
              "      <td>book expect type book library pleased find pri...</td>\n",
              "    </tr>\n",
              "    <tr>\n",
              "      <th>5</th>\n",
              "      <td>story little girl big dreams aislinn little gi...</td>\n",
              "    </tr>\n",
              "    <tr>\n",
              "      <th>6</th>\n",
              "      <td>story potential ultimately disappoints makings...</td>\n",
              "    </tr>\n",
              "    <tr>\n",
              "      <th>7</th>\n",
              "      <td>good thriller got like collaborated short stor...</td>\n",
              "    </tr>\n",
              "  </tbody>\n",
              "</table>\n",
              "</div><br><label><b>dtype:</b> object</label>"
            ]
          },
          "metadata": {},
          "execution_count": 49
        }
      ]
    },
    {
      "cell_type": "markdown",
      "source": [
        "# Split the Dataset"
      ],
      "metadata": {
        "id": "yk9t4oE-vJX8"
      }
    },
    {
      "cell_type": "code",
      "source": [
        "X = df[\"clean_text\"]\n",
        "y = df[\"sentiment\"]\n",
        "\n",
        "X_train, X_test, y_train, y_test = train_test_split(\n",
        "    X, y,\n",
        "    test_size=0.2,\n",
        "    random_state=42,\n",
        "    stratify=y\n",
        ")\n",
        "\n",
        "print(\"Train:\", X_train.shape, \"Test:\", X_test.shape)\n"
      ],
      "metadata": {
        "colab": {
          "base_uri": "https://localhost:8080/"
        },
        "id": "5Q8tmux-vQ1e",
        "outputId": "791c88f7-54e9-47a2-d33a-163e0e154b0e"
      },
      "execution_count": 50,
      "outputs": [
        {
          "output_type": "stream",
          "name": "stdout",
          "text": [
            "Train: (8000,) Test: (2000,)\n"
          ]
        }
      ]
    },
    {
      "cell_type": "markdown",
      "source": [
        "# Feature Representation"
      ],
      "metadata": {
        "id": "3tkoFIY1vaL_"
      }
    },
    {
      "cell_type": "markdown",
      "source": [
        "## Bag of Words (CountVectorizer)"
      ],
      "metadata": {
        "id": "K1SB96jovfLD"
      }
    },
    {
      "cell_type": "code",
      "source": [
        "bow = CountVectorizer(max_features=30000)  # cap features to speed up\n",
        "X_train_bow = bow.fit_transform(X_train)\n",
        "X_test_bow  = bow.transform(X_test)\n",
        "\n",
        "print(X_train_bow.shape, X_test_bow.shape)\n"
      ],
      "metadata": {
        "colab": {
          "base_uri": "https://localhost:8080/"
        },
        "id": "m4zEnmtVvcES",
        "outputId": "28d758c4-5318-46a3-a95b-164acdb4b2e7"
      },
      "execution_count": 51,
      "outputs": [
        {
          "output_type": "stream",
          "name": "stdout",
          "text": [
            "(8000, 25288) (2000, 25288)\n"
          ]
        }
      ]
    },
    {
      "cell_type": "markdown",
      "source": [
        "## TF-IDF (Unigrams + Bigrams)"
      ],
      "metadata": {
        "id": "2F4wttgWvkZ9"
      }
    },
    {
      "cell_type": "code",
      "source": [
        "tfidf = TfidfVectorizer(ngram_range=(1,2), max_features=50000)\n",
        "X_train_tfidf = tfidf.fit_transform(X_train)\n",
        "X_test_tfidf  = tfidf.transform(X_test)\n",
        "\n",
        "print(X_train_tfidf.shape, X_test_tfidf.shape)\n"
      ],
      "metadata": {
        "colab": {
          "base_uri": "https://localhost:8080/"
        },
        "id": "YyxR4YL7vniD",
        "outputId": "c6b0bbfb-e3eb-48da-feee-fa1c8f6c854c"
      },
      "execution_count": 52,
      "outputs": [
        {
          "output_type": "stream",
          "name": "stdout",
          "text": [
            "(8000, 50000) (2000, 50000)\n"
          ]
        }
      ]
    },
    {
      "cell_type": "markdown",
      "source": [
        "# Evaluation Helper"
      ],
      "metadata": {
        "id": "UIMOWkt8z1Sn"
      }
    },
    {
      "cell_type": "code",
      "source": [
        "def evaluate_model(model_name, y_true, y_pred):\n",
        "    acc = accuracy_score(y_true, y_pred)\n",
        "    prec = precision_score(y_true, y_pred, average=\"weighted\")\n",
        "    rec = recall_score(y_true, y_pred, average=\"weighted\")\n",
        "    f1 = f1_score(y_true, y_pred, average=\"weighted\")\n",
        "    cm = confusion_matrix(y_true, y_pred)\n",
        "\n",
        "    print(\"Model:\", model_name)\n",
        "    print(f\"Accuracy : {acc:.4f}\")\n",
        "    print(f\"Precision: {prec:.4f}\")\n",
        "    print(f\"Recall   : {rec:.4f}\")\n",
        "    print(f\"F1-score : {f1:.4f}\")\n",
        "    print(\"\\nClassification Report:\\n\", classification_report(y_true, y_pred))\n",
        "\n",
        "    plt.figure(figsize=(4,4))\n",
        "    sns.heatmap(cm, annot=True, fmt=\"d\", cbar=False)\n",
        "    plt.title(f\"Confusion Matrix — {model_name}\")\n",
        "    plt.xlabel(\"Predicted\")\n",
        "    plt.ylabel(\"True\")\n",
        "    plt.show()\n",
        "\n",
        "    return {\"accuracy\": acc, \"precision\": prec, \"recall\": rec, \"f1\": f1}\n"
      ],
      "metadata": {
        "id": "0f4cpLnHz4bz"
      },
      "execution_count": 59,
      "outputs": []
    },
    {
      "cell_type": "markdown",
      "source": [
        "# Train & Evaluate Models"
      ],
      "metadata": {
        "id": "DYzurMvMwJhZ"
      }
    },
    {
      "cell_type": "markdown",
      "source": [
        "## Random Forest + GridSearch (using BoW)"
      ],
      "metadata": {
        "id": "_O6BZ_yvwP3r"
      }
    },
    {
      "cell_type": "code",
      "source": [
        "rf = RandomForestClassifier(random_state=42)\n",
        "\n",
        "param_grid = {\n",
        "    \"n_estimators\": [100, 200],\n",
        "    \"max_depth\": [None, 20]\n",
        "}\n",
        "\n",
        "grid = GridSearchCV(\n",
        "    estimator=rf,\n",
        "    param_grid=param_grid,\n",
        "    cv=3,                  # use 3 for speed (5 is slower)\n",
        "    scoring=\"accuracy\",\n",
        "    n_jobs=-1,\n",
        "    verbose=1\n",
        ")\n",
        "\n",
        "grid.fit(X_train_bow, y_train)\n",
        "best_rf = grid.best_estimator_\n",
        "\n",
        "y_pred = best_rf.predict(X_test_bow)\n",
        "evaluate_model(\"RandomForest (BoW)\", y_test, y_pred)\n",
        "\n",
        "print(\"Best Params:\", grid.best_params_)\n"
      ],
      "metadata": {
        "colab": {
          "base_uri": "https://localhost:8080/",
          "height": 722
        },
        "id": "bwwCTgYuwLST",
        "outputId": "02903870-b855-4806-d275-55f0de6b3f40"
      },
      "execution_count": 54,
      "outputs": [
        {
          "output_type": "stream",
          "name": "stdout",
          "text": [
            "Fitting 3 folds for each of 4 candidates, totalling 12 fits\n",
            "Model: RandomForest (BoW)\n",
            "Accuracy : 0.8835\n",
            "Precision: 0.8850\n",
            "Recall   : 0.8835\n",
            "F1-score : 0.8820\n",
            "\n",
            "Classification Report:\n",
            "               precision    recall  f1-score   support\n",
            "\n",
            "    negative       0.90      0.79      0.84       800\n",
            "    positive       0.87      0.94      0.91      1200\n",
            "\n",
            "    accuracy                           0.88      2000\n",
            "   macro avg       0.89      0.87      0.88      2000\n",
            "weighted avg       0.88      0.88      0.88      2000\n",
            "\n"
          ]
        },
        {
          "output_type": "display_data",
          "data": {
            "text/plain": [
              "<Figure size 400x400 with 1 Axes>"
            ],
            "image/png": "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\n"
          },
          "metadata": {}
        },
        {
          "output_type": "stream",
          "name": "stdout",
          "text": [
            "Best Params: {'max_depth': None, 'n_estimators': 200}\n"
          ]
        }
      ]
    },
    {
      "cell_type": "markdown",
      "source": [
        "## DecisionTree"
      ],
      "metadata": {
        "id": "HwyV8WMnxgov"
      }
    },
    {
      "cell_type": "code",
      "source": [
        "dt = DecisionTreeClassifier(random_state=42)\n",
        "\n",
        "param_grid = {\n",
        "    \"criterion\": [\"gini\", \"entropy\"],\n",
        "    \"max_depth\": [None, 10, 20]\n",
        "}\n",
        "\n",
        "grid = GridSearchCV(\n",
        "    estimator=dt,\n",
        "    param_grid=param_grid,\n",
        "    cv=3,\n",
        "    scoring=\"accuracy\",\n",
        "    n_jobs=-1,\n",
        "    verbose=1\n",
        ")\n",
        "\n",
        "grid.fit(X_train_tfidf, y_train)\n",
        "best_dt = grid.best_estimator_\n",
        "\n",
        "y_pred = best_dt.predict(X_test_tfidf)\n",
        "evaluate_model(\"Decision Tree (TF-IDF)\", y_test, y_pred)\n",
        "\n",
        "print(\"Best Params:\", grid.best_params_)\n"
      ],
      "metadata": {
        "colab": {
          "base_uri": "https://localhost:8080/",
          "height": 722
        },
        "id": "DYEazrKNxTmN",
        "outputId": "4f5c642c-b42b-4356-eb20-289b64d4185a"
      },
      "execution_count": 55,
      "outputs": [
        {
          "output_type": "stream",
          "name": "stdout",
          "text": [
            "Fitting 3 folds for each of 6 candidates, totalling 18 fits\n",
            "Model: Decision Tree (TF-IDF)\n",
            "Accuracy : 0.7640\n",
            "Precision: 0.7628\n",
            "Recall   : 0.7640\n",
            "F1-score : 0.7632\n",
            "\n",
            "Classification Report:\n",
            "               precision    recall  f1-score   support\n",
            "\n",
            "    negative       0.71      0.69      0.70       800\n",
            "    positive       0.80      0.82      0.81      1200\n",
            "\n",
            "    accuracy                           0.76      2000\n",
            "   macro avg       0.75      0.75      0.75      2000\n",
            "weighted avg       0.76      0.76      0.76      2000\n",
            "\n"
          ]
        },
        {
          "output_type": "display_data",
          "data": {
            "text/plain": [
              "<Figure size 400x400 with 1 Axes>"
            ],
            "image/png": "iVBORw0KGgoAAAANSUhEUgAAAYgAAAGJCAYAAACQH6SDAAAAOnRFWHRTb2Z0d2FyZQBNYXRwbG90bGliIHZlcnNpb24zLjEwLjAsIGh0dHBzOi8vbWF0cGxvdGxpYi5vcmcvlHJYcgAAAAlwSFlzAAAPYQAAD2EBqD+naQAALtBJREFUeJzt3XlcFWX///H3AdlkERX3FBdy99bUMkVFckHTwsi807sEU1ssW1xSMhewtM09lxZNI71/3lmpZd3q7ZJalKY3ZmYqrpX7ggoqIMzvD7+cuwMXCAYc0tfz8TiPh+eaa2Y+c5xz3mdmrjnYLMuyBABANi7OLgAAUDIREAAAIwICAGBEQAAAjAgIAIARAQEAMCIgAABGBAQAwIiAAAAYERDZ7Nu3T126dFGZMmVks9m0bNmyQl3+oUOHZLPZtGDBgkJd7l9Zhw4d1KFDB2eXUeLVrFlTUVFRBZpn/PjxstlsRVPQTeDXX3+Vp6envvnmG2eXUqTuvvtuvfjiiwWer0QGxP79+/XEE0+odu3a8vT0lJ+fn4KDgzV9+nRdvny5SNcdGRmpnTt36tVXX1VcXJxatmxZpOsrTlFRUbLZbPLz8zO+jvv27ZPNZpPNZtNbb71V4OUfPXpU48ePV0JCQiFUW7JkBXvWw83NTQEBAWrTpo1eeuklHTlyxNkllhhZ+9n1HgUNu6IQGxurVq1aKTg4WBs2bMhX3VmBu2DBglynjxo16rrrttlseuaZZ+zPb2Qfy6vmhx9+2N5v5MiRmjVrlo4fP16g16dUgXoXg5UrV+qhhx6Sh4eH+vXrp8aNGystLU2bN2/WiBEjtGvXLr377rtFsu7Lly8rPj5eo0ePdviPK0yBgYG6fPmy3NzcimT511OqVCldunRJn3/+uXr37u0wbdGiRfL09NSVK1duaNlHjx5VTEyMatasqWbNmuV7vtWrV9/Q+pyhT58+uvfee5WZmalz585p69atmjZtmqZPn6558+Y5vCkL2549e+TiUrDvdC+//HK+PqwK0xNPPKFOnTrZnx88eFBjx47V448/rnbt2tnb69SpU6x1ZXfq1CktXLhQCxculCQ1aNBAcXFxDn2io6Pl4+Oj0aNH57qc2NhY1apVy6GtcePGN1zXjexjzz77rO68806Htpo1a9r/HR4eLj8/P82ePVuxsbH5L8YqQQ4cOGD5+PhY9evXt44ePZpj+r59+6xp06YV2foPHz5sSbLefPPNIluHM0VGRlre3t5Wly5drJ49e+aYfvvtt1sPPvjgDb8GW7dutSRZH3zwQb76p6SkFHgdznLw4MFcX5dDhw5ZdevWtdzd3a2EhAQnVFey5Xe/SE5OLp6C/s+UKVMsLy8v6+LFi7n2adSokRUSEmKc9sEHH1iSrK1bt97Q+iVZTz/9tP35jexj69evtyRZH3/88XXX98wzz1iBgYFWZmZmvmssUaeY3njjDSUnJ2vevHmqUqVKjulBQUF67rnn7M+vXr2qCRMmqE6dOvLw8FDNmjX10ksvKTU11WG+mjVrqkePHtq8ebPuuusueXp6qnbt2vrwww/tfcaPH6/AwEBJ0ogRI2Sz2ewJHBUV5ZDGf5wn+/ndNWvWqG3btvL395ePj4/q1aunl156yT49t2sQ69atU7t27eTt7S1/f3+Fh4dr9+7dxvUlJiYqKipK/v7+KlOmjPr3769Lly7l/sJm07dvX3311VdKSkqyt23dulX79u1T3759c/Q/e/ashg8friZNmsjHx0d+fn7q1q2bduzYYe+zYcMG+zeY/v372w9zs7azQ4cOaty4sbZt26b27durdOnS9tcl+zWIyMhIeXp65tj+sLAwlS1bVkePHs33thaHwMBALViwQGlpaXrjjTccpiUlJen5559X9erV5eHhoaCgIL3++uvKzMx06JeZmanp06erSZMm8vT0VIUKFdS1a1f98MMP9j7Zr0Gkp6crJiZGt99+uzw9PVW+fHm1bdtWa9assfcx7aOF+b65UVmnZ77++msNHjxYFStW1G233Waf/tVXX9nfD76+vurevbt27dqVYzm//PKLevXqpXLlysnT01MtW7bUihUr8lXDsmXL1KpVK/n4+Pzp7Slqee1j+dW5c2cdPny4QKeAS1RAfP7556pdu7batGmTr/4DBw7U2LFj1bx5c02dOlUhISGaNGmS8RAsMTFRvXr1UufOnTV58mSVLVtWUVFR9p0uIiJCU6dOlXTtEC8uLk7Tpk0rUP27du1Sjx49lJqaqtjYWE2ePFn333//dS+A/ec//1FYWJhOnjyp8ePHa+jQofr2228VHBysQ4cO5ejfu3dvXbx4UZMmTVLv3r21YMECxcTE5LvOiIgI2Ww2ffrpp/a2xYsXq379+mrevHmO/gcOHNCyZcvUo0cPTZkyRSNGjNDOnTsVEhJi/7Bu0KCB/dD18ccfV1xcnOLi4tS+fXv7cs6cOaNu3bqpWbNmmjZtmkJDQ431TZ8+XRUqVFBkZKQyMjIkSe+8845Wr16tmTNnqmrVqvne1uLSunVr1alTx+HD+dKlSwoJCdFHH32kfv36acaMGQoODlZ0dLSGDh3qMP+AAQPsQfL6669r1KhR8vT01HfffZfrOsePH6+YmBiFhobq7bff1ujRo1WjRg1t3749z1oL833zZw0ePFg///yzxo4daz8VFhcXp+7du8vHx0evv/66xowZo59//llt27Z1eD/s2rVLd999t3bv3q1Ro0Zp8uTJ8vb2Vs+ePfXZZ5/lud709HRt3brVuL8X1Pnz53X69GmHR1Ew7WNZLl68mKOG7F9CWrRoIUkFuyCf72ONInb+/HlLkhUeHp6v/gkJCZYka+DAgQ7tw4cPtyRZ69ats7cFBgZakqyNGzfa206ePGl5eHhYw4YNs7fldogXGRlpBQYG5qhh3Lhx1h9fwqlTp1qSrFOnTuVad9Y6/ni43axZM6tixYrWmTNn7G07duywXFxcrH79+uVY32OPPeawzAceeMAqX758ruv843Z4e3tblmVZvXr1sjp27GhZlmVlZGRYlStXtmJiYoyvwZUrV6yMjIwc2+Hh4WHFxsba2/I6lRASEmJJsubOnWuclv0wftWqVZYk65VXXrGfejSdFisueR3+ZwkPD7ckWefPn7csy7ImTJhgeXt7W3v37nXoN2rUKMvV1dU6cuSIZVmWtW7dOkuS9eyzz+ZY5h9PBwQGBlqRkZH2502bNrW6d++eZ93Z99GieN9cj2m/yDo907ZtW+vq1av29osXL1r+/v7WoEGDHJZx/Phxq0yZMg7tHTt2tJo0aWJduXLF3paZmWm1adPGuv322/OsKTEx0ZJkzZw5M89++TnFZHrkhwpwiilL9n0s6xST6XHw4MEc87u7u1tPPfVUvuqzrBJ0iunChQuSJF9f33z1//LLLyUpxzexYcOGSbp2sfuPGjZs6HCBrEKFCqpXr54OHDhwwzVn5+/vL0lavnx5jvTOzbFjx5SQkKCoqCiVK1fO3v63v/1NnTt3tm/nHz355JMOz9u1a6czZ87YX8P86Nu3rzZs2KDjx49r3bp1On78uPH0kiR5eHjYL45mZGTozJkz9tNn1/u2mn05/fv3z1ffLl266IknnlBsbKwiIiLk6empd955J9/rcoasUxUXL16UJH388cdq166dypYt6/DNrlOnTsrIyNDGjRslSZ988olsNpvGjRuXY5l5DVH19/fXrl27tG/fvnzXWNLeN4MGDZKrq6v9+Zo1a5SUlKQ+ffo4vGaurq5q1aqV1q9fL+naac9169bZj6az+p05c0ZhYWHat2+ffv/991zXe+bMGUlS2bJl//Q2zJo1S2vWrHF4FJXs+1iWsWPH5qihcuXKOebP2hfzq8SMYvLz85OUc8Nzc/jwYbm4uCgoKMihvXLlyvL399fhw4cd2mvUqJFjGWXLltW5c+dusOKc/v73v+v999/XwIEDNWrUKHXs2FERERHq1atXrqNPsuqsV69ejmkNGjTQqlWrlJKSIm9vb3t79m3J2snPnTtnfx2v595775Wvr6+WLFmihIQE3XnnnQoKCjKe0so6Pz579mwdPHjQftpHksqXL5+v9UlStWrV5O7unu/+b731lpYvX66EhAQtXrxYFStWvO48p06dcqivICpUqODwYVVQycnJkv73JWffvn368ccfVaFCBWP/kydPSro2rLtq1aoOXxDyIzY2VuHh4apbt64aN26srl276tFHH9Xf/va3XOcpae+b7KN/ssLunnvuMfbP2r8TExNlWZbGjBmjMWPGGPuePHlS1apVy3P9ViH8Qc277ror1+HwZ8+eVVpamv25l5eXypQpc8Pryr6PZWnSpInDyLHcWJZVoPtiSlRAVK1aVT/99FOB5svvxub2xs/PDpLbOrJ/EHl5eWnjxo1av369Vq5cqX//+99asmSJ7rnnHq1evfpPffj80Z/ZliweHh6KiIjQwoULdeDAAY0fPz7XvhMnTtSYMWP02GOPacKECSpXrpxcXFz0/PPP5/tISbr2+hTEf//7X/uH6M6dO9WnT5/rznPnnXfm+JDLr4MHDxoHI+TXTz/9pIoVK9o/xDIzM9W5c+dcb1CqW7fuDa9Lktq3b6/9+/dr+fLlWr16td5//31NnTpVc+fO1cCBA/OctzjeN/mRfZ/I2p/i4uKM34BLlSrl0G/48OEKCwszLjt7CP5R1hebwvyCaBIREaGvv/7a/jwyMvJP3SSbfR8rqKSkJAUEBOS7f4kJCEnq0aOH3n33XcXHx6t169Z59g0MDFRmZqb27dun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\n"
          },
          "metadata": {}
        },
        {
          "output_type": "stream",
          "name": "stdout",
          "text": [
            "Best Params: {'criterion': 'gini', 'max_depth': None}\n"
          ]
        }
      ]
    },
    {
      "cell_type": "markdown",
      "source": [
        "## LogisticRegression"
      ],
      "metadata": {
        "id": "N-BzCg5XyEZH"
      }
    },
    {
      "cell_type": "code",
      "source": [
        "lr = LogisticRegression(max_iter=2000)\n",
        "\n",
        "param_grid = {\n",
        "    \"solver\": [\"liblinear\", \"lbfgs\"]\n",
        "}\n",
        "\n",
        "grid = GridSearchCV(\n",
        "    estimator=lr,\n",
        "    param_grid=param_grid,\n",
        "    cv=3,\n",
        "    scoring=\"accuracy\",\n",
        "    n_jobs=-1,\n",
        "    verbose=1\n",
        ")\n",
        "\n",
        "grid.fit(X_train_bow, y_train)\n",
        "best_lr = grid.best_estimator_\n",
        "\n",
        "y_pred = best_lr.predict(X_test_bow)\n",
        "evaluate_model(\"Logistic Regression (BoW)\", y_test, y_pred)\n",
        "\n",
        "print(\"Best Params:\", grid.best_params_)\n"
      ],
      "metadata": {
        "colab": {
          "base_uri": "https://localhost:8080/",
          "height": 722
        },
        "collapsed": true,
        "id": "lPtyMCVbyG3M",
        "outputId": "64433507-0495-4001-c406-12a5fbf6dd32"
      },
      "execution_count": 57,
      "outputs": [
        {
          "output_type": "stream",
          "name": "stdout",
          "text": [
            "Fitting 3 folds for each of 2 candidates, totalling 6 fits\n",
            "Model: Logistic Regression (BoW)\n",
            "Accuracy : 0.9040\n",
            "Precision: 0.9040\n",
            "Recall   : 0.9040\n",
            "F1-score : 0.9040\n",
            "\n",
            "Classification Report:\n",
            "               precision    recall  f1-score   support\n",
            "\n",
            "    negative       0.88      0.88      0.88       800\n",
            "    positive       0.92      0.92      0.92      1200\n",
            "\n",
            "    accuracy                           0.90      2000\n",
            "   macro avg       0.90      0.90      0.90      2000\n",
            "weighted avg       0.90      0.90      0.90      2000\n",
            "\n"
          ]
        },
        {
          "output_type": "display_data",
          "data": {
            "text/plain": [
              "<Figure size 400x400 with 1 Axes>"
            ],
            "image/png": "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\n"
          },
          "metadata": {}
        },
        {
          "output_type": "stream",
          "name": "stdout",
          "text": [
            "Best Params: {'solver': 'liblinear'}\n"
          ]
        }
      ]
    },
    {
      "cell_type": "markdown",
      "source": [
        "## SVM"
      ],
      "metadata": {
        "id": "f4_HOJ2sySPW"
      }
    },
    {
      "cell_type": "code",
      "source": [
        "svm = SVC()\n",
        "\n",
        "param_grid = {\n",
        "    \"kernel\": [\"linear\", \"rbf\"]\n",
        "}\n",
        "\n",
        "grid = GridSearchCV(\n",
        "    estimator=svm,\n",
        "    param_grid=param_grid,\n",
        "    cv=3,\n",
        "    scoring=\"accuracy\",\n",
        "    n_jobs=-1,\n",
        "    verbose=1\n",
        ")\n",
        "\n",
        "grid.fit(X_train_tfidf, y_train)\n",
        "best_svm = grid.best_estimator_\n",
        "\n",
        "y_pred = best_svm.predict(X_test_tfidf)\n",
        "evaluate_model(\"SVM (TF-IDF)\", y_test, y_pred)\n",
        "\n",
        "print(\"Best Params:\", grid.best_params_)\n"
      ],
      "metadata": {
        "colab": {
          "base_uri": "https://localhost:8080/",
          "height": 722
        },
        "id": "XNkLoJmzyT1d",
        "outputId": "a8d3eb5b-17ac-46da-fc4d-97afc49255b9"
      },
      "execution_count": 58,
      "outputs": [
        {
          "output_type": "stream",
          "name": "stdout",
          "text": [
            "Fitting 3 folds for each of 2 candidates, totalling 6 fits\n",
            "Model: SVM (TF-IDF)\n",
            "Accuracy : 0.9255\n",
            "Precision: 0.9254\n",
            "Recall   : 0.9255\n",
            "F1-score : 0.9254\n",
            "\n",
            "Classification Report:\n",
            "               precision    recall  f1-score   support\n",
            "\n",
            "    negative       0.91      0.90      0.91       800\n",
            "    positive       0.93      0.94      0.94      1200\n",
            "\n",
            "    accuracy                           0.93      2000\n",
            "   macro avg       0.92      0.92      0.92      2000\n",
            "weighted avg       0.93      0.93      0.93      2000\n",
            "\n"
          ]
        },
        {
          "output_type": "display_data",
          "data": {
            "text/plain": [
              "<Figure size 400x400 with 1 Axes>"
            ],
            "image/png": "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\n"
          },
          "metadata": {}
        },
        {
          "output_type": "stream",
          "name": "stdout",
          "text": [
            "Best Params: {'kernel': 'linear'}\n"
          ]
        }
      ]
    }
  ]
}