{
 "cells": [
  {
   "cell_type": "code",
   "execution_count": 1,
   "id": "c5b892a9-9d69-46e4-aba4-f6b5b8588ddd",
   "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>gender</th>\n",
       "      <th>age</th>\n",
       "      <th>hypertension</th>\n",
       "      <th>heart_disease</th>\n",
       "      <th>smoking_history</th>\n",
       "      <th>bmi</th>\n",
       "      <th>HbA1c_level</th>\n",
       "      <th>blood_glucose_level</th>\n",
       "      <th>diabetes</th>\n",
       "    </tr>\n",
       "  </thead>\n",
       "  <tbody>\n",
       "    <tr>\n",
       "      <th>0</th>\n",
       "      <td>Female</td>\n",
       "      <td>80.0</td>\n",
       "      <td>0</td>\n",
       "      <td>1</td>\n",
       "      <td>never</td>\n",
       "      <td>25.19</td>\n",
       "      <td>6.6</td>\n",
       "      <td>140</td>\n",
       "      <td>0</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>1</th>\n",
       "      <td>Female</td>\n",
       "      <td>54.0</td>\n",
       "      <td>0</td>\n",
       "      <td>0</td>\n",
       "      <td>No Info</td>\n",
       "      <td>27.32</td>\n",
       "      <td>6.6</td>\n",
       "      <td>80</td>\n",
       "      <td>0</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>2</th>\n",
       "      <td>Male</td>\n",
       "      <td>28.0</td>\n",
       "      <td>0</td>\n",
       "      <td>0</td>\n",
       "      <td>never</td>\n",
       "      <td>27.32</td>\n",
       "      <td>5.7</td>\n",
       "      <td>158</td>\n",
       "      <td>0</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>3</th>\n",
       "      <td>Female</td>\n",
       "      <td>36.0</td>\n",
       "      <td>0</td>\n",
       "      <td>0</td>\n",
       "      <td>current</td>\n",
       "      <td>23.45</td>\n",
       "      <td>5.0</td>\n",
       "      <td>155</td>\n",
       "      <td>0</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>4</th>\n",
       "      <td>Male</td>\n",
       "      <td>76.0</td>\n",
       "      <td>1</td>\n",
       "      <td>1</td>\n",
       "      <td>current</td>\n",
       "      <td>20.14</td>\n",
       "      <td>4.8</td>\n",
       "      <td>155</td>\n",
       "      <td>0</td>\n",
       "    </tr>\n",
       "  </tbody>\n",
       "</table>\n",
       "</div>"
      ],
      "text/plain": [
       "   gender   age  hypertension  heart_disease smoking_history    bmi  \\\n",
       "0  Female  80.0             0              1           never  25.19   \n",
       "1  Female  54.0             0              0         No Info  27.32   \n",
       "2    Male  28.0             0              0           never  27.32   \n",
       "3  Female  36.0             0              0         current  23.45   \n",
       "4    Male  76.0             1              1         current  20.14   \n",
       "\n",
       "   HbA1c_level  blood_glucose_level  diabetes  \n",
       "0          6.6                  140         0  \n",
       "1          6.6                   80         0  \n",
       "2          5.7                  158         0  \n",
       "3          5.0                  155         0  \n",
       "4          4.8                  155         0  "
      ]
     },
     "execution_count": 1,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "import numpy as np\n",
    "import pandas as pd\n",
    "from sklearn.impute import KNNImputer\n",
    "from sklearn.preprocessing import LabelEncoder\n",
    "import seaborn as sns\n",
    "from matplotlib import pyplot as plt\n",
    "from sklearn.metrics import accuracy_score, precision_score, recall_score, f1_score, classification_report, confusion_matrix\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.neighbors import KNeighborsClassifier\n",
    "from sklearn.model_selection import train_test_split\n",
    "from sklearn.svm import SVC\n",
    "from sklearn.naive_bayes import GaussianNB\n",
    "from sklearn.neighbors import KNeighborsClassifier\n",
    "from sklearn.linear_model import LogisticRegression\n",
    "from sklearn.metrics import classification_report\n",
    "from sklearn.preprocessing import LabelEncoder\n",
    "from sklearn.datasets import load_iris\n",
    "from sklearn.feature_selection import SelectKBest, chi2\n",
    "\n",
    "df = pd.read_csv('diabetes_prediction_dataset.csv')\n",
    "df.head()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 9,
   "id": "45e26add-da06-4d56-a02f-25ece097c374",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "gender                  object\n",
       "age                    float64\n",
       "hypertension             int64\n",
       "heart_disease            int64\n",
       "smoking_history         object\n",
       "bmi                    float64\n",
       "HbA1c_level            float64\n",
       "blood_glucose_level      int64\n",
       "diabetes                 int64\n",
       "dtype: object"
      ]
     },
     "execution_count": 9,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "df.dtypes"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 10,
   "id": "51a49359-542e-4007-8b9e-d0eb91b57923",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "gender                 0\n",
       "age                    0\n",
       "hypertension           0\n",
       "heart_disease          0\n",
       "smoking_history        0\n",
       "bmi                    0\n",
       "HbA1c_level            0\n",
       "blood_glucose_level    0\n",
       "diabetes               0\n",
       "dtype: int64"
      ]
     },
     "execution_count": 10,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "df.isnull().sum()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 4,
   "id": "520b18d4-5083-45d0-b90b-c46a34312bb9",
   "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>age</th>\n",
       "      <th>hypertension</th>\n",
       "      <th>heart_disease</th>\n",
       "      <th>bmi</th>\n",
       "      <th>HbA1c_level</th>\n",
       "      <th>blood_glucose_level</th>\n",
       "      <th>diabetes</th>\n",
       "    </tr>\n",
       "  </thead>\n",
       "  <tbody>\n",
       "    <tr>\n",
       "      <th>count</th>\n",
       "      <td>100000.000000</td>\n",
       "      <td>100000.00000</td>\n",
       "      <td>100000.000000</td>\n",
       "      <td>100000.000000</td>\n",
       "      <td>100000.000000</td>\n",
       "      <td>100000.000000</td>\n",
       "      <td>100000.000000</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>mean</th>\n",
       "      <td>41.885856</td>\n",
       "      <td>0.07485</td>\n",
       "      <td>0.039420</td>\n",
       "      <td>27.320767</td>\n",
       "      <td>5.527507</td>\n",
       "      <td>138.058060</td>\n",
       "      <td>0.085000</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>std</th>\n",
       "      <td>22.516840</td>\n",
       "      <td>0.26315</td>\n",
       "      <td>0.194593</td>\n",
       "      <td>6.636783</td>\n",
       "      <td>1.070672</td>\n",
       "      <td>40.708136</td>\n",
       "      <td>0.278883</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>min</th>\n",
       "      <td>0.080000</td>\n",
       "      <td>0.00000</td>\n",
       "      <td>0.000000</td>\n",
       "      <td>10.010000</td>\n",
       "      <td>3.500000</td>\n",
       "      <td>80.000000</td>\n",
       "      <td>0.000000</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>25%</th>\n",
       "      <td>24.000000</td>\n",
       "      <td>0.00000</td>\n",
       "      <td>0.000000</td>\n",
       "      <td>23.630000</td>\n",
       "      <td>4.800000</td>\n",
       "      <td>100.000000</td>\n",
       "      <td>0.000000</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>50%</th>\n",
       "      <td>43.000000</td>\n",
       "      <td>0.00000</td>\n",
       "      <td>0.000000</td>\n",
       "      <td>27.320000</td>\n",
       "      <td>5.800000</td>\n",
       "      <td>140.000000</td>\n",
       "      <td>0.000000</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>75%</th>\n",
       "      <td>60.000000</td>\n",
       "      <td>0.00000</td>\n",
       "      <td>0.000000</td>\n",
       "      <td>29.580000</td>\n",
       "      <td>6.200000</td>\n",
       "      <td>159.000000</td>\n",
       "      <td>0.000000</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>max</th>\n",
       "      <td>80.000000</td>\n",
       "      <td>1.00000</td>\n",
       "      <td>1.000000</td>\n",
       "      <td>95.690000</td>\n",
       "      <td>9.000000</td>\n",
       "      <td>300.000000</td>\n",
       "      <td>1.000000</td>\n",
       "    </tr>\n",
       "  </tbody>\n",
       "</table>\n",
       "</div>"
      ],
      "text/plain": [
       "                 age  hypertension  heart_disease            bmi  \\\n",
       "count  100000.000000  100000.00000  100000.000000  100000.000000   \n",
       "mean       41.885856       0.07485       0.039420      27.320767   \n",
       "std        22.516840       0.26315       0.194593       6.636783   \n",
       "min         0.080000       0.00000       0.000000      10.010000   \n",
       "25%        24.000000       0.00000       0.000000      23.630000   \n",
       "50%        43.000000       0.00000       0.000000      27.320000   \n",
       "75%        60.000000       0.00000       0.000000      29.580000   \n",
       "max        80.000000       1.00000       1.000000      95.690000   \n",
       "\n",
       "         HbA1c_level  blood_glucose_level       diabetes  \n",
       "count  100000.000000        100000.000000  100000.000000  \n",
       "mean        5.527507           138.058060       0.085000  \n",
       "std         1.070672            40.708136       0.278883  \n",
       "min         3.500000            80.000000       0.000000  \n",
       "25%         4.800000           100.000000       0.000000  \n",
       "50%         5.800000           140.000000       0.000000  \n",
       "75%         6.200000           159.000000       0.000000  \n",
       "max         9.000000           300.000000       1.000000  "
      ]
     },
     "execution_count": 4,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "df.describe()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 11,
   "id": "f2b04911-f0f1-419a-972e-5730ef44a918",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "diabetes\n",
       "0    91500\n",
       "1     8500\n",
       "Name: count, dtype: int64"
      ]
     },
     "execution_count": 11,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "df['diabetes'].value_counts()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 3,
   "id": "93253bb2-ab2b-4297-b8d7-10edbb16d0a4",
   "metadata": {},
   "outputs": [],
   "source": [
    "\n",
    "label_encoders = {}\n",
    "for column in df.select_dtypes(include=['object']).columns:\n",
    "    le = LabelEncoder()\n",
    "    df[column] = le.fit_transform(df[column])\n",
    "    label_encoders[column] = le"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 4,
   "id": "9da21f89-16a0-428c-ab99-e9d84e24e096",
   "metadata": {},
   "outputs": [],
   "source": [
    "X = df.drop('diabetes', axis=1).values\n",
    "y = df['diabetes'].values"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 5,
   "id": "366a0c91-2506-498c-b18d-f0d5f8a3a7d3",
   "metadata": {},
   "outputs": [],
   "source": [
    "from sklearn.preprocessing import StandardScaler \n",
    "scaler = StandardScaler()\n",
    "X = scaler.fit_transform(X)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 6,
   "id": "bb8314a2-1f1d-43b4-abb8-e19626770e84",
   "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": 16,
   "id": "0244be9d-8aac-445b-9ab7-693b5284fccb",
   "metadata": {},
   "outputs": [],
   "source": [
    "def evaluate_model (model_name, y_true, y_pred):\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",
    "    report = classification_report(y_true, y_pred)\n",
    "\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",
    "    plt.figure(figsize=(4, 4))\n",
    "    sns.heatmap(cm, annot=True, fmt='d', cmap='Blues', cbar=False,\n",
    "                xticklabels=np.unique(y_true), yticklabels=np.unique(y_true))\n",
    "    plt.title(f'Confusion Matrix for {model_name}')\n",
    "    plt.xlabel('Predicted Label')\n",
    "    plt.ylabel('True Label')\n",
    "    plt.show()\n",
    "\n",
    "    return metrics"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 17,
   "id": "8dc61bee-2a3a-43f0-8c9c-3ad9b7f3bcbd",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "image/png": "iVBORw0KGgoAAAANSUhEUgAAAZIAAAGJCAYAAACgk7WiAAAAOnRFWHRTb2Z0d2FyZQBNYXRwbG90bGliIHZlcnNpb24zLjEwLjEsIGh0dHBzOi8vbWF0cGxvdGxpYi5vcmcvc2/+5QAAAAlwSFlzAAAPYQAAD2EBqD+naQAAM0hJREFUeJzt3Qd4FFXU8PETWuihN+kiTWnSuxTBRleU3gRRRKQpvCoKoiCiNCmKNBEVFSkCr3QB6UXAAoiAoEjvNYFkvudcv913d7OBTW4ayf/3PAvZmdndOzN37rltdoMcx3EEAIAYShHTFwIAoAgkAAArBBIAgBUCCQDACoEEAGCFQAIAsEIgAQBYIZAAAKwQSAAAVpJNIDlw4IA0atRIQkJCJCgoSBYsWBCr7//XX3+Z9505c2asvu/d7KGHHjKP2HLlyhV59tlnJU+ePOZYv/zyy5LckM8SRufOnaVw4cIJ9vkzZ840513Pv6f3339fihYtKilTppTy5cubZZpOTW+SDSQHDx6U5557zux42rRpJXPmzFKzZk0ZN26cXL9+PU4/u1OnTvLLL7/IO++8I7Nnz5ZKlSpJUqGZRjOZHk9/x1GDqK7Xx+jRo6P9/v/++6+89dZbsmvXLklI7777rrmgnn/+eXMOO3ToEKefpxek67jpI0OGDFKlShX57LPPJDlyBTF/j2rVqkli9MUXX8jYsWOjXH/p0iUZOnSolCtXTjJmzCjp0qWTBx54QF599VWT7xOz5cuXyyuvvGLK0BkzZpjrI6Gkiq8PWrJkiTz11FMSHBwsHTt2NCcrLCxMfvrpJxk4cKD89ttv8sknn8TJZ2vhumnTJnnttdfkxRdfjJPPKFSokPmc1KlTS0JIlSqVXLt2Tb7//ntp3bq117o5c+aYwH3jxo0YvbdeUHqxacHqqvUEmtFj0+rVq02B9eabb0p80f3t37+/+fv48ePy6aefmkpJaGiodO/eXZKjNm3ayGOPPea1LGfOnJJYA8mvv/7qt/V66NAhadiwoRw9etSUTT169JA0adLInj17ZNq0aTJ//nz5448/JDHo0KGDPPPMM6b89LweUqRIYdKq6XbZv3+/WZ7kAsnhw4fNQdDCVnc+b9687nW9evWSP//80wSauHL69Gnzf5YsWeLsM7RWpoV1QtEMpjWTL7/8MlIg0Yvp8ccfl3nz5sVLWjSgpU+f3itzx4ZTp05J6dKlY+39bt26JREREbdN5z333CPt27f3av1pi3rMmDHJNpA8+OCDXscktmhFR89FfBSCeu5btmwpJ0+elB9//FFq1arltV57Lt577z1JLFKmTGkevteDtqB8869nsImPa8Rw4kHPnj31G4adDRs2BLT9zZs3nWHDhjlFixZ10qRJ4xQqVMgZPHiwc+PGDa/tdPnjjz/urF+/3qlcubITHBzsFClSxJk1a5Z7mzfffNN8tudDX6c6derk/tuT6zWeli9f7tSsWdMJCQlxMmTI4BQvXtykyeXw4cPmNTNmzPB63apVq5xatWo56dOnN69t2rSp8/vvv/v9vAMHDpg06XaZM2d2Onfu7Fy9evWOx0tfo2maOXOmOQbnz593r9u6dat573nz5pn/33//ffe6s2fPOv3793ceeOAB8/pMmTI5jzzyiLNr1y73NmvWrIl0/Dz3s27dus7999/vbN++3aldu7aTLl06p0+fPu51+nDp2LGjSZ/v/jdq1MjJkiWLc+zYMb/7F1Ua9JirkydPOl27dnVy5cpl3r9s2bLmWHhynR/d/zFjxpi8lSJFCufnn3+O8ri68pevSpUqmXzpad26dc6TTz7pFChQwKzLnz+/8/LLLzvXrl3ze67++ecfp1mzZubvHDlymPNw69Ytr231POr2mhc0T+jx0/Ta5rP9+/c77dq1M++rn/366687ERERztGjR83rNB/kzp3bGT16dJTH8HYOHjxojkXWrFlNfqhataqzePFiv+f0yy+/dF577TUnX758TlBQkDvvbt682WncuLFJo75HnTp1nJ9++snrPS5dumTymp4nPeY5c+Z0GjZs6OzYscOs17wX1bX/1VdfmefvvPPObffF87z5lhV6HKpXr+5ky5bNSZs2rfPggw8633zzTaTX3qnsUOPHj3dKly5t9lWvhYoVKzpz5sxxr9fz7Znnb3dNajo1vZ70uOqx0nypx+ree+91Ro4c6YSHh1tdIy7x0iLR7hatxdWoUSOg7XVAddasWfLkk0+aboUtW7bIiBEjZO/evaa56UlbM7pdt27dTJfD9OnTTa2xYsWKcv/995tah7ZE+vbt626Sa19odGi32xNPPCFly5aVYcOGmYivn7thw4bbvm7lypXy6KOPmn3XMQbt+powYYJpOezcuTPS4J22JIoUKWL2VddrN0quXLkCrhnpvvbs2VO+++476dq1q7s1UrJkSVOL9Ne010kH2qzXz9Xa2ccffyx169aV33//XfLlyyelSpUy+zxkyBDT9K9du7Z5ree5PHv2rNlPbXVqTTV37tx+06djYdoi1fOkXY1aw9LP0y4wHfPQz/NH06Dr9Rzmz5/f3dWk3Sl6THVAX8+HdlvqfnzzzTcmD1y4cEH69Onj9V7al6w1X90XPY/ZsmWT6NbQ/vnnH8maNavXcv1MbYnp+E327Nll69at5lzrtrrOU3h4uDRu3FiqVq1qxqw0n3zwwQdy7733mtcrLSuaNWtmun71nOox0Lyvx842nz399NPm/UaOHGl6AoYPH26Og56L+vXrm/ym3aEDBgyQypUrS506dbxer/t55swZr2U6iUW7dTUPad7QbV566SVzLPRabtq0qXz77bfSokULr9e9/fbbprarn6Xdhfq35hHdH72GtRtTWyh63jRt69evN+NUSo+Lvqeed22paj7U46XlhOZ37cq+ePGiOQfaglSua3/RokXmf5txNs3Pul/t2rUz3fRfffWVuZYWL15segACLTumTp1qjpWWY5pfNX9q95qWe23btvX72Xo96FCA5jMtJ1RU5aueC72mjx07ZsaoCxYsKBs3bpTBgweb7lrfMaQYXSNOHLt48aKJclr7CoTWhnX7Z5991mv5gAEDzPLVq1e7l2nk1WVaG3Q5deqUqZVqDe9ONalAWyQanfX56dOno0y3vxZJ+fLlTS1Za/4uu3fvNlFea5e+n6e1ak8tWrRwsmfPHuVneu6H1nSU1gQbNGhg/tbaRp48eZyhQ4f6PQbawvOskbj2Q4+ftghdtm3b5rcW7FnrmzJlit91ni0StWzZMrP98OHDnUOHDjkZM2Z0mjdv7gTCXwth7Nix5v0+//xz97KwsDBTU9T31lqra790O63hah4J9PO0taTnXR+//PKL06FDB/M+vXr18trWt+WhRowYYWrZR44c8TpX+nrP46sqVKhgaqEuCxYsMNuNGjXKvUxbLNrqs81nPXr08HpPraVqOrWG6lmD1dqxZ83WdQz9PbSFobQVps+1l8Dl8uXLpqegcOHC7vzmapFordfz2GnL6L777jOtEf3b8/jqezz88MPuZVrD9z0PvjS/+LvG9Xjr6wPlr6zwPedhYWGmdV+/fv1olR1aNmqr/nZ8WyS+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",
      "text/plain": [
       "<Figure size 400x400 with 1 Axes>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Model Name: RandomForestClassifier\n",
      "Accuracy: 0.9702\n",
      "Precision: 0.9696\n",
      "Recall: 0.9702\n",
      "F1 Score: 0.9681\n",
      "\n",
      "               precision    recall  f1-score   support\n",
      "\n",
      "           0       0.97      1.00      0.98     27450\n",
      "           1       0.94      0.69      0.80      2550\n",
      "\n",
      "    accuracy                           0.97     30000\n",
      "   macro avg       0.96      0.84      0.89     30000\n",
      "weighted avg       0.97      0.97      0.97     30000\n",
      "\n",
      "\n",
      "Best hyperparameters found by GridSearchCV:\n",
      "{'max_depth': None, 'min_samples_leaf': 1, 'min_samples_split': 2, 'n_estimators': 100}\n"
     ]
    }
   ],
   "source": [
    "from sklearn.ensemble import RandomForestClassifier\n",
    "from sklearn.model_selection import GridSearchCV\n",
    "\n",
    "rf_classifier = RandomForestClassifier(class_weight='balanced', random_state=42)\n",
    "param_grid = {\n",
    "    'n_estimators': [100, 200, 300],\n",
    "    'max_depth': [None, 10, 20, 30],\n",
    "    'min_samples_split': [2, 5, 10],\n",
    "    'min_samples_leaf': [1, 2, 4]\n",
    "}\n",
    "grid_search = GridSearchCV(estimator=rf_classifier, param_grid=param_grid, cv=5, scoring='accuracy', n_jobs=-1)\n",
    "grid_search.fit(X_train, y_train)\n",
    "best_rf_classifier  = grid_search.best_estimator_\n",
    "y_pred = best_rf_classifier.predict(X_test)\n",
    "evaluation_results = evaluate_model('RandomForestClassifier', y_test, y_pred)\n",
    "\n",
    "for key, value in evaluation_results.items():\n",
    "    if key == 'Classification Report':\n",
    "       print(\"\\n\", value)\n",
    "    else:\n",
    "       print(f\"{key}: {value:.4f}\" if isinstance(value, float) else f\"{key}: {value}\")\n",
    "        \n",
    "print(\"\\nBest hyperparameters found by GridSearchCV:\")\n",
    "print(grid_search.best_params_)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 14,
   "id": "fba72111-49c4-43fa-b7ac-80753e15a2f8",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "image/png": "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",
      "text/plain": [
       "<Figure size 400x400 with 1 Axes>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Model Name: \n",
      "LogisticRegression\n",
      "Accuracy: 0.8893\n",
      "Precision: 0.9403\n",
      "Recall: 0.8893\n",
      "F1 Score: 0.9057\n",
      "              precision    recall  f1-score   support\n",
      "\n",
      "           0       0.99      0.89      0.94     27450\n",
      "           1       0.43      0.88      0.58      2550\n",
      "\n",
      "    accuracy                           0.89     30000\n",
      "   macro avg       0.71      0.89      0.76     30000\n",
      "weighted avg       0.94      0.89      0.91     30000\n",
      "\n",
      "\n",
      "Best hyperparameters found by GridSearchCV:\n",
      "{'C': 0.01, 'max_iter': 100, 'solver': 'lbfgs'}\n"
     ]
    }
   ],
   "source": [
    "LR = LogisticRegression(class_weight='balanced', random_state=42)\n",
    " \n",
    "param_grid = {\n",
    "   'C': [0.01, 0.1, 1, 10], # Regularization strength\n",
    "   'solver': ['liblinear', 'lbfgs'], # Solver type\n",
    "   'max_iter': [100, 200, 300] # Maximum iterations for convergence\n",
    "}\n",
    " \n",
    "grid_search = GridSearchCV(estimator=LR, param_grid=param_grid, cv=5, scoring='accuracy', n_jobs=-1)\n",
    "grid_search.fit(X_train, y_train)\n",
    "best_LR = grid_search.best_estimator_\n",
    "y_pred = best_LR.predict(X_test)\n",
    "evaluation_results = evaluate_model('LogisticRegression', y_test, y_pred)\n",
    "\n",
    "for key, value in evaluation_results.items():\n",
    "   if key == 'Classification Report':\n",
    "      print(value)  \n",
    "   else:\n",
    "     print(f\"{key}: {value:.4f}\" if isinstance(value, float) else f\"{key}: \\n{value}\")\n",
    " \n",
    "print(\"\\nBest hyperparameters found by GridSearchCV:\")\n",
    "print(grid_search.best_params_)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 20,
   "id": "0c5ea5bf-1559-4ec2-b3e9-5b7da10e33ba",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "image/png": "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IlgAAKwIFgAAK4IFAMCKYAEAsCJYAACsCBYAACuCBQDAimABALAiWAAArAgWAAArggUAwIpgAQCwIlgAAKwIFgAAK4IFAMCKYAEAsCJYAACsCBYAACuCBQDAimABALAiWAAArAgWAACrTPZNRH777TcJVMWKFQPeFgCQhoJF5cqVJSQkRBzH8bveXad/r1y5kthpBACkhmCxc+fOpE8JACB1B4vixYsnfUoAAGlrgHv27NlSt25dKVy4sOzatcssmzRpknz22WeJnT4AQGoMFlOnTpV+/frJXXfdJSdOnPCMUeTKlcsEDABA2pPgYPHKK6/IW2+9JUOGDJGMGTN6llevXl02btyY2OkDAKTGYKGD3VWqVIm1PDQ0VM6ePZtY6QIApOZgUaJECVm/fn2s5V9//bXceOONiZUuAEBqmw3lTccrnnjiCblw4YK5t2LVqlXy3nvvyfjx4+Xtt99OmlQCAFJXsHjssccka9as8uyzz8q5c+fkoYceMrOiJk+eLA8++GDSpBIAEFQhTly3ZQdAg8WZM2ckf/78kpJkrdIr2ElAOnF89avBTgLSibAEV+0T11Xv/tChQ7J161bzv37NR758+RIzXQCA1DzAffr0aXn00UdN11PDhg3NQ/9/5JFH5OTJk0mTSgBA6goWOmaxcuVK+fLLL81NefpYsGCBrFmzRrp37540qQQApK4xi+zZs8uiRYukXr16PsuXLl0qd9xxR4q414IxCyQXxiyQXsYsEtyyyJs3r0RERMRarsty586dWOkCAKQgCQ4WOmVW77U4cOCAZ5n+P3DgQBk6dGhipw8AkAIE1LDRr/fQGU+u7du3S7FixcxD7d6923zdx+HDhxm3AID0GixatWqV9CkBAKTNm/JSKga4kVwY4EZySXUD3ACA9CfBsUp/7GjixInywQcfmLGKixcv+qw/duxYYqYPAJACJLhlMXLkSHn55ZflgQceMHds68yo1q1bS4YMGWTEiBFJk0oAQOoKFnPnzjW/lNe/f3/JlCmTtGvXznw1+bBhw+SXX35JmlQCAFJXsNB7KipUqGD+Dw8P93wf1N13322+AgQAkPYkOFhcd911sn//fvN/qVKl5JtvvjH/r1692txrAQBIexIcLO699175/vvvzf+9e/c2d22XKVNG2rdvL507d06KNAIAUvt9FjpOsXz5chMwWrRoISkB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",
      "text/plain": [
       "<Figure size 400x400 with 1 Axes>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Model Name: \n",
      "DecisionTreeClassifier\n",
      "Accuracy: 0.9716\n",
      "Precision: 0.9717\n",
      "Recall: 0.9716\n",
      "F1 Score: 0.9693\n",
      "              precision    recall  f1-score   support\n",
      "\n",
      "           0       0.97      1.00      0.98     27450\n",
      "           1       0.97      0.68      0.80      2550\n",
      "\n",
      "    accuracy                           0.97     30000\n",
      "   macro avg       0.97      0.84      0.89     30000\n",
      "weighted avg       0.97      0.97      0.97     30000\n",
      "\n",
      "\n",
      "Best hyperparameters found by GridSearchCV:\n",
      "{'criterion': 'entropy', 'max_depth': 10, 'max_features': 'log2', 'min_samples_leaf': 2, 'min_samples_split': 10}\n"
     ]
    }
   ],
   "source": [
    "from sklearn.tree import DecisionTreeClassifier\n",
    "from sklearn.model_selection import train_test_split, GridSearchCV\n",
    "\n",
    "DT = DecisionTreeClassifier(random_state=42)\n",
    "\n",
    "param_grid = {\n",
    "    'criterion': ['gini', 'entropy'],            \n",
    "    'max_depth': [None, 10, 20, 30],   \n",
    "    'min_samples_split': [2, 5, 10],       \n",
    "    'min_samples_leaf': [1, 2, 4],              \n",
    "    'max_features': [None, 'sqrt', 'log2']  \n",
    "}\n",
    "grid_search = GridSearchCV(estimator=DT, param_grid=param_grid, cv=5, scoring='accuracy', n_jobs=-1)\n",
    "grid_search.fit(X_train, y_train)\n",
    "best_DT = grid_search.best_estimator_\n",
    "y_pred = best_DT.predict(X_test)\n",
    "evaluation_results = evaluate_model('DecisionTreeClassifier', y_test, y_pred)\n",
    "\n",
    "for key, value in evaluation_results.items():\n",
    "     if key == 'Classification Report':\n",
    "          print(value) \n",
    "     else:\n",
    "         print(f\"{key}: {value:.4f}\" if isinstance(value, float) else f\"{key}: \\n{value}\")\n",
    "\n",
    "print(\"\\nBest hyperparameters found by GridSearchCV:\")\n",
    "print(grid_search.best_params_)\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 42,
   "id": "8ba02e8e-fe50-433c-96e6-ee827b69f07f",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "image/png": "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",
      "text/plain": [
       "<Figure size 400x400 with 1 Axes>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Model Name: \n",
      "K-Nearest Neighbors\n",
      "Accuracy: 0.9622\n",
      "Precision: 0.9608\n",
      "Recall: 0.9622\n",
      "F1 Score: 0.9588\n",
      "              precision    recall  f1-score   support\n",
      "\n",
      "           0       0.97      0.99      0.98     27450\n",
      "           1       0.91      0.61      0.73      2550\n",
      "\n",
      "    accuracy                           0.96     30000\n",
      "   macro avg       0.94      0.80      0.86     30000\n",
      "weighted avg       0.96      0.96      0.96     30000\n",
      "\n",
      "\n",
      "Best hyperparameters found by GridSearchCV:\n",
      "{'algorithm': 'auto', 'metric': 'manhattan', 'n_neighbors': 7, 'weights': 'uniform'}\n"
     ]
    }
   ],
   "source": [
    "knn = KNeighborsClassifier()\n",
    "param_grid = {   \n",
    "    'n_neighbors': [1, 3, 5, 7, 9],\n",
    "    'weights': ['uniform', 'distance'],\n",
    "    'metric': ['euclidean', 'manhattan'], \n",
    "    'algorithm': ['auto', 'ball_tree', 'kd_tree', 'brute']\n",
    "}\n",
    "\n",
    "grid_search = GridSearchCV(estimator=knn, param_grid=param_grid, cv=5, scoring='accuracy', n_jobs=-1)\n",
    "grid_search.fit(X_train, y_train)\n",
    "best_knn = grid_search.best_estimator_\n",
    "y_pred = best_knn.predict(X_test)\n",
    "evaluation_results = evaluate_model('K-Nearest Neighbors', y_test, y_pred)\n",
    "\n",
    "for key, value in evaluation_results.items():\n",
    "     if key == 'Classification Report':\n",
    "          print(value) \n",
    "     else:\n",
    "         print(f\"{key}: {value:.4f}\" if isinstance(value, float) else f\"{key}: \\n{value}\")\n",
    "\n",
    "print(\"\\nBest hyperparameters found by GridSearchCV:\")\n",
    "print(grid_search.best_params_)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "f1fc190e-6b37-4daa-a83d-554b6a05edab",
   "metadata": {},
   "outputs": [],
   "source": [
    "SVM = SVC(random_state=42)\n",
    "param_grid = {\n",
    "    'C': [0.01, 0.1, 1, 10],  \n",
    "    'kernel': ['linear', 'rbf', 'poly'],\n",
    "    'gamma': ['scale', 'auto'], \n",
    "    'degree': [3, 4, 5], \n",
    "    'class_weight': [None, 'balanced'] \n",
    "}\n",
    "\n",
    "grid_search = GridSearchCV(estimator=SVM, param_grid=param_grid, cv=5, scoring='accuracy', n_jobs=-1)\n",
    "\n",
    "grid_search.fit(X_train, y_train)\n",
    "\n",
    "best_SVM = grid_search.best_estimator_\n",
    "\n",
    "y_pred = best_SVM.predict(X_test)\n",
    "\n",
    "evaluation_results = evaluate_model('Support Vector Machine', y_test, y_pred)\n",
    "\n",
    "for key, value in evaluation_results.items():\n",
    "     if key == 'Classification Report':\n",
    "          print(value) \n",
    "     else:\n",
    "         print(f\"{key}: {value:.4f}\" if isinstance(value, float) else f\"{key}: \\n{value}\")\n",
    "\n",
    "\n",
    "print(\"\\nBest hyperparameters found by GridSearchCV:\")\n",
    "print(grid_search.best_params_)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "2708a25b-895c-4b28-9478-4de6f001b410",
   "metadata": {},
   "outputs": [],
   "source": [
    "gnb = GaussianNB()\n",
    "param_grid = {\n",
    "    'var_smoothing': [1e-9, 1e-8, 1e-7, 1e-6] \n",
    "}\n",
    "\n",
    "grid_search = GridSearchCV(estimator=gnb, param_grid=param_grid, cv=5, cv=5, scoring='accuracy', n_jobs=-1)\n",
    "\n",
    "grid_search.fit(X_train, y_train)\n",
    "\n",
    "best_gnb = grid_search.best_estimator_\n",
    "\n",
    "y_pred = best_gnb.predict(X_test)\n",
    "\n",
    "evaluation_results = evaluate_model('Gaussian Naive Bayes', y_test, y_pred)\n",
    "\n",
    "or key, value in evaluation_results.items():\n",
    "     if key == 'Classification Report':\n",
    "          print(value) \n",
    "     else:\n",
    "         print(f\"{key}: {value:.4f}\" if isinstance(value, float) else f\"{key}: \\n{value}\")\n",
    "         \n",
    "print(\"\\nBest hyperparameters found by GridSearchCV:\")\n",
    "print(grid_search.best_params_)\n",
    "\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "32e14b83-6690-435b-8435-1a7173daf759",
   "metadata": {},
   "outputs": [],
   "source": [
    "from sklearn.preprocessing import MinMaxScaler\n",
    "\n",
    "scaler = MinMaxScaler()\n",
    "X_scaled = scaler.fit_transform(X_train)\n",
    "\n",
    "from sklearn.feature_selection import SelectKBest, chi2\n",
    "select_feature = SelectKBest(chi2, k=5).fit(X_scaled, y_train)\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "4773be1f-743e-4141-b432-3dce57afc9a4",
   "metadata": {},
   "outputs": [],
   "source": [
    "df = pd.DataFrame([])\n",
    "df._append(pd.DataFrame({'Feature': X.columns, 'Score': select_feature .scores_}))"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "2d02eea5-a5e3-4170-a810-e077c7d1c579",
   "metadata": {},
   "outputs": [],
   "source": [
    "X_train_selected = select_feature.transform(X_train)\n",
    "X_test_selected = select_feature.transform(X_test)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "6dc7bb74-13f4-4b7e-b9a5-d4971beb3722",
   "metadata": {},
   "outputs": [],
   "source": [
    "def evaluate_model(model_name, y_true, y_pred):\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",
    "        metrics = {\n",
    "            'Model Name': model_name,\n",
    "            'Accuracy': accuracy,\n",
    "            'Precision': precision,\n",
    "            'Recall': recall,\n",
    "            'F1 Score': f1,                 \n",
    "  }       \n",
    "        return metrics"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "1e886e4a-2741-4cf3-8507-9944af1fe5f5",
   "metadata": {},
   "outputs": [],
   "source": [
    "rf_classifier = RandomForestClassifier(random_state=42)\n",
    "param_grid = {\n",
    "    'n_estimators': [100, 200, 300],\n",
    "    'max_depth': [None, 10, 20, 30],\n",
    "    'min_samples_split': [2, 5, 10],\n",
    "    'min_samples_leaf': [1, 2, 4] } \n",
    "\n",
    "grid_search = GridSearchCV(estimator=rf_classifier, param_grid=param_grid, cv=5, scoring='accuracy', n_jobs=-1) \n",
    "grid_search.fit(X_train_selected, y_train)\n",
    "best_rf_classifier = grid_search.best_estimator_ \n",
    "\n",
    "y_pred = best_rf_classifier.predict(X_test_selected)\n",
    "\n",
    "evaluation_results = evaluate_model('RandomForestClassifier', y_test, y_pred) \n",
    "\n",
    "for key, value in evaluation_results.items():\n",
    "    print(f\"{key}: {value:.4f}\" if isinstance(value, float) else f\"{key}: \\n{value}\") \n",
    "    \n",
    "print(\"\\nBest hyperparameters found by GridSearchCV:\")\n",
    "print(grid_search.best_params_)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "3c2a73aa-56eb-4e59-81e0-2c5d9b01cf56",
   "metadata": {},
   "outputs": [],
   "source": [
    "from sklearn.tree import DecisionTreeClassifier\n",
    "from sklearn.model_selection import train_test_split, GridSearchCV\n",
    "\n",
    "DT = DecisionTreeClassifier(random_state=42)\n",
    "\n",
    "param_grid = {\n",
    "    'criterion': ['gini', 'entropy'],            \n",
    "    'max_depth': [None, 10, 20, 30],   \n",
    "    'min_samples_split': [2, 5, 10],       \n",
    "    'min_samples_leaf': [1, 2, 4],              \n",
    "    'max_features': [None, 'sqrt', 'log2']  \n",
    "}\n",
    "grid_search = GridSearchCV(estimator=DT, param_grid=param_grid, cv=5, scoring='accuracy', n_jobs=-1)\n",
    "\n",
    "grid_search.fit(, y_train)\n",
    "\n",
    "best_DT = grid_search.best_estimator_\n",
    "\n",
    "y_pred = best_DT.predict(X_test_selected)\n",
    "\n",
    "evaluation_results = evaluate_model('DecisionTreeClassifier', y_test, y_pred)\n",
    "\n",
    "for key, value in evaluation_results.items():\n",
    "    print(f\"{key}: {value:.4f}\" if isinstance(value, float) else f\"{key}: \\n{value}\") \n",
    "    \n",
    "print(\"\\nBest hyperparameters found by GridSearchCV:\")\n",
    "print(grid_search.best_params_)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "dcb7d53b-7c65-4f77-9494-1042cc0ffa41",
   "metadata": {},
   "outputs": [],
   "source": [
    "from sklearn.feature_selection import RFE\n",
    "\n",
    "clf_rf_2 = RandomForestClassifier(random_state=43) \n",
    "\n",
    "rfe_selector = RFE(estimator=clf_rf_2, n_features_to_select=5)\n",
    "\n",
    "X_train_selected_rfe = rfe_selector.fit_transform(X_train, y_train)\n",
    "X_test_selected_rfe = rfe_selector.transform(X_test)\n",
    "\n",
    "selected_features = rfe_selector.get_support(indices=True)\n",
    "\n",
    "print(\"Selected Features (RFE):\", selected_features)\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "e97ee491-a156-45aa-8091-8762ede5da1c",
   "metadata": {},
   "outputs": [],
   "source": [
    "rf_classifier = RandomForestClassifier(random_state=42)\n",
    "param_grid = {\n",
    "    'n_estimators': [100, 200, 300],\n",
    "    'max_depth': [None, 10, 20, 30],\n",
    "    'min_samples_split': [2, 5, 10],\n",
    "    'min_samples_leaf': [1, 2, 4] \n",
    "}\n",
    "\n",
    "grid_search = GridSearchCV(estimator=rf_classifier, param_grid=param_grid, cv=5, scoring='accuracy', n_jobs=-1)\n",
    "\n",
    "grid_search.fit(X_train_selected_rfe, y_train)\n",
    "\n",
    "best_rf_classifier = grid_search.best_estimator_\n",
    "\n",
    "y_pred = best_rf_classifier.predict(X_test_selected_rfe)\n",
    "\n",
    "evaluation_results = evaluate_model('RandomForestClassifier', y_test, y_pred)\n",
    "\n",
    "for key, value in evaluation_results.items():\n",
    "    print(f\"{key}: {value:.4f}\" if isinstance(value, float) else f\"{key}: \\n{value}\")\n",
    "\n",
    "print(\"\\nBest hyperparameters found by GridSearchCV:\")\n",
    "print(grid_search.best_params_)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "3c95d70a-0049-4c81-b8b8-c5070b3141de",
   "metadata": {},
   "outputs": [],
   "source": [
    "LR = LogisticRegression(class_weight='balanced', random_state=42)\n",
    " \n",
    "param_grid = {\n",
    "   'C': [0.01, 0.1, 1, 10], # Regularization strength\n",
    "   'solver': ['liblinear', 'lbfgs'], # Solver type\n",
    "   'max_iter': [100, 200, 300] # Maximum iterations for convergence\n",
    "}\n",
    " \n",
    "grid_search = GridSearchCV(estimator=LR, param_grid=param_grid, cv=5, scoring='accuracy', n_jobs=-1)\n",
    "grid_search.fit(X_train_selected_rfe, y_train)\n",
    "best_LR = grid_search.best_estimator_\n",
    "y_pred = best_LR.predict(X_test_selected_rfe)\n",
    "evaluation_results = evaluate_model('LogisticRegression', y_test, y_pred)\n",
    "\n",
    "for key, value in evaluation_results.items():\n",
    "   print(f\"{key}: {value:.4f}\" if isinstance(value, float) else f\"{key}: \\n{value}\")\n",
    " \n",
    "print(\"\\nBest hyperparameters found by GridSearchCV:\")\n",
    "print(grid_search.best_params_)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "776bfc98-f0d7-4f98-86dd-582bca2c91c2",
   "metadata": {},
   "outputs": [],
   "source": [
    "knn = KNeighborsClassifier()\n",
    "param_grid = {   \n",
    "    'n_neighbors': [1, 3, 5, 7, 9],\n",
    "    'weights': ['uniform', 'distance'],\n",
    "    'metric': ['euclidean', 'manhattan'], \n",
    "    'algorithm': ['auto', 'ball_tree', 'kd_tree', 'brute']\n",
    "}\n",
    "\n",
    "grid_search = GridSearchCV(estimator=knn, param_grid=param_grid, cv=5, scoring='accuracy', n_jobs=-1)\n",
    "grid_search.fit(X_train_selected_rfe, y_train)\n",
    "best_knn = grid_search.best_estimator_\n",
    "y_pred = best_knn.predict(X_test_selected_rfe)\n",
    "evaluation_results = evaluate_model('K-Nearest Neighbors', y_test, y_pred)\n",
    "\n",
    "for key, value in evaluation_results.items():\n",
    "   print(f\"{key}: {value:.4f}\" if isinstance(value, float) else f\"{key}: \\n{value}\")\n",
    "\n",
    "print(\"\\nBest hyperparameters found by GridSearchCV:\")\n",
    "print(grid_search.best_params_)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "9edb6617-8aa9-4266-9475-376ec30dcb4b",
   "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.12.9"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 5
}
