{
 "cells": [
  {
   "cell_type": "code",
   "execution_count": 64,
   "id": "01c46189-a598-4bfc-9565-a914346decf7",
   "metadata": {},
   "outputs": [],
   "source": [
    "import pandas as pd\n",
    "from sklearn.model_selection import train_test_split, GridSearchCV\n",
    "from sklearn.preprocessing import StandardScaler\n",
    "from sklearn.neighbors import KNeighborsClassifier\n",
    "# from sklearn.metrics import confusion_matrix, roc_curve, roc_auc_score, RocCurveDisplay\n",
    "from sklearn.metrics import confusion_matrix, recall_score, precision_score, roc_auc_score, roc_curve, accuracy_score, RocCurveDisplay\n",
    "\n",
    "import matplotlib.pyplot as plt"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 65,
   "id": "53f58e2c-169e-434c-9b8e-1bd0cb5f7715",
   "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>Enroll</th>\n",
       "      <th>Age</th>\n",
       "      <th>Income</th>\n",
       "      <th>Hours</th>\n",
       "    </tr>\n",
       "  </thead>\n",
       "  <tbody>\n",
       "    <tr>\n",
       "      <th>0</th>\n",
       "      <td>1</td>\n",
       "      <td>26</td>\n",
       "      <td>18000</td>\n",
       "      <td>14</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>1</th>\n",
       "      <td>0</td>\n",
       "      <td>43</td>\n",
       "      <td>13000</td>\n",
       "      <td>9</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>2</th>\n",
       "      <td>1</td>\n",
       "      <td>55</td>\n",
       "      <td>42000</td>\n",
       "      <td>16</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>3</th>\n",
       "      <td>1</td>\n",
       "      <td>55</td>\n",
       "      <td>100000</td>\n",
       "      <td>13</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>4</th>\n",
       "      <td>0</td>\n",
       "      <td>55</td>\n",
       "      <td>13000</td>\n",
       "      <td>12</td>\n",
       "    </tr>\n",
       "  </tbody>\n",
       "</table>\n",
       "</div>"
      ],
      "text/plain": [
       "   Enroll  Age  Income  Hours\n",
       "0       1   26   18000     14\n",
       "1       0   43   13000      9\n",
       "2       1   55   42000     16\n",
       "3       1   55  100000     13\n",
       "4       0   55   13000     12"
      ]
     },
     "execution_count": 65,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "# Load the data\n",
    "df = pd.read_excel(\"gym.xlsx\")\n",
    "df.head()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 66,
   "id": "b5809395-d339-4a18-bef1-ea12b06cc9f7",
   "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>Enroll</th>\n",
       "      <th>Age</th>\n",
       "      <th>Income</th>\n",
       "      <th>Hours</th>\n",
       "    </tr>\n",
       "  </thead>\n",
       "  <tbody>\n",
       "    <tr>\n",
       "      <th>count</th>\n",
       "      <td>1000.000000</td>\n",
       "      <td>1000.000000</td>\n",
       "      <td>1000.000000</td>\n",
       "      <td>1000.000000</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>mean</th>\n",
       "      <td>0.403000</td>\n",
       "      <td>44.582000</td>\n",
       "      <td>68340.000000</td>\n",
       "      <td>10.182000</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>std</th>\n",
       "      <td>0.490746</td>\n",
       "      <td>13.876737</td>\n",
       "      <td>44466.928247</td>\n",
       "      <td>4.671263</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>min</th>\n",
       "      <td>0.000000</td>\n",
       "      <td>21.000000</td>\n",
       "      <td>1000.000000</td>\n",
       "      <td>2.000000</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>25%</th>\n",
       "      <td>0.000000</td>\n",
       "      <td>32.000000</td>\n",
       "      <td>31000.000000</td>\n",
       "      <td>6.000000</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>50%</th>\n",
       "      <td>0.000000</td>\n",
       "      <td>45.000000</td>\n",
       "      <td>64000.000000</td>\n",
       "      <td>10.000000</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>75%</th>\n",
       "      <td>1.000000</td>\n",
       "      <td>57.000000</td>\n",
       "      <td>97000.000000</td>\n",
       "      <td>14.000000</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>max</th>\n",
       "      <td>1.000000</td>\n",
       "      <td>68.000000</td>\n",
       "      <td>198000.000000</td>\n",
       "      <td>18.000000</td>\n",
       "    </tr>\n",
       "  </tbody>\n",
       "</table>\n",
       "</div>"
      ],
      "text/plain": [
       "            Enroll          Age         Income        Hours\n",
       "count  1000.000000  1000.000000    1000.000000  1000.000000\n",
       "mean      0.403000    44.582000   68340.000000    10.182000\n",
       "std       0.490746    13.876737   44466.928247     4.671263\n",
       "min       0.000000    21.000000    1000.000000     2.000000\n",
       "25%       0.000000    32.000000   31000.000000     6.000000\n",
       "50%       0.000000    45.000000   64000.000000    10.000000\n",
       "75%       1.000000    57.000000   97000.000000    14.000000\n",
       "max       1.000000    68.000000  198000.000000    18.000000"
      ]
     },
     "execution_count": 66,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "df.describe()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 67,
   "id": "46f2b835-2f7d-4d65-a1e9-5dacaf6a370e",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "(1000, 4)"
      ]
     },
     "execution_count": 67,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "df.shape"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 68,
   "id": "92834d50-c430-4431-b5d9-81b10415dca1",
   "metadata": {},
   "outputs": [],
   "source": [
    "indAtts = [\"Age\", \"Income\", \"Hours\"]\n",
    "depAtt = \"Enroll\""
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 69,
   "id": "3b789418-6284-41cb-9c41-5f2b5d2114ac",
   "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>Income</th>\n",
       "      <th>Hours</th>\n",
       "    </tr>\n",
       "  </thead>\n",
       "  <tbody>\n",
       "    <tr>\n",
       "      <th>0</th>\n",
       "      <td>26</td>\n",
       "      <td>18000</td>\n",
       "      <td>14</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>1</th>\n",
       "      <td>43</td>\n",
       "      <td>13000</td>\n",
       "      <td>9</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>2</th>\n",
       "      <td>55</td>\n",
       "      <td>42000</td>\n",
       "      <td>16</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>3</th>\n",
       "      <td>55</td>\n",
       "      <td>100000</td>\n",
       "      <td>13</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>4</th>\n",
       "      <td>55</td>\n",
       "      <td>13000</td>\n",
       "      <td>12</td>\n",
       "    </tr>\n",
       "  </tbody>\n",
       "</table>\n",
       "</div>"
      ],
      "text/plain": [
       "   Age  Income  Hours\n",
       "0   26   18000     14\n",
       "1   43   13000      9\n",
       "2   55   42000     16\n",
       "3   55  100000     13\n",
       "4   55   13000     12"
      ]
     },
     "execution_count": 69,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "# Separate features and target variable\n",
    "Xs = df[indAtts]\n",
    "Xs.head()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 70,
   "id": "c9c82753-ed45-4d63-9f5a-75fd54d196fb",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "0      1\n",
       "1      0\n",
       "2      1\n",
       "3      1\n",
       "4      0\n",
       "      ..\n",
       "995    0\n",
       "996    0\n",
       "997    1\n",
       "998    1\n",
       "999    0\n",
       "Name: Enroll, Length: 1000, dtype: int64"
      ]
     },
     "execution_count": 70,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "y = df[depAtt]\n",
    "y\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 71,
   "id": "13b2648e-6a32-4775-9970-3e0c466271fe",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "array([[-1.33974561, -1.13264376,  0.81774684],\n",
       "       [-0.11406079, -1.24514314, -0.25316311],\n",
       "       [ 0.7511285 , -0.59264674,  1.24611082],\n",
       "       ...,\n",
       "       [ 0.7511285 ,  0.03734979,  1.46029281],\n",
       "       [ 1.68841689, -0.09764946,  1.03192883],\n",
       "       [ 0.24643475, -0.03014983,  1.6744748 ]])"
      ]
     },
     "execution_count": 71,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "# Scale the features\n",
    "scaler = StandardScaler()\n",
    "XsScaled = scaler.fit_transform(Xs)\n",
    "XsScaled"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 72,
   "id": "b3d1b271-1670-410e-a98b-c0af06571d70",
   "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>Income</th>\n",
       "      <th>Hours</th>\n",
       "      <th>Enroll</th>\n",
       "    </tr>\n",
       "  </thead>\n",
       "  <tbody>\n",
       "    <tr>\n",
       "      <th>0</th>\n",
       "      <td>-1.339746</td>\n",
       "      <td>-1.132644</td>\n",
       "      <td>0.817747</td>\n",
       "      <td>1</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>1</th>\n",
       "      <td>-0.114061</td>\n",
       "      <td>-1.245143</td>\n",
       "      <td>-0.253163</td>\n",
       "      <td>0</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>2</th>\n",
       "      <td>0.751128</td>\n",
       "      <td>-0.592647</td>\n",
       "      <td>1.246111</td>\n",
       "      <td>1</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>3</th>\n",
       "      <td>0.751128</td>\n",
       "      <td>0.712346</td>\n",
       "      <td>0.603565</td>\n",
       "      <td>1</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>4</th>\n",
       "      <td>0.751128</td>\n",
       "      <td>-1.245143</td>\n",
       "      <td>0.389383</td>\n",
       "      <td>0</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>...</th>\n",
       "      <td>...</td>\n",
       "      <td>...</td>\n",
       "      <td>...</td>\n",
       "      <td>...</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>995</th>\n",
       "      <td>-0.402457</td>\n",
       "      <td>-1.425142</td>\n",
       "      <td>0.603565</td>\n",
       "      <td>0</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>996</th>\n",
       "      <td>-0.474556</td>\n",
       "      <td>-1.425142</td>\n",
       "      <td>-1.538255</td>\n",
       "      <td>0</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>997</th>\n",
       "      <td>0.751128</td>\n",
       "      <td>0.037350</td>\n",
       "      <td>1.460293</td>\n",
       "      <td>1</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>998</th>\n",
       "      <td>1.688417</td>\n",
       "      <td>-0.097649</td>\n",
       "      <td>1.031929</td>\n",
       "      <td>1</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>999</th>\n",
       "      <td>0.246435</td>\n",
       "      <td>-0.030150</td>\n",
       "      <td>1.674475</td>\n",
       "      <td>0</td>\n",
       "    </tr>\n",
       "  </tbody>\n",
       "</table>\n",
       "<p>1000 rows × 4 columns</p>\n",
       "</div>"
      ],
      "text/plain": [
       "          Age    Income     Hours Enroll\n",
       "0   -1.339746 -1.132644  0.817747      1\n",
       "1   -0.114061 -1.245143 -0.253163      0\n",
       "2    0.751128 -0.592647  1.246111      1\n",
       "3    0.751128  0.712346  0.603565      1\n",
       "4    0.751128 -1.245143  0.389383      0\n",
       "..        ...       ...       ...    ...\n",
       "995 -0.402457 -1.425142  0.603565      0\n",
       "996 -0.474556 -1.425142 -1.538255      0\n",
       "997  0.751128  0.037350  1.460293      1\n",
       "998  1.688417 -0.097649  1.031929      1\n",
       "999  0.246435 -0.030150  1.674475      0\n",
       "\n",
       "[1000 rows x 4 columns]"
      ]
     },
     "execution_count": 72,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "# Combine scaled features and target into a new DataFrame\n",
    "dfScaled = pd.DataFrame(XsScaled, columns=Xs.columns)\n",
    "dfScaled[depAtt] = y.astype('category')\n",
    "dfScaled"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 73,
   "id": "4e6402c1-05f3-4cfe-b96d-9758d36aed57",
   "metadata": {},
   "outputs": [],
   "source": [
    "# Split the data into training and testing sets\n",
    "X_train, X_test, y_train, y_test = train_test_split(\n",
    "    dfScaled[indAtts],\n",
    "    dfScaled[depAtt],\n",
    "    test_size=0.4,\n",
    "    random_state=1,\n",
    "    stratify=dfScaled[depAtt]\n",
    ")\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 74,
   "id": "a9b32cbd-f135-4c17-9b52-7078722caae3",
   "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>Income</th>\n",
       "      <th>Hours</th>\n",
       "    </tr>\n",
       "  </thead>\n",
       "  <tbody>\n",
       "    <tr>\n",
       "      <th>808</th>\n",
       "      <td>0.030137</td>\n",
       "      <td>0.824845</td>\n",
       "      <td>1.674475</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>393</th>\n",
       "      <td>-0.618755</td>\n",
       "      <td>-0.975145</td>\n",
       "      <td>0.175201</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>416</th>\n",
       "      <td>-0.979250</td>\n",
       "      <td>-1.425142</td>\n",
       "      <td>0.817747</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>486</th>\n",
       "      <td>0.679029</td>\n",
       "      <td>-1.065144</td>\n",
       "      <td>0.817747</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>422</th>\n",
       "      <td>-0.114061</td>\n",
       "      <td>-1.267643</td>\n",
       "      <td>-1.324073</td>\n",
       "    </tr>\n",
       "  </tbody>\n",
       "</table>\n",
       "</div>"
      ],
      "text/plain": [
       "          Age    Income     Hours\n",
       "808  0.030137  0.824845  1.674475\n",
       "393 -0.618755 -0.975145  0.175201\n",
       "416 -0.979250 -1.425142  0.817747\n",
       "486  0.679029 -1.065144  0.817747\n",
       "422 -0.114061 -1.267643 -1.324073"
      ]
     },
     "execution_count": 74,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "X_train.head()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 75,
   "id": "2226b885-9cff-41aa-a0f4-35ef5682daaa",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/html": [
       "<style>#sk-container-id-4 {\n",
       "  /* Definition of color scheme common for light and dark mode */\n",
       "  --sklearn-color-text: black;\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-4 {\n",
       "  color: var(--sklearn-color-text);\n",
       "}\n",
       "\n",
       "#sk-container-id-4 pre {\n",
       "  padding: 0;\n",
       "}\n",
       "\n",
       "#sk-container-id-4 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-4 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-4 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-4 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-4 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-4 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-4 div.sk-parallel-item {\n",
       "  display: flex;\n",
       "  flex-direction: column;\n",
       "}\n",
       "\n",
       "#sk-container-id-4 div.sk-parallel-item:first-child::after {\n",
       "  align-self: flex-end;\n",
       "  width: 50%;\n",
       "}\n",
       "\n",
       "#sk-container-id-4 div.sk-parallel-item:last-child::after {\n",
       "  align-self: flex-start;\n",
       "  width: 50%;\n",
       "}\n",
       "\n",
       "#sk-container-id-4 div.sk-parallel-item:only-child::after {\n",
       "  width: 0;\n",
       "}\n",
       "\n",
       "/* Serial-specific style estimator block */\n",
       "\n",
       "#sk-container-id-4 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-4 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-4 label.sk-toggleable__label {\n",
       "  cursor: pointer;\n",
       "  display: block;\n",
       "  width: 100%;\n",
       "  margin-bottom: 0;\n",
       "  padding: 0.5em;\n",
       "  box-sizing: border-box;\n",
       "  text-align: center;\n",
       "}\n",
       "\n",
       "#sk-container-id-4 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-4 label.sk-toggleable__label-arrow:hover:before {\n",
       "  color: var(--sklearn-color-text);\n",
       "}\n",
       "\n",
       "/* Toggleable content - dropdown */\n",
       "\n",
       "#sk-container-id-4 div.sk-toggleable__content {\n",
       "  max-height: 0;\n",
       "  max-width: 0;\n",
       "  overflow: hidden;\n",
       "  text-align: left;\n",
       "  /* unfitted */\n",
       "  background-color: var(--sklearn-color-unfitted-level-0);\n",
       "}\n",
       "\n",
       "#sk-container-id-4 div.sk-toggleable__content.fitted {\n",
       "  /* fitted */\n",
       "  background-color: var(--sklearn-color-fitted-level-0);\n",
       "}\n",
       "\n",
       "#sk-container-id-4 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-4 div.sk-toggleable__content.fitted pre {\n",
       "  /* unfitted */\n",
       "  background-color: var(--sklearn-color-fitted-level-0);\n",
       "}\n",
       "\n",
       "#sk-container-id-4 input.sk-toggleable__control:checked~div.sk-toggleable__content {\n",
       "  /* Expand drop-down */\n",
       "  max-height: 200px;\n",
       "  max-width: 100%;\n",
       "  overflow: auto;\n",
       "}\n",
       "\n",
       "#sk-container-id-4 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-4 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-4 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-4 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-4 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-4 div.sk-label label.sk-toggleable__label,\n",
       "#sk-container-id-4 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-4 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-4 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-4 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-4 div.sk-label-container {\n",
       "  text-align: center;\n",
       "}\n",
       "\n",
       "/* Estimator-specific */\n",
       "#sk-container-id-4 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-4 div.sk-estimator.fitted {\n",
       "  /* fitted */\n",
       "  background-color: var(--sklearn-color-fitted-level-0);\n",
       "}\n",
       "\n",
       "/* on hover */\n",
       "#sk-container-id-4 div.sk-estimator:hover {\n",
       "  /* unfitted */\n",
       "  background-color: var(--sklearn-color-unfitted-level-2);\n",
       "}\n",
       "\n",
       "#sk-container-id-4 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: 1ex;\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-4 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-4 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-4 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-4 a.estimator_doc_link.fitted:hover {\n",
       "  /* fitted */\n",
       "  background-color: var(--sklearn-color-fitted-level-3);\n",
       "}\n",
       "</style><div id=\"sk-container-id-4\" class=\"sk-top-container\"><div class=\"sk-text-repr-fallback\"><pre>GridSearchCV(cv=5, estimator=KNeighborsClassifier(),\n",
       "             param_grid={&#x27;n_neighbors&#x27;: [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]})</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 sk-dashed-wrapped\"><div class=\"sk-label-container\"><div class=\"sk-label fitted sk-toggleable\"><input class=\"sk-toggleable__control sk-hidden--visually\" id=\"sk-estimator-id-10\" type=\"checkbox\" ><label for=\"sk-estimator-id-10\" class=\"sk-toggleable__label fitted sk-toggleable__label-arrow fitted\">&nbsp;&nbsp;GridSearchCV<a class=\"sk-estimator-doc-link fitted\" rel=\"noreferrer\" target=\"_blank\" href=\"https://scikit-learn.org/1.5/modules/generated/sklearn.model_selection.GridSearchCV.html\">?<span>Documentation for GridSearchCV</span></a><span class=\"sk-estimator-doc-link fitted\">i<span>Fitted</span></span></label><div class=\"sk-toggleable__content fitted\"><pre>GridSearchCV(cv=5, estimator=KNeighborsClassifier(),\n",
       "             param_grid={&#x27;n_neighbors&#x27;: [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]})</pre></div> </div></div><div class=\"sk-parallel\"><div class=\"sk-parallel-item\"><div class=\"sk-item\"><div class=\"sk-label-container\"><div class=\"sk-label fitted sk-toggleable\"><input class=\"sk-toggleable__control sk-hidden--visually\" id=\"sk-estimator-id-11\" type=\"checkbox\" ><label for=\"sk-estimator-id-11\" class=\"sk-toggleable__label fitted sk-toggleable__label-arrow fitted\">best_estimator_: KNeighborsClassifier</label><div class=\"sk-toggleable__content fitted\"><pre>KNeighborsClassifier()</pre></div> </div></div><div class=\"sk-serial\"><div class=\"sk-item\"><div class=\"sk-estimator fitted sk-toggleable\"><input class=\"sk-toggleable__control sk-hidden--visually\" id=\"sk-estimator-id-12\" type=\"checkbox\" ><label for=\"sk-estimator-id-12\" class=\"sk-toggleable__label fitted sk-toggleable__label-arrow fitted\">&nbsp;KNeighborsClassifier<a class=\"sk-estimator-doc-link fitted\" rel=\"noreferrer\" target=\"_blank\" href=\"https://scikit-learn.org/1.5/modules/generated/sklearn.neighbors.KNeighborsClassifier.html\">?<span>Documentation for KNeighborsClassifier</span></a></label><div class=\"sk-toggleable__content fitted\"><pre>KNeighborsClassifier()</pre></div> </div></div></div></div></div></div></div></div></div>"
      ],
      "text/plain": [
       "GridSearchCV(cv=5, estimator=KNeighborsClassifier(),\n",
       "             param_grid={'n_neighbors': [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]})"
      ]
     },
     "execution_count": 75,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "# Perform k-NN classification with cross-validation to find the best k\n",
    "knn = KNeighborsClassifier()\n",
    "param_grid = {'n_neighbors': list(range(1, 11))}\n",
    "grid_search = GridSearchCV(knn, param_grid, cv=5)\n",
    "grid_search.fit(X_train, y_train)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 76,
   "id": "779e861d-04cf-4d8f-94e0-e42c96525b61",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Best parameters: {'n_neighbors': 5}\n",
      "Best cross-validation score: 0.915\n"
     ]
    }
   ],
   "source": [
    "print(\"Best parameters:\", grid_search.best_params_)\n",
    "print(\"Best cross-validation score:\", grid_search.best_score_)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 77,
   "id": "046a78bc-4b77-44d9-a5d9-3d6084d1ad16",
   "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>mean_fit_time</th>\n",
       "      <th>std_fit_time</th>\n",
       "      <th>mean_score_time</th>\n",
       "      <th>std_score_time</th>\n",
       "      <th>param_n_neighbors</th>\n",
       "      <th>params</th>\n",
       "      <th>split0_test_score</th>\n",
       "      <th>split1_test_score</th>\n",
       "      <th>split2_test_score</th>\n",
       "      <th>split3_test_score</th>\n",
       "      <th>split4_test_score</th>\n",
       "      <th>mean_test_score</th>\n",
       "      <th>std_test_score</th>\n",
       "      <th>rank_test_score</th>\n",
       "    </tr>\n",
       "  </thead>\n",
       "  <tbody>\n",
       "    <tr>\n",
       "      <th>0</th>\n",
       "      <td>0.001109</td>\n",
       "      <td>0.000455</td>\n",
       "      <td>0.003694</td>\n",
       "      <td>0.000536</td>\n",
       "      <td>1</td>\n",
       "      <td>{'n_neighbors': 1}</td>\n",
       "      <td>0.866667</td>\n",
       "      <td>0.908333</td>\n",
       "      <td>0.866667</td>\n",
       "      <td>0.900000</td>\n",
       "      <td>0.916667</td>\n",
       "      <td>0.891667</td>\n",
       "      <td>0.021082</td>\n",
       "      <td>9</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>1</th>\n",
       "      <td>0.000886</td>\n",
       "      <td>0.000090</td>\n",
       "      <td>0.003221</td>\n",
       "      <td>0.000229</td>\n",
       "      <td>2</td>\n",
       "      <td>{'n_neighbors': 2}</td>\n",
       "      <td>0.833333</td>\n",
       "      <td>0.858333</td>\n",
       "      <td>0.883333</td>\n",
       "      <td>0.866667</td>\n",
       "      <td>0.866667</td>\n",
       "      <td>0.861667</td>\n",
       "      <td>0.016330</td>\n",
       "      <td>10</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>2</th>\n",
       "      <td>0.000670</td>\n",
       "      <td>0.000071</td>\n",
       "      <td>0.002760</td>\n",
       "      <td>0.000318</td>\n",
       "      <td>3</td>\n",
       "      <td>{'n_neighbors': 3}</td>\n",
       "      <td>0.908333</td>\n",
       "      <td>0.916667</td>\n",
       "      <td>0.883333</td>\n",
       "      <td>0.933333</td>\n",
       "      <td>0.900000</td>\n",
       "      <td>0.908333</td>\n",
       "      <td>0.016667</td>\n",
       "      <td>2</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>3</th>\n",
       "      <td>0.000545</td>\n",
       "      <td>0.000020</td>\n",
       "      <td>0.002311</td>\n",
       "      <td>0.000066</td>\n",
       "      <td>4</td>\n",
       "      <td>{'n_neighbors': 4}</td>\n",
       "      <td>0.850000</td>\n",
       "      <td>0.925000</td>\n",
       "      <td>0.858333</td>\n",
       "      <td>0.933333</td>\n",
       "      <td>0.900000</td>\n",
       "      <td>0.893333</td>\n",
       "      <td>0.033912</td>\n",
       "      <td>8</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>4</th>\n",
       "      <td>0.000489</td>\n",
       "      <td>0.000010</td>\n",
       "      <td>0.002191</td>\n",
       "      <td>0.000051</td>\n",
       "      <td>5</td>\n",
       "      <td>{'n_neighbors': 5}</td>\n",
       "      <td>0.875000</td>\n",
       "      <td>0.941667</td>\n",
       "      <td>0.883333</td>\n",
       "      <td>0.950000</td>\n",
       "      <td>0.925000</td>\n",
       "      <td>0.915000</td>\n",
       "      <td>0.030459</td>\n",
       "      <td>1</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>5</th>\n",
       "      <td>0.000457</td>\n",
       "      <td>0.000006</td>\n",
       "      <td>0.002055</td>\n",
       "      <td>0.000038</td>\n",
       "      <td>6</td>\n",
       "      <td>{'n_neighbors': 6}</td>\n",
       "      <td>0.866667</td>\n",
       "      <td>0.941667</td>\n",
       "      <td>0.858333</td>\n",
       "      <td>0.933333</td>\n",
       "      <td>0.916667</td>\n",
       "      <td>0.903333</td>\n",
       "      <td>0.034400</td>\n",
       "      <td>5</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>6</th>\n",
       "      <td>0.000439</td>\n",
       "      <td>0.000006</td>\n",
       "      <td>0.001990</td>\n",
       "      <td>0.000035</td>\n",
       "      <td>7</td>\n",
       "      <td>{'n_neighbors': 7}</td>\n",
       "      <td>0.875000</td>\n",
       "      <td>0.933333</td>\n",
       "      <td>0.858333</td>\n",
       "      <td>0.941667</td>\n",
       "      <td>0.916667</td>\n",
       "      <td>0.905000</td>\n",
       "      <td>0.032745</td>\n",
       "      <td>4</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>7</th>\n",
       "      <td>0.000436</td>\n",
       "      <td>0.000005</td>\n",
       "      <td>0.001974</td>\n",
       "      <td>0.000008</td>\n",
       "      <td>8</td>\n",
       "      <td>{'n_neighbors': 8}</td>\n",
       "      <td>0.866667</td>\n",
       "      <td>0.933333</td>\n",
       "      <td>0.858333</td>\n",
       "      <td>0.933333</td>\n",
       "      <td>0.908333</td>\n",
       "      <td>0.900000</td>\n",
       "      <td>0.032059</td>\n",
       "      <td>7</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>8</th>\n",
       "      <td>0.000430</td>\n",
       "      <td>0.000004</td>\n",
       "      <td>0.001981</td>\n",
       "      <td>0.000016</td>\n",
       "      <td>9</td>\n",
       "      <td>{'n_neighbors': 9}</td>\n",
       "      <td>0.866667</td>\n",
       "      <td>0.925000</td>\n",
       "      <td>0.883333</td>\n",
       "      <td>0.941667</td>\n",
       "      <td>0.916667</td>\n",
       "      <td>0.906667</td>\n",
       "      <td>0.027588</td>\n",
       "      <td>3</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>9</th>\n",
       "      <td>0.000472</td>\n",
       "      <td>0.000047</td>\n",
       "      <td>0.002084</td>\n",
       "      <td>0.000079</td>\n",
       "      <td>10</td>\n",
       "      <td>{'n_neighbors': 10}</td>\n",
       "      <td>0.841667</td>\n",
       "      <td>0.941667</td>\n",
       "      <td>0.866667</td>\n",
       "      <td>0.941667</td>\n",
       "      <td>0.916667</td>\n",
       "      <td>0.901667</td>\n",
       "      <td>0.040620</td>\n",
       "      <td>6</td>\n",
       "    </tr>\n",
       "  </tbody>\n",
       "</table>\n",
       "</div>"
      ],
      "text/plain": [
       "   mean_fit_time  std_fit_time  mean_score_time  std_score_time  \\\n",
       "0       0.001109      0.000455         0.003694        0.000536   \n",
       "1       0.000886      0.000090         0.003221        0.000229   \n",
       "2       0.000670      0.000071         0.002760        0.000318   \n",
       "3       0.000545      0.000020         0.002311        0.000066   \n",
       "4       0.000489      0.000010         0.002191        0.000051   \n",
       "5       0.000457      0.000006         0.002055        0.000038   \n",
       "6       0.000439      0.000006         0.001990        0.000035   \n",
       "7       0.000436      0.000005         0.001974        0.000008   \n",
       "8       0.000430      0.000004         0.001981        0.000016   \n",
       "9       0.000472      0.000047         0.002084        0.000079   \n",
       "\n",
       "   param_n_neighbors               params  split0_test_score  \\\n",
       "0                  1   {'n_neighbors': 1}           0.866667   \n",
       "1                  2   {'n_neighbors': 2}           0.833333   \n",
       "2                  3   {'n_neighbors': 3}           0.908333   \n",
       "3                  4   {'n_neighbors': 4}           0.850000   \n",
       "4                  5   {'n_neighbors': 5}           0.875000   \n",
       "5                  6   {'n_neighbors': 6}           0.866667   \n",
       "6                  7   {'n_neighbors': 7}           0.875000   \n",
       "7                  8   {'n_neighbors': 8}           0.866667   \n",
       "8                  9   {'n_neighbors': 9}           0.866667   \n",
       "9                 10  {'n_neighbors': 10}           0.841667   \n",
       "\n",
       "   split1_test_score  split2_test_score  split3_test_score  split4_test_score  \\\n",
       "0           0.908333           0.866667           0.900000           0.916667   \n",
       "1           0.858333           0.883333           0.866667           0.866667   \n",
       "2           0.916667           0.883333           0.933333           0.900000   \n",
       "3           0.925000           0.858333           0.933333           0.900000   \n",
       "4           0.941667           0.883333           0.950000           0.925000   \n",
       "5           0.941667           0.858333           0.933333           0.916667   \n",
       "6           0.933333           0.858333           0.941667           0.916667   \n",
       "7           0.933333           0.858333           0.933333           0.908333   \n",
       "8           0.925000           0.883333           0.941667           0.916667   \n",
       "9           0.941667           0.866667           0.941667           0.916667   \n",
       "\n",
       "   mean_test_score  std_test_score  rank_test_score  \n",
       "0         0.891667        0.021082                9  \n",
       "1         0.861667        0.016330               10  \n",
       "2         0.908333        0.016667                2  \n",
       "3         0.893333        0.033912                8  \n",
       "4         0.915000        0.030459                1  \n",
       "5         0.903333        0.034400                5  \n",
       "6         0.905000        0.032745                4  \n",
       "7         0.900000        0.032059                7  \n",
       "8         0.906667        0.027588                3  \n",
       "9         0.901667        0.040620                6  "
      ]
     },
     "execution_count": 77,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "# Display detailed results\n",
    "results = pd.DataFrame(grid_search.cv_results_)\n",
    "results"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 78,
   "id": "1f78ee56-b9c8-4d1a-aef9-ad37dfa41858",
   "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>Actual</th>\n",
       "      <th>Predicted</th>\n",
       "    </tr>\n",
       "  </thead>\n",
       "  <tbody>\n",
       "    <tr>\n",
       "      <th>489</th>\n",
       "      <td>1</td>\n",
       "      <td>1</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>241</th>\n",
       "      <td>0</td>\n",
       "      <td>0</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>119</th>\n",
       "      <td>0</td>\n",
       "      <td>0</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>577</th>\n",
       "      <td>0</td>\n",
       "      <td>0</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>287</th>\n",
       "      <td>0</td>\n",
       "      <td>0</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>...</th>\n",
       "      <td>...</td>\n",
       "      <td>...</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>804</th>\n",
       "      <td>1</td>\n",
       "      <td>1</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>974</th>\n",
       "      <td>1</td>\n",
       "      <td>1</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>810</th>\n",
       "      <td>1</td>\n",
       "      <td>1</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>395</th>\n",
       "      <td>0</td>\n",
       "      <td>0</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>861</th>\n",
       "      <td>0</td>\n",
       "      <td>0</td>\n",
       "    </tr>\n",
       "  </tbody>\n",
       "</table>\n",
       "<p>400 rows × 2 columns</p>\n",
       "</div>"
      ],
      "text/plain": [
       "    Actual  Predicted\n",
       "489      1          1\n",
       "241      0          0\n",
       "119      0          0\n",
       "577      0          0\n",
       "287      0          0\n",
       "..     ...        ...\n",
       "804      1          1\n",
       "974      1          1\n",
       "810      1          1\n",
       "395      0          0\n",
       "861      0          0\n",
       "\n",
       "[400 rows x 2 columns]"
      ]
     },
     "execution_count": 78,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "# Make predictions on the test set\n",
    "best_knn = grid_search.best_estimator_\n",
    "predictions = best_knn.predict(X_test)\n",
    "# Combine y_test and predictions into a DataFrame\n",
    "results_df = pd.DataFrame({'Actual': y_test, 'Predicted': predictions})\n",
    "results_df"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 80,
   "id": "777a6302-6139-4199-9ed0-68f5e8938612",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Confusion Matrix as DataFrame:\n",
      "             Actual_0  Actual_1\n",
      "Predicted_0       217        22\n",
      "Predicted_1        17       144\n"
     ]
    }
   ],
   "source": [
    "# Confusion matrix\n",
    "conf_matrix = confusion_matrix(y_test, predictions)\n",
    "\n",
    "# Convert confusion matrix to DataFrame with predicted as rows and actual as columns\n",
    "conf_matrix_df = pd.DataFrame(conf_matrix, index=['Predicted_0', 'Predicted_1'], columns=['Actual_0', 'Actual_1'])\n",
    "print(\"Confusion Matrix as DataFrame:\")\n",
    "print(conf_matrix_df)\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 82,
   "id": "aa493759-f506-4278-a212-4a3a0b5db15a",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Accuracy: 0.9025\n",
      "Precision: 0.8674698795180723\n",
      "Recall (Sensitivity): 0.8944099378881988\n",
      "Specificity: 0.9079497907949791\n",
      "F1 Score: 0.8807339449541285\n"
     ]
    }
   ],
   "source": [
    "# Calculate metrics\n",
    "precision = precision_score(y_test, predictions)\n",
    "recall = recall_score(y_test, predictions)\n",
    "accuracy = accuracy_score(y_test, predictions)\n",
    "specificity = conf_matrix[0, 0] / (conf_matrix[0, 0] + conf_matrix[0, 1])\n",
    "f1_score = 2 * (precision * recall) / (precision + recall)\n",
    "\n",
    "print(f\"Accuracy: {accuracy}\")\n",
    "print(f\"Precision: {precision}\")\n",
    "print(f\"Recall (Sensitivity): {recall}\")\n",
    "print(f\"Specificity: {specificity}\")\n",
    "print(f\"F1 Score: {f1_score}\")"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 84,
   "id": "c9a97f8e-0ebc-4b51-a4a1-ff059dd75535",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "array([1. , 0. , 0.2, 0.4, 0.2, 0.6, 1. , 0.2, 0.8, 0. , 0. , 0.2, 0. ,\n",
       "       0. , 0.6, 0.6, 0. , 0. , 0. , 0.8, 1. , 0. , 1. , 0.8, 0. , 0.8,\n",
       "       0. , 0.2, 1. , 0. , 0.8, 0. , 0.2, 0.2, 0. , 0. , 0.4, 0.4, 0. ,\n",
       "       1. , 0. , 0.8, 0. , 0.8, 0. , 0.8, 0. , 0.6, 1. , 0.8, 0. , 1. ,\n",
       "       1. , 0.8, 0.4, 0. , 0.8, 0. , 0.2, 0. , 0.6, 1. , 0.6, 0. , 1. ,\n",
       "       0. , 0.8, 0. , 0. , 0.2, 0.2, 0.8, 1. , 0. , 0. , 0. , 0.8, 0.4,\n",
       "       1. , 0. , 0. , 1. , 0. , 0.2, 0. , 0.8, 0. , 1. , 0. , 0. , 0. ,\n",
       "       0. , 0. , 1. , 1. , 1. , 0. , 1. , 0. , 0. , 0.4, 0.2, 1. , 0. ,\n",
       "       1. , 0.8, 1. , 1. , 0. , 1. , 0.8, 1. , 1. , 1. , 0. , 0. , 1. ,\n",
       "       0.8, 0. , 0. , 0.2, 0.8, 0. , 1. , 1. , 1. , 0.8, 1. , 1. , 0.8,\n",
       "       0.2, 0. , 0. , 0. , 0.6, 0. , 1. , 0.2, 0. , 1. , 0. , 0. , 0.8,\n",
       "       0.6, 0. , 0. , 0. , 0.2, 0.4, 1. , 0.8, 0. , 1. , 0. , 0. , 1. ,\n",
       "       1. , 0. , 0.6, 0. , 0. , 0. , 0.2, 0.2, 0.4, 0.2, 0.2, 0.4, 1. ,\n",
       "       0.8, 0. , 0.8, 0. , 0. , 0.2, 1. , 0. , 0. , 0. , 0. , 1. , 0. ,\n",
       "       0. , 1. , 0. , 0.2, 0. , 1. , 0. , 0.2, 1. , 0. , 0.4, 0.2, 0.2,\n",
       "       0. , 0.6, 0.2, 0.6, 0.6, 0. , 0. , 0.8, 0.8, 0.8, 0. , 0. , 0. ,\n",
       "       0. , 0. , 0. , 0.4, 0. , 0. , 0.6, 1. , 1. , 0.2, 0. , 0.8, 0. ,\n",
       "       0. , 0. , 0. , 0.2, 1. , 1. , 0.2, 1. , 0.2, 0. , 0.8, 0. , 0. ,\n",
       "       0. , 1. , 0.4, 1. , 0. , 0. , 1. , 1. , 0. , 0.2, 1. , 0.6, 0.4,\n",
       "       0.8, 1. , 0. , 0. , 1. , 0.2, 0. , 1. , 0.8, 0.6, 0. , 0.8, 1. ,\n",
       "       0.4, 0. , 0. , 0.6, 0.6, 0. , 1. , 0.2, 1. , 1. , 0.6, 0.2, 0.8,\n",
       "       1. , 0.2, 0.2, 0. , 0. , 1. , 1. , 0.8, 0.8, 0. , 0.2, 1. , 0.8,\n",
       "       0. , 0.8, 0. , 1. , 0. , 0. , 1. , 0.8, 0.2, 0.2, 0.2, 0. , 0.6,\n",
       "       1. , 1. , 0.2, 0. , 0. , 0. , 0.2, 0.8, 1. , 1. , 1. , 0. , 0.8,\n",
       "       0.8, 0.4, 0. , 0.4, 0. , 1. , 0.4, 0.8, 0.4, 0.2, 0. , 0. , 0. ,\n",
       "       0. , 0. , 0. , 0.8, 0.8, 0. , 0.8, 0.8, 0. , 1. , 0.2, 0. , 0. ,\n",
       "       0.6, 1. , 0.8, 0. , 0. , 0. , 0. , 0.8, 0. , 0.6, 0. , 0.8, 0.2,\n",
       "       0. , 0. , 0. , 0.8, 0.6, 0. , 1. , 0. , 0.4, 0. , 0.4, 0. , 0.8,\n",
       "       0. , 0. , 0.2, 1. , 0.4, 0. , 0.2, 0.2, 0.8, 0. , 0.8, 0. , 0.2,\n",
       "       0.8, 0. , 0. , 0.8, 0.6, 0. , 0.8, 0. , 0.8, 0. , 1. , 0. , 0. ,\n",
       "       0.2, 0.8, 1. , 0.8, 0. , 0.6, 1. , 0.8, 0.2, 0.2])"
      ]
     },
     "execution_count": 84,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "# Predict probabilities for ROC curve\n",
    "probs= best_knn.predict_proba(X_test)[:, 1]\n",
    "probs"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 85,
   "id": "b23ed9f8-b1c0-491c-b048-112a0797299f",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "ROC AUC: 0.9423191870890616\n"
     ]
    }
   ],
   "source": [
    "roc_auc = roc_auc_score(y_test, probs)\n",
    "print(\"ROC AUC:\", roc_auc)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 90,
   "id": "ffe52a48-533d-43db-b845-8aab740638ef",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "image/png": "[encoded data, 45368 characters]",
      "text/plain": [
       "<Figure size 640x480 with 1 Axes>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    }
   ],
   "source": [
    "# Plot ROC curve\n",
    "fpr, tpr, _ = roc_curve(y_test, probs )\n",
    "plt.figure()\n",
    "plt.plot(fpr, tpr, label=f'ROC curve (area = {roc_auc:.2f})')\n",
    "plt.plot([0, 1], [0, 1], 'k--')\n",
    "plt.xlim([0.0, 1.0])\n",
    "plt.ylim([0.0, 1.05])\n",
    "plt.xlabel('False Positive Rate')\n",
    "plt.ylabel('True Positive Rate')\n",
    "plt.title('Receiver Operating Characteristic')\n",
    "plt.legend(loc=\"lower right\")\n",
    "plt.show()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "68206bb3-19e3-435a-a311-e82035c1d57a",
   "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.3"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 5
}
