{
 "cells": [
  {
   "cell_type": "code",
   "execution_count": 1,
   "id": "4beb6c87",
   "metadata": {},
   "outputs": [
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "[nltk_data] Downloading package punkt to C:\\Users\\G\n",
      "[nltk_data]     InCase/nltk_data...\n",
      "[nltk_data]   Package punkt is already up-to-date!\n",
      "[nltk_data] Downloading package stopwords to C:\\Users\\G\n",
      "[nltk_data]     InCase/nltk_data...\n",
      "[nltk_data]   Package stopwords is already up-to-date!\n",
      "[nltk_data] Downloading package wordnet to C:\\Users\\G\n",
      "[nltk_data]     InCase/nltk_data...\n",
      "[nltk_data]   Package wordnet is already up-to-date!\n"
     ]
    },
    {
     "data": {
      "text/plain": [
       "True"
      ]
     },
     "execution_count": 1,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "import pandas as pd\n",
    "import numpy as np\n",
    "from sklearn.model_selection import train_test_split, GridSearchCV\n",
    "from sklearn.preprocessing import StandardScaler, LabelEncoder\n",
    "from sklearn.linear_model import LogisticRegression\n",
    "from sklearn.tree import DecisionTreeClassifier\n",
    "from sklearn.ensemble import RandomForestClassifier\n",
    "from sklearn.svm import SVC\n",
    "from sklearn.naive_bayes import GaussianNB\n",
    "from sklearn.neighbors import KNeighborsClassifier\n",
    "from sklearn.metrics import confusion_matrix, accuracy_score, precision_score, recall_score, f1_score, classification_report\n",
    "import matplotlib.pyplot as plt\n",
    "import seaborn as sns\n",
    "from sklearn.model_selection import GridSearchCV\n",
    "from sklearn.linear_model import LogisticRegression\n",
    "from sklearn.metrics import classification_report\n",
    "from sklearn.feature_extraction.text import TfidfVectorizer\n",
    "from sklearn.model_selection import train_test_split\n",
    "from sklearn.feature_extraction.text import CountVectorizer\n",
    "import re\n",
    "import nltk\n",
    "import spacy\n",
    "from nltk.corpus import stopwords\n",
    "from nltk.tokenize import word_tokenize\n",
    "from nltk.stem import PorterStemmer\n",
    "from nltk.stem import WordNetLemmatizer\n",
    "\n",
    "\n",
    "# Download NLTK resources (only first time)\n",
    "import nltk\n",
    "nltk.download('punkt')\n",
    "nltk.download('stopwords')\n",
    "nltk.download('wordnet')\n",
    "\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 2,
   "id": "2620db8d",
   "metadata": {},
   "outputs": [],
   "source": [
    "def evaluate_model(model_name, y_true, y_pred):\n",
    "    # Calculate metrics\n",
    "    accuracy = accuracy_score(y_true, y_pred)\n",
    "    precision = precision_score(y_true, y_pred, average='weighted')\n",
    "    recall = recall_score(y_true, y_pred, average='weighted')\n",
    "    f1 = f1_score(y_true, y_pred, average='weighted')\n",
    "    cm = confusion_matrix(y_true, y_pred)\n",
    "    \n",
    "    # Create a report\n",
    "    report = classification_report(y_true, y_pred)\n",
    "    \n",
    "    # Output results\n",
    "    metrics = {\n",
    "        'Model Name': model_name,\n",
    "        'Accuracy': accuracy,\n",
    "        'Precision': precision,\n",
    "        'Recall': recall,\n",
    "        'F1 Score': f1,\n",
    "        'Classification Report': report\n",
    "    }\n",
    "    \n",
    "    return metrics\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 3,
   "id": "34430d94",
   "metadata": {},
   "outputs": [],
   "source": [
    "from sklearn.ensemble import RandomForestClassifier\n",
    "from sklearn.model_selection import GridSearchCV\n",
    "\n",
    "def train_random_forest_classifier_with_grid_search(X_train_vec, y_train, X_test_vec, y_test, evaluate_model_func):\n",
    "    # Define the Random Forest Classifier\n",
    "    rf_classifier = RandomForestClassifier(random_state=42)\n",
    "    \n",
    "    # Define the hyperparameters for grid search\n",
    "    param_grid = {\n",
    "        'n_estimators': [100, 200, 300],\n",
    "        'max_depth': [None, 10, 20, 30],\n",
    "    }\n",
    "    \n",
    "    # Initialize GridSearchCV\n",
    "    grid_search = GridSearchCV(estimator=rf_classifier, param_grid=param_grid, cv=5,\n",
    "                               scoring='accuracy', n_jobs=-1)\n",
    "    \n",
    "    # Fit the grid search to the data\n",
    "    grid_search.fit(X_train_vec, y_train)\n",
    "    \n",
    "    # Get the best estimator from grid search\n",
    "    best_rf_classifier = grid_search.best_estimator_\n",
    "    \n",
    "    # Make predictions using the best model\n",
    "    y_pred = best_rf_classifier.predict(X_test_vec)\n",
    "    \n",
    "    # Evaluate the model\n",
    "    evaluation_results = evaluate_model_func('RandomForestClassifier', y_test, y_pred)\n",
    "    \n",
    "    # Print the evaluation results\n",
    "    for key, value in evaluation_results.items():\n",
    "        if key == 'Classification Report':\n",
    "            print(value)  # Print report separately for better readability\n",
    "        else:\n",
    "            print(f\"{key}: {value:.4f}\" if isinstance(value, float) else f\"{key}: \\n{value}\")\n",
    "    \n",
    "    # Print the best parameters found by grid search\n",
    "    print(\"\\nBest hyperparameters found by GridSearchCV:\")\n",
    "    print(grid_search.best_params_)\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 4,
   "id": "4b0b1ea5",
   "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>text</th>\n",
       "      <th>sentiment</th>\n",
       "    </tr>\n",
       "  </thead>\n",
       "  <tbody>\n",
       "    <tr>\n",
       "      <th>0</th>\n",
       "      <td>Java Concurrency in Practice is probably the b...</td>\n",
       "      <td>positive</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>1</th>\n",
       "      <td>haha aww hun i bet you are more creative tha...</td>\n",
       "      <td>positive</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>2</th>\n",
       "      <td>_pickle lol, thank you very much Hope you`re h...</td>\n",
       "      <td>positive</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>3</th>\n",
       "      <td>Out for an evening on the town with jeremy. Sa...</td>\n",
       "      <td>negative</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>4</th>\n",
       "      <td>- just took over the #1 Most Endorsed spot on...</td>\n",
       "      <td>positive</td>\n",
       "    </tr>\n",
       "  </tbody>\n",
       "</table>\n",
       "</div>"
      ],
      "text/plain": [
       "                                                text sentiment\n",
       "0  Java Concurrency in Practice is probably the b...  positive\n",
       "1    haha aww hun i bet you are more creative tha...  positive\n",
       "2  _pickle lol, thank you very much Hope you`re h...  positive\n",
       "3  Out for an evening on the town with jeremy. Sa...  negative\n",
       "4   - just took over the #1 Most Endorsed spot on...  positive"
      ]
     },
     "execution_count": 4,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "df = pd.read_csv(\"unbalanceddataset.csv\")\n",
    "df.head()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 5,
   "id": "dfb1eeb1",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "sentiment\n",
       "positive    2000\n",
       "negative     600\n",
       "Name: count, dtype: int64"
      ]
     },
     "execution_count": 5,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "df['sentiment'].value_counts()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 6,
   "id": "880d6283",
   "metadata": {},
   "outputs": [
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "[nltk_data] Downloading package punkt to C:/nltk_data...\n",
      "[nltk_data]   Package punkt is already up-to-date!\n",
      "[nltk_data] Downloading package stopwords to C:/nltk_data...\n",
      "[nltk_data]   Package stopwords is already up-to-date!\n",
      "[nltk_data] Downloading package wordnet to C:/nltk_data...\n",
      "[nltk_data]   Package wordnet is already up-to-date!\n"
     ]
    }
   ],
   "source": [
    "import nltk\n",
    "\n",
    "nltk.download('punkt', download_dir='C:/nltk_data')\n",
    "nltk.download('stopwords', download_dir='C:/nltk_data')\n",
    "nltk.download('wordnet', download_dir='C:/nltk_data')\n",
    "\n",
    "nltk.data.path.append('C:/nltk_data')\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 7,
   "id": "877c69ad",
   "metadata": {},
   "outputs": [
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "[nltk_data] Downloading package punkt to C:\\Users\\G\n",
      "[nltk_data]     InCase/nltk_data...\n",
      "[nltk_data]   Package punkt is already up-to-date!\n"
     ]
    },
    {
     "data": {
      "text/plain": [
       "True"
      ]
     },
     "execution_count": 7,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "import nltk\n",
    "nltk.download('punkt')\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 8,
   "id": "b95ff2e9",
   "metadata": {},
   "outputs": [],
   "source": [
    "import nltk\n",
    "nltk.data.path.append('C:/nltk_data')\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 9,
   "id": "28bdaac9",
   "metadata": {},
   "outputs": [],
   "source": [
    "stemmer = PorterStemmer()\n",
    "stop_words = set(stopwords.words('english'))\n",
    "\n",
    "def preprocess_text(text):\n",
    "    text = text.lower()\n",
    "    text = re.sub(r'http\\S+|www.\\S+', '', text)\n",
    "    text = re.sub(r'<.*?>', '', text)\n",
    "    text = re.sub(r'[^a-zA-Z\\s]', '', text)\n",
    "    tokens = word_tokenize(text)\n",
    "    tokens = [word for word in tokens if word not in stop_words]\n",
    "    stemmed_tokens = [stemmer.stem(word) for word in tokens]\n",
    "    clean_text = ' '.join(stemmed_tokens)\n",
    "    return clean_text\n",
    "\n",
    "\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 12,
   "id": "a1afe15f",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "['C:\\\\Users\\\\G InCase/nltk_data', 'd:\\\\Downloads\\\\ANACONDA\\\\envs\\\\FinalProject\\\\nltk_data', 'd:\\\\Downloads\\\\ANACONDA\\\\envs\\\\FinalProject\\\\share\\\\nltk_data', 'd:\\\\Downloads\\\\ANACONDA\\\\envs\\\\FinalProject\\\\lib\\\\nltk_data', 'C:\\\\Users\\\\G InCase\\\\AppData\\\\Roaming\\\\nltk_data', 'C:\\\\nltk_data', 'D:\\\\nltk_data', 'E:\\\\nltk_data', 'C:/nltk_data', 'C:/nltk_data']\n"
     ]
    }
   ],
   "source": [
    "import nltk\n",
    "print(nltk.data.path)\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 14,
   "id": "a86c29e2",
   "metadata": {},
   "outputs": [
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "[nltk_data] Downloading package punkt to C:/nltk_data...\n",
      "[nltk_data]   Unzipping tokenizers\\punkt.zip.\n",
      "[nltk_data] Downloading package stopwords to C:/nltk_data...\n",
      "[nltk_data]   Unzipping corpora\\stopwords.zip.\n",
      "[nltk_data] Downloading package wordnet to C:/nltk_data...\n"
     ]
    }
   ],
   "source": [
    "nltk.download('punkt', download_dir='C:/nltk_data')\n",
    "nltk.download('stopwords', download_dir='C:/nltk_data')\n",
    "nltk.download('wordnet', download_dir='C:/nltk_data')\n",
    "nltk.data.path.append('C:/nltk_data')\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 16,
   "id": "768b19cc",
   "metadata": {},
   "outputs": [],
   "source": [
    "from nltk.tokenize import word_tokenize\n",
    "from nltk.corpus import stopwords\n",
    "from nltk.stem import PorterStemmer\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 19,
   "id": "fe2c6297",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "0       java concurrency in practice is probably the b...\n",
       "1         haha aww hun i bet you are more creative tha...\n",
       "2       pickle lol thank you very much hope youre havi...\n",
       "3       out for an evening on the town with jeremy sad...\n",
       "4         just took over the  most endorsed spot on tw...\n",
       "                              ...                        \n",
       "2595    whats up yall i made it an early night  i thin...\n",
       "2596                                              i agree\n",
       "2597                                    yeah it is thanks\n",
       "2598                                good morning everyone\n",
       "2599      and em my baby starts kindergarten  what a c...\n",
       "Name: clean_text, Length: 2600, dtype: object"
      ]
     },
     "execution_count": 19,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "df = pd.read_csv(\"unbalanceddataset.csv\")\n",
    "\n",
    "def preprocess_text(text):\n",
    "    text = text.lower()\n",
    "    text = re.sub(r'http\\S+|www.\\S+', '', text)\n",
    "    text = re.sub(r'<.*?>', '', text)\n",
    "    text = re.sub(r'[^a-zA-Z\\s]', '', text)\n",
    "    return text\n",
    "\n",
    "df[\"clean_text\"] = df[\"text\"].apply(preprocess_text)\n",
    "df = df.dropna()\n",
    "\n",
    "df['clean_text']\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 20,
   "id": "c3dedd88",
   "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>text</th>\n",
       "      <th>sentiment</th>\n",
       "      <th>clean_text</th>\n",
       "    </tr>\n",
       "  </thead>\n",
       "  <tbody>\n",
       "    <tr>\n",
       "      <th>0</th>\n",
       "      <td>Java Concurrency in Practice is probably the b...</td>\n",
       "      <td>positive</td>\n",
       "      <td>java concurrency in practice is probably the b...</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>1</th>\n",
       "      <td>haha aww hun i bet you are more creative tha...</td>\n",
       "      <td>positive</td>\n",
       "      <td>haha aww hun i bet you are more creative tha...</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>2</th>\n",
       "      <td>_pickle lol, thank you very much Hope you`re h...</td>\n",
       "      <td>positive</td>\n",
       "      <td>pickle lol thank you very much hope youre havi...</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>3</th>\n",
       "      <td>Out for an evening on the town with jeremy. Sa...</td>\n",
       "      <td>negative</td>\n",
       "      <td>out for an evening on the town with jeremy sad...</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>4</th>\n",
       "      <td>- just took over the #1 Most Endorsed spot on...</td>\n",
       "      <td>positive</td>\n",
       "      <td>just took over the  most endorsed spot on tw...</td>\n",
       "    </tr>\n",
       "  </tbody>\n",
       "</table>\n",
       "</div>"
      ],
      "text/plain": [
       "                                                text sentiment  \\\n",
       "0  Java Concurrency in Practice is probably the b...  positive   \n",
       "1    haha aww hun i bet you are more creative tha...  positive   \n",
       "2  _pickle lol, thank you very much Hope you`re h...  positive   \n",
       "3  Out for an evening on the town with jeremy. Sa...  negative   \n",
       "4   - just took over the #1 Most Endorsed spot on...  positive   \n",
       "\n",
       "                                          clean_text  \n",
       "0  java concurrency in practice is probably the b...  \n",
       "1    haha aww hun i bet you are more creative tha...  \n",
       "2  pickle lol thank you very much hope youre havi...  \n",
       "3  out for an evening on the town with jeremy sad...  \n",
       "4    just took over the  most endorsed spot on tw...  "
      ]
     },
     "execution_count": 20,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "df.head()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 22,
   "id": "a1edeebf",
   "metadata": {},
   "outputs": [],
   "source": [
    "X = df['clean_text'] \n",
    "y = df['sentiment']"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 24,
   "id": "179c36f9",
   "metadata": {},
   "outputs": [],
   "source": [
    "X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.30, random_state=42, stratify=y)\n",
    "\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 25,
   "id": "af08ab5e",
   "metadata": {},
   "outputs": [],
   "source": [
    "vectorizer = TfidfVectorizer()\n",
    "X_train_vec = vectorizer.fit_transform(X_train)\n",
    "X_test_vec = vectorizer.transform(X_test)\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 26,
   "id": "c257eca0",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Model Name: \n",
      "RandomForestClassifier\n",
      "Accuracy: 0.8308\n",
      "Precision: 0.8298\n",
      "Recall: 0.8308\n",
      "F1 Score: 0.8023\n",
      "              precision    recall  f1-score   support\n",
      "\n",
      "    negative       0.82      0.34      0.48       180\n",
      "    positive       0.83      0.98      0.90       600\n",
      "\n",
      "    accuracy                           0.83       780\n",
      "   macro avg       0.83      0.66      0.69       780\n",
      "weighted avg       0.83      0.83      0.80       780\n",
      "\n",
      "\n",
      "Best hyperparameters found by GridSearchCV:\n",
      "{'max_depth': None, 'n_estimators': 100}\n"
     ]
    }
   ],
   "source": [
    "train_random_forest_classifier_with_grid_search(X_train_vec, y_train, X_test_vec, y_test, evaluate_model)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 27,
   "id": "edfeabc3",
   "metadata": {},
   "outputs": [],
   "source": [
    "X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.30, random_state=42, stratify=y)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 28,
   "id": "8a70588a",
   "metadata": {},
   "outputs": [],
   "source": [
    "vectorizer = TfidfVectorizer() \n",
    "X_train_vec = vectorizer.fit_transform(X_train)\n",
    "X_test_vec = vectorizer.transform(X_test)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 30,
   "id": "68356bf0",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "After RandomOversampling: Counter({'positive': 1400, 'negative': 1400})\n"
     ]
    }
   ],
   "source": [
    "from imblearn.over_sampling import RandomOverSampler\n",
    "from collections import Counter\n",
    "\n",
    "ros = RandomOverSampler(random_state=42)\n",
    "X_ros, y_ros = ros.fit_resample(X_train_vec, y_train)\n",
    "\n",
    "print(\"After RandomOversampling:\", Counter(y_ros))\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 31,
   "id": "46de3cc2",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Model Name: \n",
      "RandomForestClassifier\n",
      "Accuracy: 0.8449\n",
      "Precision: 0.8359\n",
      "Recall: 0.8449\n",
      "F1 Score: 0.8361\n",
      "              precision    recall  f1-score   support\n",
      "\n",
      "    negative       0.72      0.53      0.61       180\n",
      "    positive       0.87      0.94      0.90       600\n",
      "\n",
      "    accuracy                           0.84       780\n",
      "   macro avg       0.80      0.74      0.76       780\n",
      "weighted avg       0.84      0.84      0.84       780\n",
      "\n",
      "\n",
      "Best hyperparameters found by GridSearchCV:\n",
      "{'max_depth': None, 'n_estimators': 300}\n"
     ]
    }
   ],
   "source": [
    "train_random_forest_classifier_with_grid_search(X_ros, y_ros, X_test_vec, y_test, evaluate_model)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 32,
   "id": "a7ab8711",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "After undersampling: Counter({'negative': 420, 'positive': 420})\n"
     ]
    }
   ],
   "source": [
    "from imblearn.under_sampling import RandomUnderSampler\n",
    "from collections import Counter\n",
    "\n",
    "rus = RandomUnderSampler(random_state=42)\n",
    "X_res, y_res = rus.fit_resample(X_train_vec, y_train)\n",
    "\n",
    "print(\"After undersampling:\", Counter(y_res))\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 33,
   "id": "a02b042b",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Model Name: \n",
      "RandomForestClassifier\n",
      "Accuracy: 0.7026\n",
      "Precision: 0.8153\n",
      "Recall: 0.7026\n",
      "F1 Score: 0.7258\n",
      "              precision    recall  f1-score   support\n",
      "\n",
      "    negative       0.43      0.84      0.57       180\n",
      "    positive       0.93      0.66      0.77       600\n",
      "\n",
      "    accuracy                           0.70       780\n",
      "   macro avg       0.68      0.75      0.67       780\n",
      "weighted avg       0.82      0.70      0.73       780\n",
      "\n",
      "\n",
      "Best hyperparameters found by GridSearchCV:\n",
      "{'max_depth': 10, 'n_estimators': 300}\n"
     ]
    }
   ],
   "source": [
    "train_random_forest_classifier_with_grid_search(X_res, y_res, X_test_vec, y_test, evaluate_model)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 34,
   "id": "69f4ec81",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "After SMOTE: Counter({'positive': 1400, 'negative': 1400})\n"
     ]
    }
   ],
   "source": [
    "from imblearn.over_sampling import SMOTE\n",
    "from collections import Counter\n",
    "\n",
    "smote = SMOTE(random_state=42)\n",
    "X_smote, y_smote = smote.fit_resample(X_train_vec, y_train)\n",
    "\n",
    "print(\"After SMOTE:\", Counter(y_smote))\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 35,
   "id": "4301a16e",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Model Name: \n",
      "RandomForestClassifier\n",
      "Accuracy: 0.8308\n",
      "Precision: 0.8204\n",
      "Recall: 0.8308\n",
      "F1 Score: 0.8112\n",
      "              precision    recall  f1-score   support\n",
      "\n",
      "    negative       0.74      0.41      0.53       180\n",
      "    positive       0.84      0.96      0.90       600\n",
      "\n",
      "    accuracy                           0.83       780\n",
      "   macro avg       0.79      0.68      0.71       780\n",
      "weighted avg       0.82      0.83      0.81       780\n",
      "\n",
      "\n",
      "Best hyperparameters found by GridSearchCV:\n",
      "{'max_depth': None, 'n_estimators': 100}\n"
     ]
    }
   ],
   "source": [
    "train_random_forest_classifier_with_grid_search(X_smote, y_smote, X_test_vec, y_test, evaluate_model)"
   ]
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "FinalProject",
   "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.11.11"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 5
}
