{
 "cells": [
  {
   "cell_type": "code",
   "execution_count": 3,
   "id": "f99c6d70-18cc-4b96-89e3-7956e389df3c",
   "metadata": {},
   "outputs": [],
   "source": [
    "import pandas as pd\n",
    "import numpy as np\n",
    "import re\n",
    "import string\n",
    "\n",
    "from sklearn.model_selection import train_test_split\n",
    "from sklearn.feature_extraction.text import TfidfVectorizer\n",
    "from sklearn.linear_model import LogisticRegression\n",
    "from sklearn.svm import LinearSVC\n",
    "from sklearn.metrics import classification_report, accuracy_score, f1_score\n",
    "from sklearn.utils.class_weight import compute_class_weight\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 4,
   "id": "fb09003c-e258-4add-baa0-24e49a6c46a4",
   "metadata": {},
   "outputs": [
    {
     "ename": "SyntaxError",
     "evalue": "(unicode error) 'unicodeescape' codec can't decode bytes in position 2-3: truncated \\UXXXXXXXX escape (1851046779.py, line 2)",
     "output_type": "error",
     "traceback": [
      "\u001b[1;36m  Cell \u001b[1;32mIn[4], line 2\u001b[1;36m\u001b[0m\n\u001b[1;33m    df = pd.read_csv(\"C:\\Users\\khh26\\Downloads\\archive (11)\\unbalanceddataset.csv\")\u001b[0m\n\u001b[1;37m                     ^\u001b[0m\n\u001b[1;31mSyntaxError\u001b[0m\u001b[1;31m:\u001b[0m (unicode error) 'unicodeescape' codec can't decode bytes in position 2-3: truncated \\UXXXXXXXX escape\n"
     ]
    }
   ],
   "source": [
    "# Load dataset\n",
    "df = pd.read_csv(\"C:\\Users\\khh26\\Downloads\\archive (11)\\unbalanceddataset.csv\")\n",
    "\n",
    "df.head()\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 5,
   "id": "f086ba60-ce92-4ae2-999d-f33ff1d47c42",
   "metadata": {},
   "outputs": [
    {
     "ename": "SyntaxError",
     "evalue": "(unicode error) 'unicodeescape' codec can't decode bytes in position 2-3: truncated \\UXXXXXXXX escape (4024888092.py, line 2)",
     "output_type": "error",
     "traceback": [
      "\u001b[1;36m  Cell \u001b[1;32mIn[5], line 2\u001b[1;36m\u001b[0m\n\u001b[1;33m    df = pd.read_csv(\"C:\\Users\\khh26\\Downloads\\unbalanceddataset.csv\")\u001b[0m\n\u001b[1;37m                     ^\u001b[0m\n\u001b[1;31mSyntaxError\u001b[0m\u001b[1;31m:\u001b[0m (unicode error) 'unicodeescape' codec can't decode bytes in position 2-3: truncated \\UXXXXXXXX escape\n"
     ]
    }
   ],
   "source": [
    "# Load dataset\n",
    "df = pd.read_csv(\"C:\\Users\\khh26\\Downloads\\unbalanceddataset.csv\")\n",
    "\n",
    "df.head()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "a6cf0794-6fa7-4bcf-bc0d-64c8ed1f3686",
   "metadata": {},
   "outputs": [],
   "source": []
  },
  {
   "cell_type": "code",
   "execution_count": 6,
   "id": "fd84757b-ab68-423c-9c98-248ac9afda19",
   "metadata": {},
   "outputs": [],
   "source": [
    "df = pd.read_csv(r\"C:\\Users\\khh26\\Downloads\\unbalanceddataset.csv\")\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 7,
   "id": "6dacd800-d14b-45c9-9fba-d5e4b22cf5a1",
   "metadata": {},
   "outputs": [],
   "source": [
    "def preprocess_text(text):\n",
    "    text = text.lower()\n",
    "    text = re.sub(r\"http\\S+|www\\S+\", \" \", text)  # remove URLs\n",
    "    text = re.sub(r\"<.*?>\", \" \", text)           # remove HTML\n",
    "    text = text.translate(str.maketrans(\"\", \"\", string.punctuation))\n",
    "    text = re.sub(r\"\\s+\", \" \", text).strip()\n",
    "    return text\n",
    "\n",
    "df[\"clean_text\"] = df[\"text\"].astype(str).apply(preprocess_text)\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 8,
   "id": "4b2c73f6-5f46-4258-98ab-9da6f3ed443c",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "sentiment\n",
       "positive    2000\n",
       "negative     600\n",
       "Name: count, dtype: int64"
      ]
     },
     "execution_count": 8,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "df[\"sentiment\"].value_counts()\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 9,
   "id": "e34c4117-b93b-4a8b-afc8-e8e756b87adb",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "sentiment\n",
       "positive    2000\n",
       "negative     600\n",
       "Name: count, dtype: int64"
      ]
     },
     "execution_count": 9,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "df[\"sentiment\"].value_counts()\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 12,
   "id": "28745935-a022-48b2-890f-5478902519fa",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "Index(['text', 'sentiment', 'clean_text'], dtype='object')"
      ]
     },
     "execution_count": 12,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "df.columns\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 13,
   "id": "2fa9b278-87d6-4fc5-9b05-68fb8a43f3d8",
   "metadata": {},
   "outputs": [],
   "source": [
    "label_map = {\"negative\": 0, \"positive\": 1}\n",
    "df[\"label\"] = df[\"sentiment\"].map(label_map)\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 14,
   "id": "824bbf62-6894-49be-89dd-85c75ef23c07",
   "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>sentiment</th>\n",
       "      <th>label</th>\n",
       "    </tr>\n",
       "  </thead>\n",
       "  <tbody>\n",
       "    <tr>\n",
       "      <th>0</th>\n",
       "      <td>positive</td>\n",
       "      <td>1</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>1</th>\n",
       "      <td>positive</td>\n",
       "      <td>1</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>2</th>\n",
       "      <td>positive</td>\n",
       "      <td>1</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>3</th>\n",
       "      <td>negative</td>\n",
       "      <td>0</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>4</th>\n",
       "      <td>positive</td>\n",
       "      <td>1</td>\n",
       "    </tr>\n",
       "  </tbody>\n",
       "</table>\n",
       "</div>"
      ],
      "text/plain": [
       "  sentiment  label\n",
       "0  positive      1\n",
       "1  positive      1\n",
       "2  positive      1\n",
       "3  negative      0\n",
       "4  positive      1"
      ]
     },
     "execution_count": 14,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "df[[\"sentiment\", \"label\"]].head()\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 15,
   "id": "1ee50fc6-409d-4a53-8969-3da8b7fca756",
   "metadata": {},
   "outputs": [],
   "source": [
    "from sklearn.model_selection import train_test_split\n",
    "\n",
    "X_train, X_test, y_train, y_test = train_test_split(\n",
    "    df[\"clean_text\"],\n",
    "    df[\"label\"],\n",
    "    test_size=0.2,\n",
    "    random_state=42,\n",
    "    stratify=df[\"label\"]\n",
    ")\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 16,
   "id": "9bf94c91-b5e8-4e1b-994b-b15a260f4342",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "label\n",
       "1    0.769231\n",
       "0    0.230769\n",
       "Name: proportion, dtype: float64"
      ]
     },
     "execution_count": 16,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "y_train.value_counts(normalize=True)\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 19,
   "id": "38fab310-91af-4729-85c7-acbbe7735255",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "{0: np.float64(2.1666666666666665), 1: np.float64(0.65)}"
      ]
     },
     "execution_count": 19,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "import numpy as np\n",
    "from sklearn.utils.class_weight import compute_class_weight\n",
    "\n",
    "class_weights = compute_class_weight(\n",
    "    class_weight=\"balanced\",\n",
    "    classes=np.unique(y_train),\n",
    "    y=y_train\n",
    ")\n",
    "\n",
    "class_weight_dict = {\n",
    "    0: class_weights[0],\n",
    "    1: class_weights[1]\n",
    "}\n",
    "\n",
    "class_weight_dict\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 20,
   "id": "93e58b7d-4793-41ae-a60d-297c701bc520",
   "metadata": {},
   "outputs": [
    {
     "ename": "NameError",
     "evalue": "name 'X_train_tfidf' is not defined",
     "output_type": "error",
     "traceback": [
      "\u001b[1;31m---------------------------------------------------------------------------\u001b[0m",
      "\u001b[1;31mNameError\u001b[0m                                 Traceback (most recent call last)",
      "Cell \u001b[1;32mIn[20], line 4\u001b[0m\n\u001b[0;32m      1\u001b[0m \u001b[38;5;28;01mfrom\u001b[39;00m\u001b[38;5;250m \u001b[39m\u001b[38;5;21;01msklearn\u001b[39;00m\u001b[38;5;21;01m.\u001b[39;00m\u001b[38;5;21;01msvm\u001b[39;00m\u001b[38;5;250m \u001b[39m\u001b[38;5;28;01mimport\u001b[39;00m LinearSVC\n\u001b[0;32m      3\u001b[0m svm \u001b[38;5;241m=\u001b[39m LinearSVC(class_weight\u001b[38;5;241m=\u001b[39mclass_weight_dict)\n\u001b[1;32m----> 4\u001b[0m svm\u001b[38;5;241m.\u001b[39mfit(X_train_tfidf, y_train)\n\u001b[0;32m      6\u001b[0m y_pred_svm \u001b[38;5;241m=\u001b[39m svm\u001b[38;5;241m.\u001b[39mpredict(X_test_tfidf)\n",
      "\u001b[1;31mNameError\u001b[0m: name 'X_train_tfidf' is not defined"
     ]
    }
   ],
   "source": [
    "from sklearn.svm import LinearSVC\n",
    "\n",
    "svm = LinearSVC(class_weight=class_weight_dict)\n",
    "svm.fit(X_train_tfidf, y_train)\n",
    "\n",
    "y_pred_svm = svm.predict(X_test_tfidf)\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 21,
   "id": "121fe4a5-d77e-4cfb-a86a-c43a46db48bc",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "((2080, 15756), (520, 15756))"
      ]
     },
     "execution_count": 21,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "from sklearn.feature_extraction.text import TfidfVectorizer\n",
    "\n",
    "vectorizer = TfidfVectorizer(\n",
    "    ngram_range=(1, 2),\n",
    "    max_features=50000,\n",
    "    stop_words=\"english\",\n",
    "    sublinear_tf=True\n",
    ")\n",
    "\n",
    "X_train_tfidf = vectorizer.fit_transform(X_train)\n",
    "X_test_tfidf = vectorizer.transform(X_test)\n",
    "\n",
    "X_train_tfidf.shape, X_test_tfidf.shape\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 22,
   "id": "848e0ff3-3077-42af-a81a-b1440f55b710",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "{0: np.float64(2.1666666666666665), 1: np.float64(0.65)}"
      ]
     },
     "execution_count": 22,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "import numpy as np\n",
    "from sklearn.utils.class_weight import compute_class_weight\n",
    "\n",
    "class_weights = compute_class_weight(\n",
    "    class_weight=\"balanced\",\n",
    "    classes=np.unique(y_train),\n",
    "    y=y_train\n",
    ")\n",
    "\n",
    "class_weight_dict = {0: class_weights[0], 1: class_weights[1]}\n",
    "class_weight_dict\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 23,
   "id": "ccabdcf0-2b84-4a61-a69d-61849c175251",
   "metadata": {},
   "outputs": [],
   "source": [
    "from sklearn.svm import LinearSVC\n",
    "\n",
    "svm = LinearSVC(class_weight=class_weight_dict)\n",
    "svm.fit(X_train_tfidf, y_train)\n",
    "\n",
    "y_pred_svm = svm.predict(X_test_tfidf)\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 24,
   "id": "818a0609-a3d4-4a44-9d6b-31eb7e9ab0e8",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Accuracy: 0.8634615384615385\n",
      "Macro F1: 0.7858853686402097\n",
      "              precision    recall  f1-score   support\n",
      "\n",
      "           0       0.78      0.57      0.66       120\n",
      "           1       0.88      0.95      0.91       400\n",
      "\n",
      "    accuracy                           0.86       520\n",
      "   macro avg       0.83      0.76      0.79       520\n",
      "weighted avg       0.86      0.86      0.86       520\n",
      "\n"
     ]
    }
   ],
   "source": [
    "from sklearn.metrics import accuracy_score, f1_score, classification_report\n",
    "\n",
    "print(\"Accuracy:\", accuracy_score(y_test, y_pred_svm))\n",
    "print(\"Macro F1:\", f1_score(y_test, y_pred_svm, average=\"macro\"))\n",
    "print(classification_report(y_test, y_pred_svm))\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "4f7a38ab-cfcd-47dc-9a3a-89bfa2565b16",
   "metadata": {},
   "outputs": [],
   "source": []
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "Python (base)",
   "language": "python",
   "name": "base"
  },
  "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.5"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 5
}
