{
 "cells": [
  {
   "cell_type": "code",
   "execution_count": 110,
   "id": "cc858fe4-f063-446a-a78a-f55a0cbc1dd4",
   "metadata": {},
   "outputs": [],
   "source": [
    "import pandas as pd\n",
    "import numpy as np\n",
    "import matplotlib.pyplot as plt\n",
    "import seaborn as sns\n",
    "import joblib\n",
    "\n",
    "import re\n",
    "import nltk\n",
    "from nltk.corpus import stopwords\n",
    "from wordcloud import WordCloud, STOPWORDS\n",
    "from sklearn.feature_extraction.text import TfidfVectorizer\n",
    "from nltk.tokenize import RegexpTokenizer\n",
    "from scipy.sparse import hstack\n",
    "\n",
    "from imblearn.over_sampling import SMOTE\n",
    "from sklearn.model_selection import train_test_split\n",
    "from sklearn.metrics import accuracy_score, classification_report, confusion_matrix, ConfusionMatrixDisplay\n",
    "from sklearn.naive_bayes import MultinomialNB\n",
    "from sklearn.preprocessing import LabelEncoder\n",
    "from sklearn.utils import resample\n",
    "\n",
    "import Sastrawi\n",
    "from Sastrawi.StopWordRemover.StopWordRemoverFactory import StopWordRemoverFactory\n",
    "from Sastrawi.StopWordRemover.StopWordRemover import StopWordRemover\n",
    "from Sastrawi.Dictionary.ArrayDictionary import ArrayDictionary\n",
    "from Sastrawi.Stemmer.StemmerFactory import StemmerFactory\n",
    "\n",
    "from tqdm import tqdm\n",
    "\n",
    "from wordcloud import WordCloud, STOPWORDS\n",
    "    "
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 111,
   "id": "93e3c933-b421-4b50-95e9-35f8d0c98a5d",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "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>Category</th>\n",
       "      <th>Product Name</th>\n",
       "      <th>Location</th>\n",
       "      <th>Price</th>\n",
       "      <th>Overall Rating</th>\n",
       "      <th>Number Sold</th>\n",
       "      <th>Total Review</th>\n",
       "      <th>Customer Rating</th>\n",
       "      <th>Customer Review</th>\n",
       "      <th>Sentiment</th>\n",
       "      <th>Emotion</th>\n",
       "    </tr>\n",
       "  </thead>\n",
       "  <tbody>\n",
       "    <tr>\n",
       "      <th>0</th>\n",
       "      <td>Computers and Laptops</td>\n",
       "      <td>Wireless Keyboard i8 Mini TouchPad Mouse 2.4G ...</td>\n",
       "      <td>Jakarta Utara</td>\n",
       "      <td>53500</td>\n",
       "      <td>4.9</td>\n",
       "      <td>5449</td>\n",
       "      <td>2369</td>\n",
       "      <td>5</td>\n",
       "      <td>Alhamdulillah berfungsi dengan baik. Packaging...</td>\n",
       "      <td>Positive</td>\n",
       "      <td>Happy</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>1</th>\n",
       "      <td>Computers and Laptops</td>\n",
       "      <td>PAKET LISENSI WINDOWS 10 PRO DAN OFFICE 2019 O...</td>\n",
       "      <td>Kota Tangerang Selatan</td>\n",
       "      <td>72000</td>\n",
       "      <td>4.9</td>\n",
       "      <td>2359</td>\n",
       "      <td>1044</td>\n",
       "      <td>5</td>\n",
       "      <td>barang bagus dan respon cepat, harga bersaing ...</td>\n",
       "      <td>Positive</td>\n",
       "      <td>Happy</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>2</th>\n",
       "      <td>Computers and Laptops</td>\n",
       "      <td>SSD Midasforce 128 Gb - Tanpa Caddy</td>\n",
       "      <td>Jakarta Barat</td>\n",
       "      <td>213000</td>\n",
       "      <td>5.0</td>\n",
       "      <td>12300</td>\n",
       "      <td>3573</td>\n",
       "      <td>5</td>\n",
       "      <td>barang bagus, berfungsi dengan baik, seler ram...</td>\n",
       "      <td>Positive</td>\n",
       "      <td>Happy</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>3</th>\n",
       "      <td>Computers and Laptops</td>\n",
       "      <td>ADAPTOR CHARGER MONITOR LCD LED TV LG merek LG...</td>\n",
       "      <td>Jakarta Timur</td>\n",
       "      <td>55000</td>\n",
       "      <td>4.7</td>\n",
       "      <td>2030</td>\n",
       "      <td>672</td>\n",
       "      <td>5</td>\n",
       "      <td>bagus sesuai harapan penjual nya juga ramah. t...</td>\n",
       "      <td>Positive</td>\n",
       "      <td>Happy</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>4</th>\n",
       "      <td>Computers and Laptops</td>\n",
       "      <td>ADAPTOR CHARGER MONITOR LCD LED TV LG merek LG...</td>\n",
       "      <td>Jakarta Timur</td>\n",
       "      <td>55000</td>\n",
       "      <td>4.7</td>\n",
       "      <td>2030</td>\n",
       "      <td>672</td>\n",
       "      <td>5</td>\n",
       "      <td>Barang Bagus, pengemasan Aman, dapat Berfungsi...</td>\n",
       "      <td>Positive</td>\n",
       "      <td>Happy</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>...</th>\n",
       "      <td>...</td>\n",
       "      <td>...</td>\n",
       "      <td>...</td>\n",
       "      <td>...</td>\n",
       "      <td>...</td>\n",
       "      <td>...</td>\n",
       "      <td>...</td>\n",
       "      <td>...</td>\n",
       "      <td>...</td>\n",
       "      <td>...</td>\n",
       "      <td>...</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>5395</th>\n",
       "      <td>Household</td>\n",
       "      <td>PCK-01 Penjepit Barang / Pickup Tool Ver.1 Ala...</td>\n",
       "      <td>Jakarta Pusat</td>\n",
       "      <td>35000</td>\n",
       "      <td>4.9</td>\n",
       "      <td>1431</td>\n",
       "      <td>562</td>\n",
       "      <td>5</td>\n",
       "      <td>Harga bersaing, barang sesuai pesanan. Saya na...</td>\n",
       "      <td>Positive</td>\n",
       "      <td>Love</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>5396</th>\n",
       "      <td>Household</td>\n",
       "      <td>Ultrasonic Aroma Diffuser Humidifier Colorful ...</td>\n",
       "      <td>Jakarta Utara</td>\n",
       "      <td>99000</td>\n",
       "      <td>4.9</td>\n",
       "      <td>15529</td>\n",
       "      <td>4074</td>\n",
       "      <td>5</td>\n",
       "      <td>Beli ini krn Anak &amp; Istri mau liburan di Jakar...</td>\n",
       "      <td>Positive</td>\n",
       "      <td>Love</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>5397</th>\n",
       "      <td>Household</td>\n",
       "      <td>Ultrasonic Aroma Diffuser Humidifier Colorful ...</td>\n",
       "      <td>Jakarta Utara</td>\n",
       "      <td>99000</td>\n",
       "      <td>4.9</td>\n",
       "      <td>15529</td>\n",
       "      <td>4074</td>\n",
       "      <td>5</td>\n",
       "      <td>pengemasan barang baik, kondisi barang jg utuh...</td>\n",
       "      <td>Positive</td>\n",
       "      <td>Happy</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>5398</th>\n",
       "      <td>Household</td>\n",
       "      <td>Ultrasonic Aroma Diffuser Humidifier Colorful ...</td>\n",
       "      <td>Jakarta Utara</td>\n",
       "      <td>99000</td>\n",
       "      <td>4.9</td>\n",
       "      <td>15529</td>\n",
       "      <td>4074</td>\n",
       "      <td>5</td>\n",
       "      <td>Mungil tapi bekerja dng baik. Dan murahh terja...</td>\n",
       "      <td>Positive</td>\n",
       "      <td>Happy</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>5399</th>\n",
       "      <td>Household</td>\n",
       "      <td>TDS Meter 3 Alat Ukur Hidroponik Air Aquarium ...</td>\n",
       "      <td>Jakarta Utara</td>\n",
       "      <td>14400</td>\n",
       "      <td>4.9</td>\n",
       "      <td>4765</td>\n",
       "      <td>3044</td>\n",
       "      <td>5</td>\n",
       "      <td>Produk sesuai deskripsi, packing aman terlindu...</td>\n",
       "      <td>Positive</td>\n",
       "      <td>Love</td>\n",
       "    </tr>\n",
       "  </tbody>\n",
       "</table>\n",
       "<p>5400 rows × 11 columns</p>\n",
       "</div>"
      ],
      "text/plain": [
       "                   Category  \\\n",
       "0     Computers and Laptops   \n",
       "1     Computers and Laptops   \n",
       "2     Computers and Laptops   \n",
       "3     Computers and Laptops   \n",
       "4     Computers and Laptops   \n",
       "...                     ...   \n",
       "5395              Household   \n",
       "5396              Household   \n",
       "5397              Household   \n",
       "5398              Household   \n",
       "5399              Household   \n",
       "\n",
       "                                           Product Name  \\\n",
       "0     Wireless Keyboard i8 Mini TouchPad Mouse 2.4G ...   \n",
       "1     PAKET LISENSI WINDOWS 10 PRO DAN OFFICE 2019 O...   \n",
       "2                   SSD Midasforce 128 Gb - Tanpa Caddy   \n",
       "3     ADAPTOR CHARGER MONITOR LCD LED TV LG merek LG...   \n",
       "4     ADAPTOR CHARGER MONITOR LCD LED TV LG merek LG...   \n",
       "...                                                 ...   \n",
       "5395  PCK-01 Penjepit Barang / Pickup Tool Ver.1 Ala...   \n",
       "5396  Ultrasonic Aroma Diffuser Humidifier Colorful ...   \n",
       "5397  Ultrasonic Aroma Diffuser Humidifier Colorful ...   \n",
       "5398  Ultrasonic Aroma Diffuser Humidifier Colorful ...   \n",
       "5399  TDS Meter 3 Alat Ukur Hidroponik Air Aquarium ...   \n",
       "\n",
       "                    Location   Price  Overall Rating  Number Sold  \\\n",
       "0              Jakarta Utara   53500             4.9         5449   \n",
       "1     Kota Tangerang Selatan   72000             4.9         2359   \n",
       "2              Jakarta Barat  213000             5.0        12300   \n",
       "3              Jakarta Timur   55000             4.7         2030   \n",
       "4              Jakarta Timur   55000             4.7         2030   \n",
       "...                      ...     ...             ...          ...   \n",
       "5395           Jakarta Pusat   35000             4.9         1431   \n",
       "5396           Jakarta Utara   99000             4.9        15529   \n",
       "5397           Jakarta Utara   99000             4.9        15529   \n",
       "5398           Jakarta Utara   99000             4.9        15529   \n",
       "5399           Jakarta Utara   14400             4.9         4765   \n",
       "\n",
       "      Total Review  Customer Rating  \\\n",
       "0             2369                5   \n",
       "1             1044                5   \n",
       "2             3573                5   \n",
       "3              672                5   \n",
       "4              672                5   \n",
       "...            ...              ...   \n",
       "5395           562                5   \n",
       "5396          4074                5   \n",
       "5397          4074                5   \n",
       "5398          4074                5   \n",
       "5399          3044                5   \n",
       "\n",
       "                                        Customer Review Sentiment Emotion  \n",
       "0     Alhamdulillah berfungsi dengan baik. Packaging...  Positive   Happy  \n",
       "1     barang bagus dan respon cepat, harga bersaing ...  Positive   Happy  \n",
       "2     barang bagus, berfungsi dengan baik, seler ram...  Positive   Happy  \n",
       "3     bagus sesuai harapan penjual nya juga ramah. t...  Positive   Happy  \n",
       "4     Barang Bagus, pengemasan Aman, dapat Berfungsi...  Positive   Happy  \n",
       "...                                                 ...       ...     ...  \n",
       "5395  Harga bersaing, barang sesuai pesanan. Saya na...  Positive    Love  \n",
       "5396  Beli ini krn Anak & Istri mau liburan di Jakar...  Positive    Love  \n",
       "5397  pengemasan barang baik, kondisi barang jg utuh...  Positive   Happy  \n",
       "5398  Mungil tapi bekerja dng baik. Dan murahh terja...  Positive   Happy  \n",
       "5399  Produk sesuai deskripsi, packing aman terlindu...  Positive    Love  \n",
       "\n",
       "[5400 rows x 11 columns]"
      ]
     },
     "execution_count": 111,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "data = pd.read_csv(\"PRDECT-ID Dataset.csv\")\n",
    "data"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 112,
   "id": "b3270536-4bac-45bd-a282-848cd77a2fe7",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "Category            object\n",
       "Product Name        object\n",
       "Location            object\n",
       "Price                int64\n",
       "Overall Rating     float64\n",
       "Number Sold          int64\n",
       "Total Review         int64\n",
       "Customer Rating      int64\n",
       "Customer Review     object\n",
       "Sentiment           object\n",
       "Emotion             object\n",
       "dtype: object"
      ]
     },
     "execution_count": 112,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "data.dtypes"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 113,
   "id": "4ad4a2e7-5b25-42bf-8514-3d5b5db312a1",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "(5400, 11)"
      ]
     },
     "execution_count": 113,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "data.shape"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 114,
   "id": "44990a0a-4416-43b3-8d43-cdedd213e5a3",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "Category           0\n",
       "Product Name       0\n",
       "Location           0\n",
       "Price              0\n",
       "Overall Rating     0\n",
       "Number Sold        0\n",
       "Total Review       0\n",
       "Customer Rating    0\n",
       "Customer Review    0\n",
       "Sentiment          0\n",
       "Emotion            0\n",
       "dtype: int64"
      ]
     },
     "execution_count": 114,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "data.isnull().sum()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 115,
   "id": "bd89bb8a-bf3c-4dea-a534-634a0fefb685",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "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>Category</th>\n",
       "      <th>Product Name</th>\n",
       "      <th>Location</th>\n",
       "      <th>Price</th>\n",
       "      <th>Overall Rating</th>\n",
       "      <th>Number Sold</th>\n",
       "      <th>Total Review</th>\n",
       "      <th>Customer Rating</th>\n",
       "      <th>Customer Review</th>\n",
       "      <th>Sentiment</th>\n",
       "      <th>Emotion</th>\n",
       "    </tr>\n",
       "  </thead>\n",
       "  <tbody>\n",
       "    <tr>\n",
       "      <th>27</th>\n",
       "      <td>Computers and Laptops</td>\n",
       "      <td>cooling pad laptop tahan 24 jam 6.000 Rpm angi...</td>\n",
       "      <td>Kota Surabaya</td>\n",
       "      <td>385000</td>\n",
       "      <td>5.0</td>\n",
       "      <td>2716</td>\n",
       "      <td>1843</td>\n",
       "      <td>5</td>\n",
       "      <td>mantap kipasnya kenceng, barangnya berkualitas...</td>\n",
       "      <td>Positive</td>\n",
       "      <td>Happy</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>29</th>\n",
       "      <td>Computers and Laptops</td>\n",
       "      <td>cooling pad laptop tahan 24 jam 6.000 Rpm angi...</td>\n",
       "      <td>Kota Surabaya</td>\n",
       "      <td>385000</td>\n",
       "      <td>5.0</td>\n",
       "      <td>2716</td>\n",
       "      <td>1843</td>\n",
       "      <td>5</td>\n",
       "      <td>mantap kipasnya kenceng, barangnya berkualitas...</td>\n",
       "      <td>Positive</td>\n",
       "      <td>Happy</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>70</th>\n",
       "      <td>Computers and Laptops</td>\n",
       "      <td>Usb HUB Vention 4 Port Usb 3.0 2.0 High Speed ...</td>\n",
       "      <td>Jakarta Barat</td>\n",
       "      <td>112000</td>\n",
       "      <td>4.9</td>\n",
       "      <td>14900</td>\n",
       "      <td>7957</td>\n",
       "      <td>1</td>\n",
       "      <td>tidak berfungsi, tapi yaa sudahlah sudah ditam...</td>\n",
       "      <td>Negative</td>\n",
       "      <td>Sadness</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>72</th>\n",
       "      <td>Computers and Laptops</td>\n",
       "      <td>Usb HUB Vention 4 Port Usb 3.0 2.0 High Speed ...</td>\n",
       "      <td>Jakarta Barat</td>\n",
       "      <td>112000</td>\n",
       "      <td>4.9</td>\n",
       "      <td>14900</td>\n",
       "      <td>7957</td>\n",
       "      <td>1</td>\n",
       "      <td>tidak berfungsi, tapi yaa sudahlah sudah ditam...</td>\n",
       "      <td>Negative</td>\n",
       "      <td>Sadness</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>290</th>\n",
       "      <td>Toys and Hobbies</td>\n",
       "      <td>Kereta Thomas Mainan Thomas</td>\n",
       "      <td>Kota Tangerang</td>\n",
       "      <td>59000</td>\n",
       "      <td>4.7</td>\n",
       "      <td>37200</td>\n",
       "      <td>11900</td>\n",
       "      <td>1</td>\n",
       "      <td>saya belom menerima paket ini kenapa sudah sel...</td>\n",
       "      <td>Negative</td>\n",
       "      <td>Anger</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>296</th>\n",
       "      <td>Toys and Hobbies</td>\n",
       "      <td>Kereta Thomas Mainan Thomas</td>\n",
       "      <td>Kota Tangerang</td>\n",
       "      <td>59000</td>\n",
       "      <td>4.7</td>\n",
       "      <td>37200</td>\n",
       "      <td>11900</td>\n",
       "      <td>1</td>\n",
       "      <td>saya belom menerima paket ini kenapa sudah sel...</td>\n",
       "      <td>Negative</td>\n",
       "      <td>Anger</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>720</th>\n",
       "      <td>Office &amp; Stationery</td>\n",
       "      <td>( ISI 30 Roll) Kertas Print Kasir thermal pape...</td>\n",
       "      <td>Kota Tangerang Selatan</td>\n",
       "      <td>58500</td>\n",
       "      <td>4.9</td>\n",
       "      <td>2294</td>\n",
       "      <td>795</td>\n",
       "      <td>5</td>\n",
       "      <td>belanja disini mantap pengiriman cepat dan bar...</td>\n",
       "      <td>Positive</td>\n",
       "      <td>Love</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>723</th>\n",
       "      <td>Office &amp; Stationery</td>\n",
       "      <td>( ISI 30 Roll) Kertas Print Kasir thermal pape...</td>\n",
       "      <td>Kota Tangerang Selatan</td>\n",
       "      <td>58500</td>\n",
       "      <td>4.9</td>\n",
       "      <td>2294</td>\n",
       "      <td>795</td>\n",
       "      <td>5</td>\n",
       "      <td>belanja disini mantap pengiriman cepat dan bar...</td>\n",
       "      <td>Positive</td>\n",
       "      <td>Love</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>835</th>\n",
       "      <td>Automotive</td>\n",
       "      <td>Hayaidesu Keychain Gantungan Kunci Aksesoris V...</td>\n",
       "      <td>Jakarta Selatan</td>\n",
       "      <td>25000</td>\n",
       "      <td>4.9</td>\n",
       "      <td>7884</td>\n",
       "      <td>4399</td>\n",
       "      <td>5</td>\n",
       "      <td>Produk sesuai deskripsi??. Variasi produk bera...</td>\n",
       "      <td>Positive</td>\n",
       "      <td>Happy</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>839</th>\n",
       "      <td>Automotive</td>\n",
       "      <td>Hayaidesu Keychain Gantungan Kunci Aksesoris V...</td>\n",
       "      <td>Jakarta Selatan</td>\n",
       "      <td>25000</td>\n",
       "      <td>4.9</td>\n",
       "      <td>7884</td>\n",
       "      <td>4399</td>\n",
       "      <td>5</td>\n",
       "      <td>Produk sesuai deskripsi??. Variasi produk bera...</td>\n",
       "      <td>Positive</td>\n",
       "      <td>Happy</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>2196</th>\n",
       "      <td>Sport</td>\n",
       "      <td>5-60kg Adjustable Handgrip Hand Grip Alat Fitn...</td>\n",
       "      <td>Jakarta Barat</td>\n",
       "      <td>16200</td>\n",
       "      <td>4.9</td>\n",
       "      <td>6323</td>\n",
       "      <td>768</td>\n",
       "      <td>1</td>\n",
       "      <td>barang tidak ada, komplain tidak direspon...pe...</td>\n",
       "      <td>Negative</td>\n",
       "      <td>Fear</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>2197</th>\n",
       "      <td>Sport</td>\n",
       "      <td>5-60kg Adjustable Handgrip Hand Grip Alat Fitn...</td>\n",
       "      <td>Jakarta Barat</td>\n",
       "      <td>16200</td>\n",
       "      <td>4.9</td>\n",
       "      <td>6323</td>\n",
       "      <td>768</td>\n",
       "      <td>1</td>\n",
       "      <td>barang tidak ada, komplain tidak direspon...pe...</td>\n",
       "      <td>Negative</td>\n",
       "      <td>Fear</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>2198</th>\n",
       "      <td>Sport</td>\n",
       "      <td>5-60kg Adjustable Handgrip Hand Grip Alat Fitn...</td>\n",
       "      <td>Jakarta Barat</td>\n",
       "      <td>16200</td>\n",
       "      <td>4.9</td>\n",
       "      <td>6323</td>\n",
       "      <td>768</td>\n",
       "      <td>1</td>\n",
       "      <td>barang tidak ada, komplain tidak direspon...pe...</td>\n",
       "      <td>Negative</td>\n",
       "      <td>Fear</td>\n",
       "    </tr>\n",
       "  </tbody>\n",
       "</table>\n",
       "</div>"
      ],
      "text/plain": [
       "                   Category  \\\n",
       "27    Computers and Laptops   \n",
       "29    Computers and Laptops   \n",
       "70    Computers and Laptops   \n",
       "72    Computers and Laptops   \n",
       "290        Toys and Hobbies   \n",
       "296        Toys and Hobbies   \n",
       "720     Office & Stationery   \n",
       "723     Office & Stationery   \n",
       "835              Automotive   \n",
       "839              Automotive   \n",
       "2196                  Sport   \n",
       "2197                  Sport   \n",
       "2198                  Sport   \n",
       "\n",
       "                                           Product Name  \\\n",
       "27    cooling pad laptop tahan 24 jam 6.000 Rpm angi...   \n",
       "29    cooling pad laptop tahan 24 jam 6.000 Rpm angi...   \n",
       "70    Usb HUB Vention 4 Port Usb 3.0 2.0 High Speed ...   \n",
       "72    Usb HUB Vention 4 Port Usb 3.0 2.0 High Speed ...   \n",
       "290                         Kereta Thomas Mainan Thomas   \n",
       "296                         Kereta Thomas Mainan Thomas   \n",
       "720   ( ISI 30 Roll) Kertas Print Kasir thermal pape...   \n",
       "723   ( ISI 30 Roll) Kertas Print Kasir thermal pape...   \n",
       "835   Hayaidesu Keychain Gantungan Kunci Aksesoris V...   \n",
       "839   Hayaidesu Keychain Gantungan Kunci Aksesoris V...   \n",
       "2196  5-60kg Adjustable Handgrip Hand Grip Alat Fitn...   \n",
       "2197  5-60kg Adjustable Handgrip Hand Grip Alat Fitn...   \n",
       "2198  5-60kg Adjustable Handgrip Hand Grip Alat Fitn...   \n",
       "\n",
       "                    Location   Price  Overall Rating  Number Sold  \\\n",
       "27             Kota Surabaya  385000             5.0         2716   \n",
       "29             Kota Surabaya  385000             5.0         2716   \n",
       "70             Jakarta Barat  112000             4.9        14900   \n",
       "72             Jakarta Barat  112000             4.9        14900   \n",
       "290           Kota Tangerang   59000             4.7        37200   \n",
       "296           Kota Tangerang   59000             4.7        37200   \n",
       "720   Kota Tangerang Selatan   58500             4.9         2294   \n",
       "723   Kota Tangerang Selatan   58500             4.9         2294   \n",
       "835          Jakarta Selatan   25000             4.9         7884   \n",
       "839          Jakarta Selatan   25000             4.9         7884   \n",
       "2196           Jakarta Barat   16200             4.9         6323   \n",
       "2197           Jakarta Barat   16200             4.9         6323   \n",
       "2198           Jakarta Barat   16200             4.9         6323   \n",
       "\n",
       "      Total Review  Customer Rating  \\\n",
       "27            1843                5   \n",
       "29            1843                5   \n",
       "70            7957                1   \n",
       "72            7957                1   \n",
       "290          11900                1   \n",
       "296          11900                1   \n",
       "720            795                5   \n",
       "723            795                5   \n",
       "835           4399                5   \n",
       "839           4399                5   \n",
       "2196           768                1   \n",
       "2197           768                1   \n",
       "2198           768                1   \n",
       "\n",
       "                                        Customer Review Sentiment  Emotion  \n",
       "27    mantap kipasnya kenceng, barangnya berkualitas...  Positive    Happy  \n",
       "29    mantap kipasnya kenceng, barangnya berkualitas...  Positive    Happy  \n",
       "70    tidak berfungsi, tapi yaa sudahlah sudah ditam...  Negative  Sadness  \n",
       "72    tidak berfungsi, tapi yaa sudahlah sudah ditam...  Negative  Sadness  \n",
       "290   saya belom menerima paket ini kenapa sudah sel...  Negative    Anger  \n",
       "296   saya belom menerima paket ini kenapa sudah sel...  Negative    Anger  \n",
       "720   belanja disini mantap pengiriman cepat dan bar...  Positive     Love  \n",
       "723   belanja disini mantap pengiriman cepat dan bar...  Positive     Love  \n",
       "835   Produk sesuai deskripsi??. Variasi produk bera...  Positive    Happy  \n",
       "839   Produk sesuai deskripsi??. Variasi produk bera...  Positive    Happy  \n",
       "2196  barang tidak ada, komplain tidak direspon...pe...  Negative     Fear  \n",
       "2197  barang tidak ada, komplain tidak direspon...pe...  Negative     Fear  \n",
       "2198  barang tidak ada, komplain tidak direspon...pe...  Negative     Fear  "
      ]
     },
     "execution_count": 115,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "data.duplicated().sum()\n",
    "data[data.duplicated(keep=False)]"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 116,
   "id": "fb4442d6-6220-45ce-a24b-8ab9cb13647b",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "np.int64(0)"
      ]
     },
     "execution_count": 116,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "data = data.drop_duplicates()\n",
    "data[data.duplicated(keep=False)]\n",
    "data.duplicated().sum()\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 117,
   "id": "c64e470b-4a3d-4b53-ac25-913c76e5145c",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "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>Category</th>\n",
       "      <th>Product Name</th>\n",
       "      <th>Location</th>\n",
       "      <th>Customer Review</th>\n",
       "      <th>Sentiment</th>\n",
       "      <th>Emotion</th>\n",
       "    </tr>\n",
       "  </thead>\n",
       "  <tbody>\n",
       "    <tr>\n",
       "      <th>count</th>\n",
       "      <td>5393</td>\n",
       "      <td>5393</td>\n",
       "      <td>5393</td>\n",
       "      <td>5393</td>\n",
       "      <td>5393</td>\n",
       "      <td>5393</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>unique</th>\n",
       "      <td>29</td>\n",
       "      <td>1308</td>\n",
       "      <td>61</td>\n",
       "      <td>5305</td>\n",
       "      <td>2</td>\n",
       "      <td>5</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>top</th>\n",
       "      <td>Food and Drink</td>\n",
       "      <td>Minigold Black Series Logam Mulia Koin Emas Mi...</td>\n",
       "      <td>Jakarta Barat</td>\n",
       "      <td>Kualitas Produk Bagus.</td>\n",
       "      <td>Negative</td>\n",
       "      <td>Happy</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>freq</th>\n",
       "      <td>200</td>\n",
       "      <td>25</td>\n",
       "      <td>1290</td>\n",
       "      <td>4</td>\n",
       "      <td>2817</td>\n",
       "      <td>1768</td>\n",
       "    </tr>\n",
       "  </tbody>\n",
       "</table>\n",
       "</div>"
      ],
      "text/plain": [
       "              Category                                       Product Name  \\\n",
       "count             5393                                               5393   \n",
       "unique              29                                               1308   \n",
       "top     Food and Drink  Minigold Black Series Logam Mulia Koin Emas Mi...   \n",
       "freq               200                                                 25   \n",
       "\n",
       "             Location         Customer Review Sentiment Emotion  \n",
       "count            5393                    5393      5393    5393  \n",
       "unique             61                    5305         2       5  \n",
       "top     Jakarta Barat  Kualitas Produk Bagus.  Negative   Happy  \n",
       "freq             1290                       4      2817    1768  "
      ]
     },
     "execution_count": 117,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "data.describe(include='object')\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 118,
   "id": "52302a0f-e178-485f-8da1-502f2c970a58",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "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>Category</th>\n",
       "      <th>Product Name</th>\n",
       "      <th>Location</th>\n",
       "      <th>Price</th>\n",
       "      <th>Overall Rating</th>\n",
       "      <th>Number Sold</th>\n",
       "      <th>Total Review</th>\n",
       "      <th>Customer Rating</th>\n",
       "      <th>Customer Review</th>\n",
       "      <th>Sentiment</th>\n",
       "      <th>Emotion</th>\n",
       "    </tr>\n",
       "  </thead>\n",
       "  <tbody>\n",
       "    <tr>\n",
       "      <th>0</th>\n",
       "      <td>Computers and Laptops</td>\n",
       "      <td>Wireless Keyboard i8 Mini TouchPad Mouse 2.4G ...</td>\n",
       "      <td>Jakarta Utara</td>\n",
       "      <td>53500</td>\n",
       "      <td>4.9</td>\n",
       "      <td>5449</td>\n",
       "      <td>2369</td>\n",
       "      <td>5</td>\n",
       "      <td>Alhamdulillah berfungsi dengan baik. Packaging...</td>\n",
       "      <td>Positive</td>\n",
       "      <td>Happy</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>1</th>\n",
       "      <td>Computers and Laptops</td>\n",
       "      <td>PAKET LISENSI WINDOWS 10 PRO DAN OFFICE 2019 O...</td>\n",
       "      <td>Kota Tangerang Selatan</td>\n",
       "      <td>72000</td>\n",
       "      <td>4.9</td>\n",
       "      <td>2359</td>\n",
       "      <td>1044</td>\n",
       "      <td>5</td>\n",
       "      <td>barang bagus dan respon cepat, harga bersaing ...</td>\n",
       "      <td>Positive</td>\n",
       "      <td>Happy</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>2</th>\n",
       "      <td>Computers and Laptops</td>\n",
       "      <td>SSD Midasforce 128 Gb - Tanpa Caddy</td>\n",
       "      <td>Jakarta Barat</td>\n",
       "      <td>213000</td>\n",
       "      <td>5.0</td>\n",
       "      <td>12300</td>\n",
       "      <td>3573</td>\n",
       "      <td>5</td>\n",
       "      <td>barang bagus, berfungsi dengan baik, seler ram...</td>\n",
       "      <td>Positive</td>\n",
       "      <td>Happy</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>3</th>\n",
       "      <td>Computers and Laptops</td>\n",
       "      <td>ADAPTOR CHARGER MONITOR LCD LED TV LG merek LG...</td>\n",
       "      <td>Jakarta Timur</td>\n",
       "      <td>55000</td>\n",
       "      <td>4.7</td>\n",
       "      <td>2030</td>\n",
       "      <td>672</td>\n",
       "      <td>5</td>\n",
       "      <td>bagus sesuai harapan penjual nya juga ramah. t...</td>\n",
       "      <td>Positive</td>\n",
       "      <td>Happy</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>4</th>\n",
       "      <td>Computers and Laptops</td>\n",
       "      <td>ADAPTOR CHARGER MONITOR LCD LED TV LG merek LG...</td>\n",
       "      <td>Jakarta Timur</td>\n",
       "      <td>55000</td>\n",
       "      <td>4.7</td>\n",
       "      <td>2030</td>\n",
       "      <td>672</td>\n",
       "      <td>5</td>\n",
       "      <td>Barang Bagus, pengemasan Aman, dapat Berfungsi...</td>\n",
       "      <td>Positive</td>\n",
       "      <td>Happy</td>\n",
       "    </tr>\n",
       "  </tbody>\n",
       "</table>\n",
       "</div>"
      ],
      "text/plain": [
       "                Category                                       Product Name  \\\n",
       "0  Computers and Laptops  Wireless Keyboard i8 Mini TouchPad Mouse 2.4G ...   \n",
       "1  Computers and Laptops  PAKET LISENSI WINDOWS 10 PRO DAN OFFICE 2019 O...   \n",
       "2  Computers and Laptops                SSD Midasforce 128 Gb - Tanpa Caddy   \n",
       "3  Computers and Laptops  ADAPTOR CHARGER MONITOR LCD LED TV LG merek LG...   \n",
       "4  Computers and Laptops  ADAPTOR CHARGER MONITOR LCD LED TV LG merek LG...   \n",
       "\n",
       "                 Location   Price  Overall Rating  Number Sold  Total Review  \\\n",
       "0           Jakarta Utara   53500             4.9         5449          2369   \n",
       "1  Kota Tangerang Selatan   72000             4.9         2359          1044   \n",
       "2           Jakarta Barat  213000             5.0        12300          3573   \n",
       "3           Jakarta Timur   55000             4.7         2030           672   \n",
       "4           Jakarta Timur   55000             4.7         2030           672   \n",
       "\n",
       "   Customer Rating                                    Customer Review  \\\n",
       "0                5  Alhamdulillah berfungsi dengan baik. Packaging...   \n",
       "1                5  barang bagus dan respon cepat, harga bersaing ...   \n",
       "2                5  barang bagus, berfungsi dengan baik, seler ram...   \n",
       "3                5  bagus sesuai harapan penjual nya juga ramah. t...   \n",
       "4                5  Barang Bagus, pengemasan Aman, dapat Berfungsi...   \n",
       "\n",
       "  Sentiment Emotion  \n",
       "0  Positive   Happy  \n",
       "1  Positive   Happy  \n",
       "2  Positive   Happy  \n",
       "3  Positive   Happy  \n",
       "4  Positive   Happy  "
      ]
     },
     "execution_count": 118,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "data.head()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 119,
   "id": "8e5e82a8-67cd-4dbf-ab00-e67e3e33d60b",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "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>Category</th>\n",
       "      <th>Customer Review</th>\n",
       "      <th>Sentiment</th>\n",
       "    </tr>\n",
       "  </thead>\n",
       "  <tbody>\n",
       "    <tr>\n",
       "      <th>0</th>\n",
       "      <td>Computers and Laptops</td>\n",
       "      <td>Alhamdulillah berfungsi dengan baik. Packaging...</td>\n",
       "      <td>Positive</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>1</th>\n",
       "      <td>Computers and Laptops</td>\n",
       "      <td>barang bagus dan respon cepat, harga bersaing ...</td>\n",
       "      <td>Positive</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>2</th>\n",
       "      <td>Computers and Laptops</td>\n",
       "      <td>barang bagus, berfungsi dengan baik, seler ram...</td>\n",
       "      <td>Positive</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>3</th>\n",
       "      <td>Computers and Laptops</td>\n",
       "      <td>bagus sesuai harapan penjual nya juga ramah. t...</td>\n",
       "      <td>Positive</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>4</th>\n",
       "      <td>Computers and Laptops</td>\n",
       "      <td>Barang Bagus, pengemasan Aman, dapat Berfungsi...</td>\n",
       "      <td>Positive</td>\n",
       "    </tr>\n",
       "  </tbody>\n",
       "</table>\n",
       "</div>"
      ],
      "text/plain": [
       "                Category                                    Customer Review  \\\n",
       "0  Computers and Laptops  Alhamdulillah berfungsi dengan baik. Packaging...   \n",
       "1  Computers and Laptops  barang bagus dan respon cepat, harga bersaing ...   \n",
       "2  Computers and Laptops  barang bagus, berfungsi dengan baik, seler ram...   \n",
       "3  Computers and Laptops  bagus sesuai harapan penjual nya juga ramah. t...   \n",
       "4  Computers and Laptops  Barang Bagus, pengemasan Aman, dapat Berfungsi...   \n",
       "\n",
       "  Sentiment  \n",
       "0  Positive  \n",
       "1  Positive  \n",
       "2  Positive  \n",
       "3  Positive  \n",
       "4  Positive  "
      ]
     },
     "execution_count": 119,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "data = data.drop(columns=[\n",
    "    \"Product Name\", \n",
    "    \"Location\", \n",
    "    \"Price\", \n",
    "    \"Overall Rating\", \n",
    "    \"Number Sold\", \n",
    "    \"Total Review\", \n",
    "    \"Customer Rating\", \n",
    "    \"Emotion\"\n",
    "])\n",
    "data.head()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 120,
   "id": "ff6816b6-98c5-44f9-a112-446ac3b10ec1",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "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>Category</th>\n",
       "      <th>Customer Review</th>\n",
       "      <th>Sentiment</th>\n",
       "    </tr>\n",
       "  </thead>\n",
       "  <tbody>\n",
       "    <tr>\n",
       "      <th>0</th>\n",
       "      <td>Computers and Laptops</td>\n",
       "      <td>alhamdulillah berfungsi dengan baik. packaging...</td>\n",
       "      <td>Positive</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>1</th>\n",
       "      <td>Computers and Laptops</td>\n",
       "      <td>barang bagus dan respon cepat, harga bersaing ...</td>\n",
       "      <td>Positive</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>2</th>\n",
       "      <td>Computers and Laptops</td>\n",
       "      <td>barang bagus, berfungsi dengan baik, seler ram...</td>\n",
       "      <td>Positive</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>3</th>\n",
       "      <td>Computers and Laptops</td>\n",
       "      <td>bagus sesuai harapan penjual nya juga ramah. t...</td>\n",
       "      <td>Positive</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>4</th>\n",
       "      <td>Computers and Laptops</td>\n",
       "      <td>barang bagus, pengemasan aman, dapat berfungsi...</td>\n",
       "      <td>Positive</td>\n",
       "    </tr>\n",
       "  </tbody>\n",
       "</table>\n",
       "</div>"
      ],
      "text/plain": [
       "                Category                                    Customer Review  \\\n",
       "0  Computers and Laptops  alhamdulillah berfungsi dengan baik. packaging...   \n",
       "1  Computers and Laptops  barang bagus dan respon cepat, harga bersaing ...   \n",
       "2  Computers and Laptops  barang bagus, berfungsi dengan baik, seler ram...   \n",
       "3  Computers and Laptops  bagus sesuai harapan penjual nya juga ramah. t...   \n",
       "4  Computers and Laptops  barang bagus, pengemasan aman, dapat berfungsi...   \n",
       "\n",
       "  Sentiment  \n",
       "0  Positive  \n",
       "1  Positive  \n",
       "2  Positive  \n",
       "3  Positive  \n",
       "4  Positive  "
      ]
     },
     "execution_count": 120,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "data[\"Customer Review\"] = data[\"Customer Review\"].str.lower()\n",
    "data.head()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 121,
   "id": "aa755a47-7758-4829-b31d-49a5cdae3c81",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "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>Category</th>\n",
       "      <th>Customer Review</th>\n",
       "      <th>Sentiment</th>\n",
       "    </tr>\n",
       "  </thead>\n",
       "  <tbody>\n",
       "    <tr>\n",
       "      <th>0</th>\n",
       "      <td>Computers and Laptops</td>\n",
       "      <td>alhamdulillah berfungsi baik. packaging aman. ...</td>\n",
       "      <td>Positive</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>1</th>\n",
       "      <td>Computers and Laptops</td>\n",
       "      <td>barang bagus respon cepat, harga bersaing yg l...</td>\n",
       "      <td>Positive</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>2</th>\n",
       "      <td>Computers and Laptops</td>\n",
       "      <td>barang bagus, berfungsi baik, seler ramah, pen...</td>\n",
       "      <td>Positive</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>3</th>\n",
       "      <td>Computers and Laptops</td>\n",
       "      <td>bagus sesuai harapan penjual nya ramah. trimak...</td>\n",
       "      <td>Positive</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>4</th>\n",
       "      <td>Computers and Laptops</td>\n",
       "      <td>barang bagus, pengemasan aman, berfungsi baik</td>\n",
       "      <td>Positive</td>\n",
       "    </tr>\n",
       "  </tbody>\n",
       "</table>\n",
       "</div>"
      ],
      "text/plain": [
       "                Category                                    Customer Review  \\\n",
       "0  Computers and Laptops  alhamdulillah berfungsi baik. packaging aman. ...   \n",
       "1  Computers and Laptops  barang bagus respon cepat, harga bersaing yg l...   \n",
       "2  Computers and Laptops  barang bagus, berfungsi baik, seler ramah, pen...   \n",
       "3  Computers and Laptops  bagus sesuai harapan penjual nya ramah. trimak...   \n",
       "4  Computers and Laptops      barang bagus, pengemasan aman, berfungsi baik   \n",
       "\n",
       "  Sentiment  \n",
       "0  Positive  \n",
       "1  Positive  \n",
       "2  Positive  \n",
       "3  Positive  \n",
       "4  Positive  "
      ]
     },
     "execution_count": 121,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "#Stopword\n",
    "\n",
    "more_stop_word = []\n",
    "\n",
    "stop_words = StopWordRemoverFactory().get_stop_words()\n",
    "new_array = ArrayDictionary(stop_words)\n",
    "stop_word_remover_new = StopWordRemover(new_array)\n",
    "\n",
    "def stopword(str_text):\n",
    "    str_text = stop_word_remover_new.remove(str_text)\n",
    "    return str_text\n",
    "\n",
    "data[\"Customer Review\"] = data[\"Customer Review\"].apply(lambda x: stopword(x))\n",
    "data.head()\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 122,
   "id": "76470552-6fd6-4526-8df0-4693d78ca35c",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "0       [alhamdulillah, berfungsi, baik., packaging, a...\n",
       "1       [barang, bagus, respon, cepat,, harga, bersain...\n",
       "2       [barang, bagus,, berfungsi, baik,, seler, rama...\n",
       "3       [bagus, sesuai, harapan, penjual, nya, ramah.,...\n",
       "4       [barang, bagus,, pengemasan, aman,, berfungsi,...\n",
       "                              ...                        \n",
       "5395    [harga, bersaing,, barang, sesuai, pesanan., n...\n",
       "5396    [beli, krn, anak, &, istri, mau, liburan, jaka...\n",
       "5397    [pengemasan, barang, baik,, kondisi, barang, j...\n",
       "5398    [mungil, bekerja, dng, baik., murahh, terjangk...\n",
       "5399    [produk, sesuai, deskripsi,, packing, aman, te...\n",
       "Name: Customer Review, Length: 5393, dtype: object"
      ]
     },
     "execution_count": 122,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "# Tokenisasi\n",
    "tokenized = data[\"Customer Review\"].apply(lambda x:x.split())\n",
    "tokenized"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 61,
   "id": "a76b33e4-287f-46b5-b9d6-568718c0eda1",
   "metadata": {},
   "outputs": [
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "100%|████████████████████████████████████████████████████████████████████████████| 5393/5393 [3:50:14<00:00,  2.56s/it]\n"
     ]
    }
   ],
   "source": [
    "#Steamming\n",
    "\n",
    "# Integrasikan tqdm ke pandas\n",
    "tqdm.pandas()\n",
    "\n",
    "# Fungsi stemming\n",
    "def stemming(text_cleaning):\n",
    "    factory = StemmerFactory()\n",
    "    stemmer = factory.create_stemmer()\n",
    "    do = []\n",
    "    for w in str(text_cleaning).split():  # pastikan tipe data string\n",
    "        dt = stemmer.stem(w)\n",
    "        do.append(dt)\n",
    "    d_clean = \" \".join(do)\n",
    "    return d_clean\n",
    "\n",
    "tokenized = data[\"Customer Review\"].progress_apply(stemming)\n",
    "\n",
    "# Simpan hasil ke CSV\n",
    "tokenized.to_csv(\"dataset_stemming.csv\", index=False)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 123,
   "id": "af947567-d6a2-4a4c-909c-385d918016c7",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "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>Customer Review</th>\n",
       "    </tr>\n",
       "  </thead>\n",
       "  <tbody>\n",
       "    <tr>\n",
       "      <th>0</th>\n",
       "      <td>alhamdulillah fungsi baik packaging aman respo...</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>1</th>\n",
       "      <td>barang bagus respon cepat harga saing yg lain</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>2</th>\n",
       "      <td>barang bagus fungsi baik seler ramah kirim cepat</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>3</th>\n",
       "      <td>bagus sesuai harap jual nya ramah trimakasih l...</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>4</th>\n",
       "      <td>barang bagus emas aman fungsi baik</td>\n",
       "    </tr>\n",
       "  </tbody>\n",
       "</table>\n",
       "</div>"
      ],
      "text/plain": [
       "                                     Customer Review\n",
       "0  alhamdulillah fungsi baik packaging aman respo...\n",
       "1      barang bagus respon cepat harga saing yg lain\n",
       "2   barang bagus fungsi baik seler ramah kirim cepat\n",
       "3  bagus sesuai harap jual nya ramah trimakasih l...\n",
       "4                 barang bagus emas aman fungsi baik"
      ]
     },
     "execution_count": 123,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "data_clean = pd.read_csv(\"dataset_stemming.csv\")\n",
    "data_clean.head()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 124,
   "id": "0cef2607-0bd8-4e6f-9505-d2a339b0e7b7",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "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>Customer Review</th>\n",
       "      <th>Category</th>\n",
       "      <th>Sentiment</th>\n",
       "    </tr>\n",
       "  </thead>\n",
       "  <tbody>\n",
       "    <tr>\n",
       "      <th>0</th>\n",
       "      <td>alhamdulillah fungsi baik packaging aman respo...</td>\n",
       "      <td>Computers and Laptops</td>\n",
       "      <td>Positive</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>1</th>\n",
       "      <td>barang bagus respon cepat harga saing yg lain</td>\n",
       "      <td>Computers and Laptops</td>\n",
       "      <td>Positive</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>2</th>\n",
       "      <td>barang bagus fungsi baik seler ramah kirim cepat</td>\n",
       "      <td>Computers and Laptops</td>\n",
       "      <td>Positive</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>3</th>\n",
       "      <td>bagus sesuai harap jual nya ramah trimakasih l...</td>\n",
       "      <td>Computers and Laptops</td>\n",
       "      <td>Positive</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>4</th>\n",
       "      <td>barang bagus emas aman fungsi baik</td>\n",
       "      <td>Computers and Laptops</td>\n",
       "      <td>Positive</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>...</th>\n",
       "      <td>...</td>\n",
       "      <td>...</td>\n",
       "      <td>...</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>5395</th>\n",
       "      <td>NaN</td>\n",
       "      <td>Household</td>\n",
       "      <td>Positive</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>5396</th>\n",
       "      <td>NaN</td>\n",
       "      <td>Household</td>\n",
       "      <td>Positive</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>5397</th>\n",
       "      <td>NaN</td>\n",
       "      <td>Household</td>\n",
       "      <td>Positive</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>5398</th>\n",
       "      <td>NaN</td>\n",
       "      <td>Household</td>\n",
       "      <td>Positive</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>5399</th>\n",
       "      <td>NaN</td>\n",
       "      <td>Household</td>\n",
       "      <td>Positive</td>\n",
       "    </tr>\n",
       "  </tbody>\n",
       "</table>\n",
       "<p>5400 rows × 3 columns</p>\n",
       "</div>"
      ],
      "text/plain": [
       "                                        Customer Review  \\\n",
       "0     alhamdulillah fungsi baik packaging aman respo...   \n",
       "1         barang bagus respon cepat harga saing yg lain   \n",
       "2      barang bagus fungsi baik seler ramah kirim cepat   \n",
       "3     bagus sesuai harap jual nya ramah trimakasih l...   \n",
       "4                    barang bagus emas aman fungsi baik   \n",
       "...                                                 ...   \n",
       "5395                                                NaN   \n",
       "5396                                                NaN   \n",
       "5397                                                NaN   \n",
       "5398                                                NaN   \n",
       "5399                                                NaN   \n",
       "\n",
       "                   Category Sentiment  \n",
       "0     Computers and Laptops  Positive  \n",
       "1     Computers and Laptops  Positive  \n",
       "2     Computers and Laptops  Positive  \n",
       "3     Computers and Laptops  Positive  \n",
       "4     Computers and Laptops  Positive  \n",
       "...                     ...       ...  \n",
       "5395              Household  Positive  \n",
       "5396              Household  Positive  \n",
       "5397              Household  Positive  \n",
       "5398              Household  Positive  \n",
       "5399              Household  Positive  \n",
       "\n",
       "[5400 rows x 3 columns]"
      ]
     },
     "execution_count": 124,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "att1 = data['Category']\n",
    "att2 = data['Sentiment']\n",
    "\n",
    "data_clean = pd.concat([data_clean, att1, att2], axis=1)\n",
    "data_clean"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 125,
   "id": "94117fec-3ec5-4ec7-8643-11f91548b5be",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "Customer Review    7\n",
       "Category           7\n",
       "Sentiment          7\n",
       "dtype: int64"
      ]
     },
     "execution_count": 125,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "data_clean.duplicated().sum()\n",
    "data_clean.isnull().sum()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 126,
   "id": "3f34df24-0b9d-438c-859e-c14ad02d4b30",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "Customer Review    0\n",
       "Category           0\n",
       "Sentiment          0\n",
       "dtype: int64"
      ]
     },
     "execution_count": 126,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "data_clean = data_clean.dropna()\n",
    "data_clean.isnull().sum()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 127,
   "id": "d8d96510-b082-4dba-a664-0b84aae728d8",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "                    Category  Encoded\n",
      "0                Animal Care        0\n",
      "1                 Automotive        1\n",
      "2                     Beauty        2\n",
      "3                  Body Care        3\n",
      "4                      Books        4\n",
      "5                     Camera        5\n",
      "6                  Carpentry        6\n",
      "7      Computers and Laptops        7\n",
      "8                Electronics        8\n",
      "9             Food and Drink        9\n",
      "10                    Gaming       10\n",
      "11                    Health       11\n",
      "12                 Household       12\n",
      "13     Kids and Baby Fashion       13\n",
      "14                   Kitchen       14\n",
      "15             Men's Fashion       15\n",
      "16           Mother and Baby       16\n",
      "17          Movies and Music       17\n",
      "18            Muslim Fashion       18\n",
      "19       Office & Stationery       19\n",
      "20            Other Products       20\n",
      "21  Party Supplies and Craft       21\n",
      "22        Phones and Tablets       22\n",
      "23            Precious Metal       23\n",
      "24                  Property       24\n",
      "25                     Sport       25\n",
      "26           Tour and Travel       26\n",
      "27          Toys and Hobbies       27\n",
      "28           Women's Fashion       28\n"
     ]
    },
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "C:\\Users\\Daffa Lintang\\AppData\\Local\\Temp\\ipykernel_23380\\1493082063.py:4: FutureWarning: Downcasting behavior in `replace` is deprecated and will be removed in a future version. To retain the old behavior, explicitly call `result.infer_objects(copy=False)`. To opt-in to the future behavior, set `pd.set_option('future.no_silent_downcasting', True)`\n",
      "  data_clean[\"Sentiment\"] = data_clean[\"Sentiment\"].replace({\"Positive\": 1, \"Negative\": 0}).astype(int)\n",
      "C:\\Users\\Daffa Lintang\\AppData\\Local\\Temp\\ipykernel_23380\\1493082063.py:4: SettingWithCopyWarning: \n",
      "A value is trying to be set on a copy of a slice from a DataFrame.\n",
      "Try using .loc[row_indexer,col_indexer] = value instead\n",
      "\n",
      "See the caveats in the documentation: https://pandas.pydata.org/pandas-docs/stable/user_guide/indexing.html#returning-a-view-versus-a-copy\n",
      "  data_clean[\"Sentiment\"] = data_clean[\"Sentiment\"].replace({\"Positive\": 1, \"Negative\": 0}).astype(int)\n",
      "C:\\Users\\Daffa Lintang\\AppData\\Local\\Temp\\ipykernel_23380\\1493082063.py:5: SettingWithCopyWarning: \n",
      "A value is trying to be set on a copy of a slice from a DataFrame.\n",
      "Try using .loc[row_indexer,col_indexer] = value instead\n",
      "\n",
      "See the caveats in the documentation: https://pandas.pydata.org/pandas-docs/stable/user_guide/indexing.html#returning-a-view-versus-a-copy\n",
      "  data_clean[\"Category\"] = encoder.fit_transform(data_clean[\"Category\"])\n"
     ]
    },
    {
     "data": {
      "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>Customer Review</th>\n",
       "      <th>Category</th>\n",
       "      <th>Sentiment</th>\n",
       "    </tr>\n",
       "  </thead>\n",
       "  <tbody>\n",
       "    <tr>\n",
       "      <th>0</th>\n",
       "      <td>alhamdulillah fungsi baik packaging aman respo...</td>\n",
       "      <td>7</td>\n",
       "      <td>1</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>1</th>\n",
       "      <td>barang bagus respon cepat harga saing yg lain</td>\n",
       "      <td>7</td>\n",
       "      <td>1</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>2</th>\n",
       "      <td>barang bagus fungsi baik seler ramah kirim cepat</td>\n",
       "      <td>7</td>\n",
       "      <td>1</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>3</th>\n",
       "      <td>bagus sesuai harap jual nya ramah trimakasih l...</td>\n",
       "      <td>7</td>\n",
       "      <td>1</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>4</th>\n",
       "      <td>barang bagus emas aman fungsi baik</td>\n",
       "      <td>7</td>\n",
       "      <td>1</td>\n",
       "    </tr>\n",
       "  </tbody>\n",
       "</table>\n",
       "</div>"
      ],
      "text/plain": [
       "                                     Customer Review  Category  Sentiment\n",
       "0  alhamdulillah fungsi baik packaging aman respo...         7          1\n",
       "1      barang bagus respon cepat harga saing yg lain         7          1\n",
       "2   barang bagus fungsi baik seler ramah kirim cepat         7          1\n",
       "3  bagus sesuai harap jual nya ramah trimakasih l...         7          1\n",
       "4                 barang bagus emas aman fungsi baik         7          1"
      ]
     },
     "execution_count": 127,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "encoder = LabelEncoder()\n",
    "data_clean[\"Sentiment\"] = data_clean[\"Sentiment\"].replace({\"Positive\": 1, \"Negative\": 0}).astype(int)\n",
    "data_clean[\"Category\"] = encoder.fit_transform(data_clean[\"Category\"])\n",
    "\n",
    "category_mapping = pd.DataFrame({\n",
    "    'Category': encoder.classes_,\n",
    "    'Encoded': range(len(encoder.classes_))\n",
    "})\n",
    "\n",
    "print(category_mapping)\n",
    "\n",
    "data_clean.head()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 48,
   "id": "b7a43a22-283a-488f-a86c-7fcefc3d842b",
   "metadata": {},
   "outputs": [],
   "source": [
    "data_negatif = data_clean[data_clean[\"Sentiment\"] == 0]\n",
    "data_positif = data_clean[data_clean[\"Sentiment\"] == 1]"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 49,
   "id": "c2637310-ec36-4b6e-a095-c952ca119c98",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "image/png": "[encoded data, 272864 characters]",
      "text/plain": [
       "<Figure size 900x600 with 1 Axes>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    }
   ],
   "source": [
    "all_text_s0 = ' '.join(word for word in data_negatif[\"Customer Review\"])\n",
    "wordCloud = WordCloud(colormap=\"Reds\", width=1000, height=1000, mode=\"RGBA\", background_color=\"white\").generate(all_text_s0)\n",
    "plt.figure(figsize=(9, 6))\n",
    "plt.imshow(wordCloud, interpolation='bilinear')\n",
    "plt.axis('off')\n",
    "plt.title('Visualisasi Kata Negatif')\n",
    "plt.margins(x=0, y=0)\n",
    "plt.show()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 50,
   "id": "f6155b51-9a94-4f9b-a222-227cdf8c9632",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "image/png": "[encoded data, 256648 characters]",
      "text/plain": [
       "<Figure size 900x600 with 1 Axes>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    }
   ],
   "source": [
    "all_text_s1 = ' '.join(word for word in data_positif[\"Customer Review\"])\n",
    "wordCloud = WordCloud(colormap=\"Blues\", width=1000, height=1000, mode=\"RGBA\", background_color=\"white\").generate(all_text_s1)\n",
    "plt.figure(figsize=(9, 6))\n",
    "plt.imshow(wordCloud, interpolation='bilinear')\n",
    "plt.axis('off')\n",
    "plt.title('Visualisasi Kata Positif')\n",
    "plt.margins(x=0, y=0)\n",
    "plt.show()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 51,
   "id": "18328cab-671e-4d34-be9d-384d9db12e47",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "Sentiment\n",
       "0    2817\n",
       "1    2569\n",
       "Name: count, dtype: int64"
      ]
     },
     "execution_count": 51,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "data_clean[\"Sentiment\"].value_counts()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 52,
   "id": "74984bba-4457-47e3-87e9-a794891b8520",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "image/png": "[encoded data, 16756 characters]",
      "text/plain": [
       "<Figure size 500x300 with 1 Axes>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    }
   ],
   "source": [
    "#Visualisasi sentimen positif dan negatif\n",
    "plt.figure(figsize=(5, 3))\n",
    "sns.countplot(data=data_clean, x='Sentiment', hue='Sentiment', palette={0: \"red\", 1: \"blue\"}, legend=False)\n",
    "plt.title('Visualisasi Sentimen Positif dan Negatif')\n",
    "plt.xlabel('Sentimen')\n",
    "plt.ylabel('Jumlah')\n",
    "plt.show()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 53,
   "id": "510f0c5b-88e9-4885-8ff2-e6b96af1b33a",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "image/png": "[encoded data, 33760 characters]",
      "text/plain": [
       "<Figure size 1800x500 with 1 Axes>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    }
   ],
   "source": [
    "#Sentimen per kategori\n",
    "plt.figure(figsize=(18, 5))\n",
    "sns.countplot(data=data_clean, x='Category', hue='Sentiment', palette={0: \"red\", 1: \"blue\"})\n",
    "plt.title('Distribusi Sentimen per Kategori')\n",
    "plt.xlabel('Kategori')\n",
    "plt.ylabel('Jumlah')\n",
    "plt.legend(title='Sentimen', labels=['Negatif', 'Positif'])\n",
    "plt.xticks(rotation=45)\n",
    "plt.show()\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 54,
   "id": "b8522709-bdbd-486d-abc2-84c11ef5cef1",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "29"
      ]
     },
     "execution_count": 54,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "data_clean[\"Category\"].nunique()\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 55,
   "id": "d75b5a02-8841-4ace-be90-4d67288312fc",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Kategori tanpa sentimen negatif: [23, 24, 26]\n"
     ]
    }
   ],
   "source": [
    "# Kategori yang hanya punya sentimen positif\n",
    "only_positive = data_clean.groupby('Category')['Sentiment'].apply(lambda x: set(x) == {1})\n",
    "only_positive_categories = only_positive[only_positive].index.tolist()\n",
    "\n",
    "print(\"Kategori tanpa sentimen negatif:\", only_positive_categories)\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 56,
   "id": "2c802ce0-1e83-44bc-a713-f519a680041d",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "✅ Oversampling selesai!\n",
      "Ukuran data asli : 5386\n",
      "Ukuran data baru  : 5586\n"
     ]
    }
   ],
   "source": [
    "# Ambil data negatif dari kategori lain\n",
    "negative_other = data_clean[(data_clean['Sentiment'] == 0) & (~data_clean['Category'].isin([23, 24, 26]))]\n",
    "\n",
    "# Kategori yang tidak punya sentimen negatif\n",
    "target_categories = [23, 24, 26]\n",
    "\n",
    "synthetic_list = []\n",
    "\n",
    "for category in target_categories:\n",
    "    # Hitung jumlah data positif di kategori tersebut\n",
    "    n_target = len(data_clean[data_clean['Category'] == category])\n",
    "    \n",
    "    if n_target == 0:\n",
    "        print(f\"⚠️ Tidak ditemukan data untuk kategori {category}, dilewati.\")\n",
    "        continue\n",
    "    \n",
    "    # Oversample data negatif dari kategori lain\n",
    "    negative_synthetic = resample(\n",
    "        negative_other,\n",
    "        replace=True,\n",
    "        n_samples=n_target,  # jumlah data negatif sintetis = jumlah data positif\n",
    "        random_state=42\n",
    "    )\n",
    "    \n",
    "    # Ubah kategorinya menjadi kategori target\n",
    "    negative_synthetic['Category'] = category\n",
    "    \n",
    "    # Tambahkan ke list\n",
    "    synthetic_list.append(negative_synthetic)\n",
    "\n",
    "# Gabungkan semua hasil sintetis\n",
    "all_synthetic = pd.concat(synthetic_list, ignore_index=True)\n",
    "\n",
    "# Gabungkan dengan dataset asli\n",
    "data_augmented = pd.concat([data_clean, all_synthetic], ignore_index=True)\n",
    "\n",
    "print(\"✅ Oversampling selesai!\")\n",
    "print(\"Ukuran data asli :\", len(data_clean))\n",
    "print(\"Ukuran data baru  :\", len(data_augmented))\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 57,
   "id": "66304c2a-bbc8-4061-912d-6d0dff403d0d",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "image/png": "[encoded data, 33780 characters]",
      "text/plain": [
       "<Figure size 1800x500 with 1 Axes>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    }
   ],
   "source": [
    "#Sentimen per kategori\n",
    "plt.figure(figsize=(18, 5))\n",
    "sns.countplot(data=data_augmented, x='Category', hue='Sentiment', palette={0: \"red\", 1: \"blue\"})\n",
    "plt.title('Distribusi Sentimen per Kategori')\n",
    "plt.xlabel('Kategori')\n",
    "plt.ylabel('Jumlah')\n",
    "plt.legend(title='Sentimen', labels=['Negatif', 'Positif'])\n",
    "plt.xticks(rotation=45)\n",
    "plt.show()\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 58,
   "id": "2f2f9953-70b4-45cb-9d69-1317d718cc21",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "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>Customer Review</th>\n",
       "      <th>Category</th>\n",
       "      <th>Sentiment</th>\n",
       "    </tr>\n",
       "  </thead>\n",
       "  <tbody>\n",
       "    <tr>\n",
       "      <th>0</th>\n",
       "      <td>alhamdulillah fungsi baik packaging aman respo...</td>\n",
       "      <td>7</td>\n",
       "      <td>1</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>1</th>\n",
       "      <td>barang bagus respon cepat harga saing yg lain</td>\n",
       "      <td>7</td>\n",
       "      <td>1</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>2</th>\n",
       "      <td>barang bagus fungsi baik seler ramah kirim cepat</td>\n",
       "      <td>7</td>\n",
       "      <td>1</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>3</th>\n",
       "      <td>bagus sesuai harap jual nya ramah trimakasih l...</td>\n",
       "      <td>7</td>\n",
       "      <td>1</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>4</th>\n",
       "      <td>barang bagus emas aman fungsi baik</td>\n",
       "      <td>7</td>\n",
       "      <td>1</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>...</th>\n",
       "      <td>...</td>\n",
       "      <td>...</td>\n",
       "      <td>...</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>5581</th>\n",
       "      <td>barang gak pakai  parah mah</td>\n",
       "      <td>26</td>\n",
       "      <td>0</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>5582</th>\n",
       "      <td>udah 2x beli ga awet banget yg pertama rusak r...</td>\n",
       "      <td>26</td>\n",
       "      <td>0</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>5583</th>\n",
       "      <td>minta warna hitam doff malah kirim warna warni...</td>\n",
       "      <td>26</td>\n",
       "      <td>0</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>5584</th>\n",
       "      <td>free canister ga kirim payah kecewah dah males...</td>\n",
       "      <td>26</td>\n",
       "      <td>0</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>5585</th>\n",
       "      <td>jual gak jujur  respon banyak bot</td>\n",
       "      <td>26</td>\n",
       "      <td>0</td>\n",
       "    </tr>\n",
       "  </tbody>\n",
       "</table>\n",
       "<p>5586 rows × 3 columns</p>\n",
       "</div>"
      ],
      "text/plain": [
       "                                        Customer Review  Category  Sentiment\n",
       "0     alhamdulillah fungsi baik packaging aman respo...         7          1\n",
       "1         barang bagus respon cepat harga saing yg lain         7          1\n",
       "2      barang bagus fungsi baik seler ramah kirim cepat         7          1\n",
       "3     bagus sesuai harap jual nya ramah trimakasih l...         7          1\n",
       "4                    barang bagus emas aman fungsi baik         7          1\n",
       "...                                                 ...       ...        ...\n",
       "5581                        barang gak pakai  parah mah        26          0\n",
       "5582  udah 2x beli ga awet banget yg pertama rusak r...        26          0\n",
       "5583  minta warna hitam doff malah kirim warna warni...        26          0\n",
       "5584  free canister ga kirim payah kecewah dah males...        26          0\n",
       "5585                  jual gak jujur  respon banyak bot        26          0\n",
       "\n",
       "[5586 rows x 3 columns]"
      ]
     },
     "execution_count": 58,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "data_augmented"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 60,
   "id": "7e4ec4b8-1b23-44bf-a7db-a9557c51a2e0",
   "metadata": {},
   "outputs": [],
   "source": [
    "X = data_augmented[['Customer Review', 'Category']]\n",
    "y = data_augmented['Sentiment']\n",
    "\n",
    "X_train, X_test, y_train, y_test = train_test_split(\n",
    "    X, y, test_size=0.2, random_state=42\n",
    ")\n",
    "\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 94,
   "id": "d9ff67a9-dc01-4a36-97fd-625721fc23f6",
   "metadata": {},
   "outputs": [],
   "source": [
    "vectorizer = TfidfVectorizer()\n",
    "x_train_vec =vectorizer.fit_transform(X_train['Customer Review'])\n",
    "x_test_vec =vectorizer.transform(X_test['Customer Review'])\n",
    "\n",
    "x_train_final = hstack([x_train_vec, X_train[['Category']].values])\n",
    "x_test_final = hstack([x_test_vec, X_test[['Category']].values])"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 106,
   "id": "32e87d7c-fed0-4296-b6b0-1f4ae4a20062",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/html": [
       "<style>#sk-container-id-7 {\n",
       "  /* Definition of color scheme common for light and dark mode */\n",
       "  --sklearn-color-text: #000;\n",
       "  --sklearn-color-text-muted: #666;\n",
       "  --sklearn-color-line: gray;\n",
       "  /* Definition of color scheme for unfitted estimators */\n",
       "  --sklearn-color-unfitted-level-0: #fff5e6;\n",
       "  --sklearn-color-unfitted-level-1: #f6e4d2;\n",
       "  --sklearn-color-unfitted-level-2: #ffe0b3;\n",
       "  --sklearn-color-unfitted-level-3: chocolate;\n",
       "  /* Definition of color scheme for fitted estimators */\n",
       "  --sklearn-color-fitted-level-0: #f0f8ff;\n",
       "  --sklearn-color-fitted-level-1: #d4ebff;\n",
       "  --sklearn-color-fitted-level-2: #b3dbfd;\n",
       "  --sklearn-color-fitted-level-3: cornflowerblue;\n",
       "\n",
       "  /* Specific color for light theme */\n",
       "  --sklearn-color-text-on-default-background: var(--sg-text-color, var(--theme-code-foreground, var(--jp-content-font-color1, black)));\n",
       "  --sklearn-color-background: var(--sg-background-color, var(--theme-background, var(--jp-layout-color0, white)));\n",
       "  --sklearn-color-border-box: var(--sg-text-color, var(--theme-code-foreground, var(--jp-content-font-color1, black)));\n",
       "  --sklearn-color-icon: #696969;\n",
       "\n",
       "  @media (prefers-color-scheme: dark) {\n",
       "    /* Redefinition of color scheme for dark theme */\n",
       "    --sklearn-color-text-on-default-background: var(--sg-text-color, var(--theme-code-foreground, var(--jp-content-font-color1, white)));\n",
       "    --sklearn-color-background: var(--sg-background-color, var(--theme-background, var(--jp-layout-color0, #111)));\n",
       "    --sklearn-color-border-box: var(--sg-text-color, var(--theme-code-foreground, var(--jp-content-font-color1, white)));\n",
       "    --sklearn-color-icon: #878787;\n",
       "  }\n",
       "}\n",
       "\n",
       "#sk-container-id-7 {\n",
       "  color: var(--sklearn-color-text);\n",
       "}\n",
       "\n",
       "#sk-container-id-7 pre {\n",
       "  padding: 0;\n",
       "}\n",
       "\n",
       "#sk-container-id-7 input.sk-hidden--visually {\n",
       "  border: 0;\n",
       "  clip: rect(1px 1px 1px 1px);\n",
       "  clip: rect(1px, 1px, 1px, 1px);\n",
       "  height: 1px;\n",
       "  margin: -1px;\n",
       "  overflow: hidden;\n",
       "  padding: 0;\n",
       "  position: absolute;\n",
       "  width: 1px;\n",
       "}\n",
       "\n",
       "#sk-container-id-7 div.sk-dashed-wrapped {\n",
       "  border: 1px dashed var(--sklearn-color-line);\n",
       "  margin: 0 0.4em 0.5em 0.4em;\n",
       "  box-sizing: border-box;\n",
       "  padding-bottom: 0.4em;\n",
       "  background-color: var(--sklearn-color-background);\n",
       "}\n",
       "\n",
       "#sk-container-id-7 div.sk-container {\n",
       "  /* jupyter's `normalize.less` sets `[hidden] { display: none; }`\n",
       "     but bootstrap.min.css set `[hidden] { display: none !important; }`\n",
       "     so we also need the `!important` here to be able to override the\n",
       "     default hidden behavior on the sphinx rendered scikit-learn.org.\n",
       "     See: https://github.com/scikit-learn/scikit-learn/issues/21755 */\n",
       "  display: inline-block !important;\n",
       "  position: relative;\n",
       "}\n",
       "\n",
       "#sk-container-id-7 div.sk-text-repr-fallback {\n",
       "  display: none;\n",
       "}\n",
       "\n",
       "div.sk-parallel-item,\n",
       "div.sk-serial,\n",
       "div.sk-item {\n",
       "  /* draw centered vertical line to link estimators */\n",
       "  background-image: linear-gradient(var(--sklearn-color-text-on-default-background), var(--sklearn-color-text-on-default-background));\n",
       "  background-size: 2px 100%;\n",
       "  background-repeat: no-repeat;\n",
       "  background-position: center center;\n",
       "}\n",
       "\n",
       "/* Parallel-specific style estimator block */\n",
       "\n",
       "#sk-container-id-7 div.sk-parallel-item::after {\n",
       "  content: \"\";\n",
       "  width: 100%;\n",
       "  border-bottom: 2px solid var(--sklearn-color-text-on-default-background);\n",
       "  flex-grow: 1;\n",
       "}\n",
       "\n",
       "#sk-container-id-7 div.sk-parallel {\n",
       "  display: flex;\n",
       "  align-items: stretch;\n",
       "  justify-content: center;\n",
       "  background-color: var(--sklearn-color-background);\n",
       "  position: relative;\n",
       "}\n",
       "\n",
       "#sk-container-id-7 div.sk-parallel-item {\n",
       "  display: flex;\n",
       "  flex-direction: column;\n",
       "}\n",
       "\n",
       "#sk-container-id-7 div.sk-parallel-item:first-child::after {\n",
       "  align-self: flex-end;\n",
       "  width: 50%;\n",
       "}\n",
       "\n",
       "#sk-container-id-7 div.sk-parallel-item:last-child::after {\n",
       "  align-self: flex-start;\n",
       "  width: 50%;\n",
       "}\n",
       "\n",
       "#sk-container-id-7 div.sk-parallel-item:only-child::after {\n",
       "  width: 0;\n",
       "}\n",
       "\n",
       "/* Serial-specific style estimator block */\n",
       "\n",
       "#sk-container-id-7 div.sk-serial {\n",
       "  display: flex;\n",
       "  flex-direction: column;\n",
       "  align-items: center;\n",
       "  background-color: var(--sklearn-color-background);\n",
       "  padding-right: 1em;\n",
       "  padding-left: 1em;\n",
       "}\n",
       "\n",
       "\n",
       "/* Toggleable style: style used for estimator/Pipeline/ColumnTransformer box that is\n",
       "clickable and can be expanded/collapsed.\n",
       "- Pipeline and ColumnTransformer use this feature and define the default style\n",
       "- Estimators will overwrite some part of the style using the `sk-estimator` class\n",
       "*/\n",
       "\n",
       "/* Pipeline and ColumnTransformer style (default) */\n",
       "\n",
       "#sk-container-id-7 div.sk-toggleable {\n",
       "  /* Default theme specific background. It is overwritten whether we have a\n",
       "  specific estimator or a Pipeline/ColumnTransformer */\n",
       "  background-color: var(--sklearn-color-background);\n",
       "}\n",
       "\n",
       "/* Toggleable label */\n",
       "#sk-container-id-7 label.sk-toggleable__label {\n",
       "  cursor: pointer;\n",
       "  display: flex;\n",
       "  width: 100%;\n",
       "  margin-bottom: 0;\n",
       "  padding: 0.5em;\n",
       "  box-sizing: border-box;\n",
       "  text-align: center;\n",
       "  align-items: start;\n",
       "  justify-content: space-between;\n",
       "  gap: 0.5em;\n",
       "}\n",
       "\n",
       "#sk-container-id-7 label.sk-toggleable__label .caption {\n",
       "  font-size: 0.6rem;\n",
       "  font-weight: lighter;\n",
       "  color: var(--sklearn-color-text-muted);\n",
       "}\n",
       "\n",
       "#sk-container-id-7 label.sk-toggleable__label-arrow:before {\n",
       "  /* Arrow on the left of the label */\n",
       "  content: \"▸\";\n",
       "  float: left;\n",
       "  margin-right: 0.25em;\n",
       "  color: var(--sklearn-color-icon);\n",
       "}\n",
       "\n",
       "#sk-container-id-7 label.sk-toggleable__label-arrow:hover:before {\n",
       "  color: var(--sklearn-color-text);\n",
       "}\n",
       "\n",
       "/* Toggleable content - dropdown */\n",
       "\n",
       "#sk-container-id-7 div.sk-toggleable__content {\n",
       "  display: none;\n",
       "  text-align: left;\n",
       "  /* unfitted */\n",
       "  background-color: var(--sklearn-color-unfitted-level-0);\n",
       "}\n",
       "\n",
       "#sk-container-id-7 div.sk-toggleable__content.fitted {\n",
       "  /* fitted */\n",
       "  background-color: var(--sklearn-color-fitted-level-0);\n",
       "}\n",
       "\n",
       "#sk-container-id-7 div.sk-toggleable__content pre {\n",
       "  margin: 0.2em;\n",
       "  border-radius: 0.25em;\n",
       "  color: var(--sklearn-color-text);\n",
       "  /* unfitted */\n",
       "  background-color: var(--sklearn-color-unfitted-level-0);\n",
       "}\n",
       "\n",
       "#sk-container-id-7 div.sk-toggleable__content.fitted pre {\n",
       "  /* unfitted */\n",
       "  background-color: var(--sklearn-color-fitted-level-0);\n",
       "}\n",
       "\n",
       "#sk-container-id-7 input.sk-toggleable__control:checked~div.sk-toggleable__content {\n",
       "  /* Expand drop-down */\n",
       "  display: block;\n",
       "  width: 100%;\n",
       "  overflow: visible;\n",
       "}\n",
       "\n",
       "#sk-container-id-7 input.sk-toggleable__control:checked~label.sk-toggleable__label-arrow:before {\n",
       "  content: \"▾\";\n",
       "}\n",
       "\n",
       "/* Pipeline/ColumnTransformer-specific style */\n",
       "\n",
       "#sk-container-id-7 div.sk-label input.sk-toggleable__control:checked~label.sk-toggleable__label {\n",
       "  color: var(--sklearn-color-text);\n",
       "  background-color: var(--sklearn-color-unfitted-level-2);\n",
       "}\n",
       "\n",
       "#sk-container-id-7 div.sk-label.fitted input.sk-toggleable__control:checked~label.sk-toggleable__label {\n",
       "  background-color: var(--sklearn-color-fitted-level-2);\n",
       "}\n",
       "\n",
       "/* Estimator-specific style */\n",
       "\n",
       "/* Colorize estimator box */\n",
       "#sk-container-id-7 div.sk-estimator input.sk-toggleable__control:checked~label.sk-toggleable__label {\n",
       "  /* unfitted */\n",
       "  background-color: var(--sklearn-color-unfitted-level-2);\n",
       "}\n",
       "\n",
       "#sk-container-id-7 div.sk-estimator.fitted input.sk-toggleable__control:checked~label.sk-toggleable__label {\n",
       "  /* fitted */\n",
       "  background-color: var(--sklearn-color-fitted-level-2);\n",
       "}\n",
       "\n",
       "#sk-container-id-7 div.sk-label label.sk-toggleable__label,\n",
       "#sk-container-id-7 div.sk-label label {\n",
       "  /* The background is the default theme color */\n",
       "  color: var(--sklearn-color-text-on-default-background);\n",
       "}\n",
       "\n",
       "/* On hover, darken the color of the background */\n",
       "#sk-container-id-7 div.sk-label:hover label.sk-toggleable__label {\n",
       "  color: var(--sklearn-color-text);\n",
       "  background-color: var(--sklearn-color-unfitted-level-2);\n",
       "}\n",
       "\n",
       "/* Label box, darken color on hover, fitted */\n",
       "#sk-container-id-7 div.sk-label.fitted:hover label.sk-toggleable__label.fitted {\n",
       "  color: var(--sklearn-color-text);\n",
       "  background-color: var(--sklearn-color-fitted-level-2);\n",
       "}\n",
       "\n",
       "/* Estimator label */\n",
       "\n",
       "#sk-container-id-7 div.sk-label label {\n",
       "  font-family: monospace;\n",
       "  font-weight: bold;\n",
       "  display: inline-block;\n",
       "  line-height: 1.2em;\n",
       "}\n",
       "\n",
       "#sk-container-id-7 div.sk-label-container {\n",
       "  text-align: center;\n",
       "}\n",
       "\n",
       "/* Estimator-specific */\n",
       "#sk-container-id-7 div.sk-estimator {\n",
       "  font-family: monospace;\n",
       "  border: 1px dotted var(--sklearn-color-border-box);\n",
       "  border-radius: 0.25em;\n",
       "  box-sizing: border-box;\n",
       "  margin-bottom: 0.5em;\n",
       "  /* unfitted */\n",
       "  background-color: var(--sklearn-color-unfitted-level-0);\n",
       "}\n",
       "\n",
       "#sk-container-id-7 div.sk-estimator.fitted {\n",
       "  /* fitted */\n",
       "  background-color: var(--sklearn-color-fitted-level-0);\n",
       "}\n",
       "\n",
       "/* on hover */\n",
       "#sk-container-id-7 div.sk-estimator:hover {\n",
       "  /* unfitted */\n",
       "  background-color: var(--sklearn-color-unfitted-level-2);\n",
       "}\n",
       "\n",
       "#sk-container-id-7 div.sk-estimator.fitted:hover {\n",
       "  /* fitted */\n",
       "  background-color: var(--sklearn-color-fitted-level-2);\n",
       "}\n",
       "\n",
       "/* Specification for estimator info (e.g. \"i\" and \"?\") */\n",
       "\n",
       "/* Common style for \"i\" and \"?\" */\n",
       "\n",
       ".sk-estimator-doc-link,\n",
       "a:link.sk-estimator-doc-link,\n",
       "a:visited.sk-estimator-doc-link {\n",
       "  float: right;\n",
       "  font-size: smaller;\n",
       "  line-height: 1em;\n",
       "  font-family: monospace;\n",
       "  background-color: var(--sklearn-color-background);\n",
       "  border-radius: 1em;\n",
       "  height: 1em;\n",
       "  width: 1em;\n",
       "  text-decoration: none !important;\n",
       "  margin-left: 0.5em;\n",
       "  text-align: center;\n",
       "  /* unfitted */\n",
       "  border: var(--sklearn-color-unfitted-level-1) 1pt solid;\n",
       "  color: var(--sklearn-color-unfitted-level-1);\n",
       "}\n",
       "\n",
       ".sk-estimator-doc-link.fitted,\n",
       "a:link.sk-estimator-doc-link.fitted,\n",
       "a:visited.sk-estimator-doc-link.fitted {\n",
       "  /* fitted */\n",
       "  border: var(--sklearn-color-fitted-level-1) 1pt solid;\n",
       "  color: var(--sklearn-color-fitted-level-1);\n",
       "}\n",
       "\n",
       "/* On hover */\n",
       "div.sk-estimator:hover .sk-estimator-doc-link:hover,\n",
       ".sk-estimator-doc-link:hover,\n",
       "div.sk-label-container:hover .sk-estimator-doc-link:hover,\n",
       ".sk-estimator-doc-link:hover {\n",
       "  /* unfitted */\n",
       "  background-color: var(--sklearn-color-unfitted-level-3);\n",
       "  color: var(--sklearn-color-background);\n",
       "  text-decoration: none;\n",
       "}\n",
       "\n",
       "div.sk-estimator.fitted:hover .sk-estimator-doc-link.fitted:hover,\n",
       ".sk-estimator-doc-link.fitted:hover,\n",
       "div.sk-label-container:hover .sk-estimator-doc-link.fitted:hover,\n",
       ".sk-estimator-doc-link.fitted:hover {\n",
       "  /* fitted */\n",
       "  background-color: var(--sklearn-color-fitted-level-3);\n",
       "  color: var(--sklearn-color-background);\n",
       "  text-decoration: none;\n",
       "}\n",
       "\n",
       "/* Span, style for the box shown on hovering the info icon */\n",
       ".sk-estimator-doc-link span {\n",
       "  display: none;\n",
       "  z-index: 9999;\n",
       "  position: relative;\n",
       "  font-weight: normal;\n",
       "  right: .2ex;\n",
       "  padding: .5ex;\n",
       "  margin: .5ex;\n",
       "  width: min-content;\n",
       "  min-width: 20ex;\n",
       "  max-width: 50ex;\n",
       "  color: var(--sklearn-color-text);\n",
       "  box-shadow: 2pt 2pt 4pt #999;\n",
       "  /* unfitted */\n",
       "  background: var(--sklearn-color-unfitted-level-0);\n",
       "  border: .5pt solid var(--sklearn-color-unfitted-level-3);\n",
       "}\n",
       "\n",
       ".sk-estimator-doc-link.fitted span {\n",
       "  /* fitted */\n",
       "  background: var(--sklearn-color-fitted-level-0);\n",
       "  border: var(--sklearn-color-fitted-level-3);\n",
       "}\n",
       "\n",
       ".sk-estimator-doc-link:hover span {\n",
       "  display: block;\n",
       "}\n",
       "\n",
       "/* \"?\"-specific style due to the `<a>` HTML tag */\n",
       "\n",
       "#sk-container-id-7 a.estimator_doc_link {\n",
       "  float: right;\n",
       "  font-size: 1rem;\n",
       "  line-height: 1em;\n",
       "  font-family: monospace;\n",
       "  background-color: var(--sklearn-color-background);\n",
       "  border-radius: 1rem;\n",
       "  height: 1rem;\n",
       "  width: 1rem;\n",
       "  text-decoration: none;\n",
       "  /* unfitted */\n",
       "  color: var(--sklearn-color-unfitted-level-1);\n",
       "  border: var(--sklearn-color-unfitted-level-1) 1pt solid;\n",
       "}\n",
       "\n",
       "#sk-container-id-7 a.estimator_doc_link.fitted {\n",
       "  /* fitted */\n",
       "  border: var(--sklearn-color-fitted-level-1) 1pt solid;\n",
       "  color: var(--sklearn-color-fitted-level-1);\n",
       "}\n",
       "\n",
       "/* On hover */\n",
       "#sk-container-id-7 a.estimator_doc_link:hover {\n",
       "  /* unfitted */\n",
       "  background-color: var(--sklearn-color-unfitted-level-3);\n",
       "  color: var(--sklearn-color-background);\n",
       "  text-decoration: none;\n",
       "}\n",
       "\n",
       "#sk-container-id-7 a.estimator_doc_link.fitted:hover {\n",
       "  /* fitted */\n",
       "  background-color: var(--sklearn-color-fitted-level-3);\n",
       "}\n",
       "\n",
       ".estimator-table summary {\n",
       "    padding: .5rem;\n",
       "    font-family: monospace;\n",
       "    cursor: pointer;\n",
       "}\n",
       "\n",
       ".estimator-table details[open] {\n",
       "    padding-left: 0.1rem;\n",
       "    padding-right: 0.1rem;\n",
       "    padding-bottom: 0.3rem;\n",
       "}\n",
       "\n",
       ".estimator-table .parameters-table {\n",
       "    margin-left: auto !important;\n",
       "    margin-right: auto !important;\n",
       "}\n",
       "\n",
       ".estimator-table .parameters-table tr:nth-child(odd) {\n",
       "    background-color: #fff;\n",
       "}\n",
       "\n",
       ".estimator-table .parameters-table tr:nth-child(even) {\n",
       "    background-color: #f6f6f6;\n",
       "}\n",
       "\n",
       ".estimator-table .parameters-table tr:hover {\n",
       "    background-color: #e0e0e0;\n",
       "}\n",
       "\n",
       ".estimator-table table td {\n",
       "    border: 1px solid rgba(106, 105, 104, 0.232);\n",
       "}\n",
       "\n",
       ".user-set td {\n",
       "    color:rgb(255, 94, 0);\n",
       "    text-align: left;\n",
       "}\n",
       "\n",
       ".user-set td.value pre {\n",
       "    color:rgb(255, 94, 0) !important;\n",
       "    background-color: transparent !important;\n",
       "}\n",
       "\n",
       ".default td {\n",
       "    color: black;\n",
       "    text-align: left;\n",
       "}\n",
       "\n",
       ".user-set td i,\n",
       ".default td i {\n",
       "    color: black;\n",
       "}\n",
       "\n",
       ".copy-paste-icon {\n",
       "    background-image: url(data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHZpZXdCb3g9IjAgMCA0NDggNTEyIj48IS0tIUZvbnQgQXdlc29tZSBGcmVlIDYuNy4yIGJ5IEBmb250YXdlc29tZSAtIGh0dHBzOi8vZm9udGF3ZXNvbWUuY29tIExpY2Vuc2UgLSBodHRwczovL2ZvbnRhd2Vzb21lLmNvbS9saWNlbnNlL2ZyZWUgQ29weXJpZ2h0IDIwMjUgRm9udGljb25zLCBJbmMuLS0+PHBhdGggZD0iTTIwOCAwTDMzMi4xIDBjMTIuNyAwIDI0LjkgNS4xIDMzLjkgMTQuMWw2Ny45IDY3LjljOSA5IDE0LjEgMjEuMiAxNC4xIDMzLjlMNDQ4IDMzNmMwIDI2LjUtMjEuNSA0OC00OCA0OGwtMTkyIDBjLTI2LjUgMC00OC0yMS41LTQ4LTQ4bDAtMjg4YzAtMjYuNSAyMS41LTQ4IDQ4LTQ4ek00OCAxMjhsODAgMCAwIDY0LTY0IDAgMCAyNTYgMTkyIDAgMC0zMiA2NCAwIDAgNDhjMCAyNi41LTIxLjUgNDgtNDggNDhMNDggNTEyYy0yNi41IDAtNDgtMjEuNS00OC00OEwwIDE3NmMwLTI2LjUgMjEuNS00OCA0OC00OHoiLz48L3N2Zz4=);\n",
       "    background-repeat: no-repeat;\n",
       "    background-size: 14px 14px;\n",
       "    background-position: 0;\n",
       "    display: inline-block;\n",
       "    width: 14px;\n",
       "    height: 14px;\n",
       "    cursor: pointer;\n",
       "}\n",
       "</style><body><div id=\"sk-container-id-7\" class=\"sk-top-container\"><div class=\"sk-text-repr-fallback\"><pre>MultinomialNB()</pre><b>In a Jupyter environment, please rerun this cell to show the HTML representation or trust the notebook. <br />On GitHub, the HTML representation is unable to render, please try loading this page with nbviewer.org.</b></div><div class=\"sk-container\" hidden><div class=\"sk-item\"><div class=\"sk-estimator fitted sk-toggleable\"><input class=\"sk-toggleable__control sk-hidden--visually\" id=\"sk-estimator-id-7\" type=\"checkbox\" checked><label for=\"sk-estimator-id-7\" class=\"sk-toggleable__label fitted sk-toggleable__label-arrow\"><div><div>MultinomialNB</div></div><div><a class=\"sk-estimator-doc-link fitted\" rel=\"noreferrer\" target=\"_blank\" href=\"https://scikit-learn.org/1.7/modules/generated/sklearn.naive_bayes.MultinomialNB.html\">?<span>Documentation for MultinomialNB</span></a><span class=\"sk-estimator-doc-link fitted\">i<span>Fitted</span></span></div></label><div class=\"sk-toggleable__content fitted\" data-param-prefix=\"\">\n",
       "        <div class=\"estimator-table\">\n",
       "            <details>\n",
       "                <summary>Parameters</summary>\n",
       "                <table class=\"parameters-table\">\n",
       "                  <tbody>\n",
       "                    \n",
       "        <tr class=\"default\">\n",
       "            <td><i class=\"copy-paste-icon\"\n",
       "                 onclick=\"copyToClipboard('alpha',\n",
       "                          this.parentElement.nextElementSibling)\"\n",
       "            ></i></td>\n",
       "            <td class=\"param\">alpha&nbsp;</td>\n",
       "            <td class=\"value\">1.0</td>\n",
       "        </tr>\n",
       "    \n",
       "\n",
       "        <tr class=\"default\">\n",
       "            <td><i class=\"copy-paste-icon\"\n",
       "                 onclick=\"copyToClipboard('force_alpha',\n",
       "                          this.parentElement.nextElementSibling)\"\n",
       "            ></i></td>\n",
       "            <td class=\"param\">force_alpha&nbsp;</td>\n",
       "            <td class=\"value\">True</td>\n",
       "        </tr>\n",
       "    \n",
       "\n",
       "        <tr class=\"default\">\n",
       "            <td><i class=\"copy-paste-icon\"\n",
       "                 onclick=\"copyToClipboard('fit_prior',\n",
       "                          this.parentElement.nextElementSibling)\"\n",
       "            ></i></td>\n",
       "            <td class=\"param\">fit_prior&nbsp;</td>\n",
       "            <td class=\"value\">True</td>\n",
       "        </tr>\n",
       "    \n",
       "\n",
       "        <tr class=\"default\">\n",
       "            <td><i class=\"copy-paste-icon\"\n",
       "                 onclick=\"copyToClipboard('class_prior',\n",
       "                          this.parentElement.nextElementSibling)\"\n",
       "            ></i></td>\n",
       "            <td class=\"param\">class_prior&nbsp;</td>\n",
       "            <td class=\"value\">None</td>\n",
       "        </tr>\n",
       "    \n",
       "                  </tbody>\n",
       "                </table>\n",
       "            </details>\n",
       "        </div>\n",
       "    </div></div></div></div></div><script>function copyToClipboard(text, element) {\n",
       "    // Get the parameter prefix from the closest toggleable content\n",
       "    const toggleableContent = element.closest('.sk-toggleable__content');\n",
       "    const paramPrefix = toggleableContent ? toggleableContent.dataset.paramPrefix : '';\n",
       "    const fullParamName = paramPrefix ? `${paramPrefix}${text}` : text;\n",
       "\n",
       "    const originalStyle = element.style;\n",
       "    const computedStyle = window.getComputedStyle(element);\n",
       "    const originalWidth = computedStyle.width;\n",
       "    const originalHTML = element.innerHTML.replace('Copied!', '');\n",
       "\n",
       "    navigator.clipboard.writeText(fullParamName)\n",
       "        .then(() => {\n",
       "            element.style.width = originalWidth;\n",
       "            element.style.color = 'green';\n",
       "            element.innerHTML = \"Copied!\";\n",
       "\n",
       "            setTimeout(() => {\n",
       "                element.innerHTML = originalHTML;\n",
       "                element.style = originalStyle;\n",
       "            }, 2000);\n",
       "        })\n",
       "        .catch(err => {\n",
       "            console.error('Failed to copy:', err);\n",
       "            element.style.color = 'red';\n",
       "            element.innerHTML = \"Failed!\";\n",
       "            setTimeout(() => {\n",
       "                element.innerHTML = originalHTML;\n",
       "                element.style = originalStyle;\n",
       "            }, 2000);\n",
       "        });\n",
       "    return false;\n",
       "}\n",
       "\n",
       "document.querySelectorAll('.fa-regular.fa-copy').forEach(function(element) {\n",
       "    const toggleableContent = element.closest('.sk-toggleable__content');\n",
       "    const paramPrefix = toggleableContent ? toggleableContent.dataset.paramPrefix : '';\n",
       "    const paramName = element.parentElement.nextElementSibling.textContent.trim();\n",
       "    const fullParamName = paramPrefix ? `${paramPrefix}${paramName}` : paramName;\n",
       "\n",
       "    element.setAttribute('title', fullParamName);\n",
       "});\n",
       "</script></body>"
      ],
      "text/plain": [
       "MultinomialNB()"
      ]
     },
     "execution_count": 106,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "naive_bayes = MultinomialNB()\n",
    "naive_bayes.fit(x_train_final, y_train)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 107,
   "id": "df94785e-861c-4e62-b8b5-35b64567851a",
   "metadata": {},
   "outputs": [],
   "source": [
    "y_pred = naive_bayes.predict(x_test_final)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 108,
   "id": "80e13b74-7a12-493b-81ca-dd767c696400",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Akurasi Model Naive Bayes :  0.8855098389982111\n",
      "\n",
      "Laporan Klasifikasi :\n",
      "               precision    recall  f1-score   support\n",
      "\n",
      "     Negatif       0.85      0.94      0.89       572\n",
      "     Positif       0.93      0.83      0.88       546\n",
      "\n",
      "    accuracy                           0.89      1118\n",
      "   macro avg       0.89      0.88      0.88      1118\n",
      "weighted avg       0.89      0.89      0.89      1118\n",
      "\n"
     ]
    },
    {
     "data": {
      "text/plain": [
       "<Figure size 600x500 with 0 Axes>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    },
    {
     "data": {
      "image/png": "[encoded data, 24672 characters]",
      "text/plain": [
       "<Figure size 640x480 with 2 Axes>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    }
   ],
   "source": [
    "accuracy = accuracy_score(y_test, y_pred)\n",
    "classification_rep = classification_report(y_test, y_pred, target_names=['Negatif', 'Positif'])\n",
    "cm = confusion_matrix(y_test, y_pred)\n",
    "\n",
    "print(\"Akurasi Model Naive Bayes : \", accuracy)\n",
    "print(\"\\nLaporan Klasifikasi :\\n\", classification_rep)\n",
    "\n",
    "# Visualisasi confusion matrix\n",
    "plt.figure(figsize=(6, 5))\n",
    "disp = ConfusionMatrixDisplay(confusion_matrix=cm, display_labels=['Negatif', 'Positif'])\n",
    "disp.plot(cmap='Blues', values_format='d')\n",
    "plt.title(\"Confusion Matrix Naive Bayes\")\n",
    "plt.xlabel(\"Prediksi\")\n",
    "plt.ylabel(\"Aktual\")\n",
    "plt.show()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 98,
   "id": "a59a00c9-a9dd-46ff-b16d-ba5d3c5526ba",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "✅ Model, Vectorizer, dan Encoder berhasil disimpan!\n"
     ]
    }
   ],
   "source": [
    "# Simpan model dan vectorizer ke file .pkl\n",
    "joblib.dump(naive_bayes, 'naive_bayes_model.pkl')\n",
    "joblib.dump(vectorizer, 'tfidf_vectorizer.pkl')\n",
    "joblib.dump(encoder, 'category_encoder.pkl')\n",
    "\n",
    "print(\"✅ Model, Vectorizer, dan Encoder berhasil disimpan!\")"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "a0eb3f86-4c12-40d9-9c52-3f8b2b161294",
   "metadata": {},
   "outputs": [],
   "source": []
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "b02423d4-baed-4144-b75e-09a81c8a6b57",
   "metadata": {},
   "outputs": [],
   "source": []
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "Python 3 (ipykernel)",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.13.7"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 5
}
