{
 "cells": [
  {
   "cell_type": "code",
   "execution_count": 1,
   "id": "28511a89",
   "metadata": {},
   "outputs": [],
   "source": [
    "# Import dependencies and packages needed\n",
    "from sklearn import neighbors, datasets\n",
    "from sklearn.model_selection import train_test_split\n",
    "import numpy as np\n",
    "import pandas as pd\n",
    "import seaborn as sn\n",
    "import matplotlib.pyplot as plt\n",
    "from sklearn import datasets"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 2,
   "id": "6492ec18",
   "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>PatientId</th>\n",
       "      <th>Pregnancies</th>\n",
       "      <th>Glucose</th>\n",
       "      <th>BloodPressure</th>\n",
       "      <th>SkinThickness</th>\n",
       "      <th>Insulin</th>\n",
       "      <th>BMI</th>\n",
       "      <th>DiabetesPedigreeFunction</th>\n",
       "      <th>Age</th>\n",
       "      <th>Outcome</th>\n",
       "    </tr>\n",
       "  </thead>\n",
       "  <tbody>\n",
       "    <tr>\n",
       "      <th>0</th>\n",
       "      <td>1</td>\n",
       "      <td>6</td>\n",
       "      <td>148</td>\n",
       "      <td>72</td>\n",
       "      <td>35</td>\n",
       "      <td>0</td>\n",
       "      <td>33.6</td>\n",
       "      <td>0.627</td>\n",
       "      <td>50</td>\n",
       "      <td>1</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>1</th>\n",
       "      <td>2</td>\n",
       "      <td>1</td>\n",
       "      <td>85</td>\n",
       "      <td>66</td>\n",
       "      <td>29</td>\n",
       "      <td>0</td>\n",
       "      <td>26.6</td>\n",
       "      <td>0.351</td>\n",
       "      <td>31</td>\n",
       "      <td>0</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>2</th>\n",
       "      <td>3</td>\n",
       "      <td>8</td>\n",
       "      <td>183</td>\n",
       "      <td>64</td>\n",
       "      <td>0</td>\n",
       "      <td>0</td>\n",
       "      <td>23.3</td>\n",
       "      <td>0.672</td>\n",
       "      <td>32</td>\n",
       "      <td>1</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>3</th>\n",
       "      <td>4</td>\n",
       "      <td>1</td>\n",
       "      <td>89</td>\n",
       "      <td>66</td>\n",
       "      <td>23</td>\n",
       "      <td>94</td>\n",
       "      <td>28.1</td>\n",
       "      <td>0.167</td>\n",
       "      <td>21</td>\n",
       "      <td>0</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>4</th>\n",
       "      <td>5</td>\n",
       "      <td>0</td>\n",
       "      <td>137</td>\n",
       "      <td>40</td>\n",
       "      <td>35</td>\n",
       "      <td>168</td>\n",
       "      <td>43.1</td>\n",
       "      <td>2.288</td>\n",
       "      <td>33</td>\n",
       "      <td>1</td>\n",
       "    </tr>\n",
       "  </tbody>\n",
       "</table>\n",
       "</div>"
      ],
      "text/plain": [
       "   PatientId  Pregnancies  Glucose  BloodPressure  SkinThickness  Insulin  \\\n",
       "0          1            6      148             72             35        0   \n",
       "1          2            1       85             66             29        0   \n",
       "2          3            8      183             64              0        0   \n",
       "3          4            1       89             66             23       94   \n",
       "4          5            0      137             40             35      168   \n",
       "\n",
       "    BMI  DiabetesPedigreeFunction  Age  Outcome  \n",
       "0  33.6                     0.627   50        1  \n",
       "1  26.6                     0.351   31        0  \n",
       "2  23.3                     0.672   32        1  \n",
       "3  28.1                     0.167   21        0  \n",
       "4  43.1                     2.288   33        1  "
      ]
     },
     "execution_count": 2,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "# import the dataset (stored in a variable)\n",
    "diabetes = pd.read_csv(\"diabetes.csv\")\n",
    "# Inspect the data(first five rows, or this can be changed by including how many rows within the brackets)\n",
    "diabetes.head()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 3,
   "id": "987e1130",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "<class 'pandas.core.frame.DataFrame'>\n",
      "Int64Index: 614 entries, 60 to 102\n",
      "Data columns (total 10 columns):\n",
      " #   Column                    Non-Null Count  Dtype  \n",
      "---  ------                    --------------  -----  \n",
      " 0   PatientId                 614 non-null    int64  \n",
      " 1   Pregnancies               614 non-null    int64  \n",
      " 2   Glucose                   614 non-null    int64  \n",
      " 3   BloodPressure             614 non-null    int64  \n",
      " 4   SkinThickness             614 non-null    int64  \n",
      " 5   Insulin                   614 non-null    int64  \n",
      " 6   BMI                       614 non-null    float64\n",
      " 7   DiabetesPedigreeFunction  614 non-null    float64\n",
      " 8   Age                       614 non-null    int64  \n",
      " 9   Outcome                   614 non-null    int64  \n",
      "dtypes: float64(2), int64(8)\n",
      "memory usage: 52.8 KB\n"
     ]
    }
   ],
   "source": [
    "# split the data into train and test using the SciKitLearn package\n",
    "from sklearn.model_selection import train_test_split\n",
    "train,test=train_test_split(diabetes,test_size=0.2,random_state=42)\n",
    "# view the information\n",
    "train.info()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 4,
   "id": "fea7a65c",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "<class 'pandas.core.frame.DataFrame'>\n",
      "Int64Index: 154 entries, 668 to 462\n",
      "Data columns (total 8 columns):\n",
      " #   Column                    Non-Null Count  Dtype  \n",
      "---  ------                    --------------  -----  \n",
      " 0   Pregnancies               154 non-null    int64  \n",
      " 1   Glucose                   154 non-null    int64  \n",
      " 2   BloodPressure             154 non-null    int64  \n",
      " 3   SkinThickness             154 non-null    int64  \n",
      " 4   Insulin                   154 non-null    int64  \n",
      " 5   BMI                       154 non-null    float64\n",
      " 6   DiabetesPedigreeFunction  154 non-null    float64\n",
      " 7   Age                       154 non-null    int64  \n",
      "dtypes: float64(2), int64(6)\n",
      "memory usage: 10.8 KB\n"
     ]
    }
   ],
   "source": [
    "# Ensure only labels are saved in y variables\n",
    "y_train=train['Outcome']\n",
    "y_test=test['Outcome']\n",
    "#drop the unwanted / irrelevant columns, features are stored in X variables\n",
    "X_train=train.drop(['PatientId','Outcome'],axis=1)\n",
    "X_test=test.drop(['PatientId','Outcome'],axis=1)\n",
    "# view the information\n",
    "X_test.info()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 5,
   "id": "48a3730a",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "{'algorithm': 'auto',\n",
       " 'leaf_size': 30,\n",
       " 'metric': 'minkowski',\n",
       " 'metric_params': None,\n",
       " 'n_jobs': None,\n",
       " 'n_neighbors': 5,\n",
       " 'p': 2,\n",
       " 'weights': 'uniform'}"
      ]
     },
     "execution_count": 5,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "# this step is just to demonstrate the adjustable parameters within the algorithm and not a necessary step\n",
    "neighbors.KNeighborsClassifier().get_params()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 6,
   "id": "5cd6e3bf",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "['__abstractmethods__',\n",
       " '__class__',\n",
       " '__delattr__',\n",
       " '__dict__',\n",
       " '__dir__',\n",
       " '__doc__',\n",
       " '__eq__',\n",
       " '__format__',\n",
       " '__ge__',\n",
       " '__getattribute__',\n",
       " '__getstate__',\n",
       " '__gt__',\n",
       " '__hash__',\n",
       " '__init__',\n",
       " '__init_subclass__',\n",
       " '__le__',\n",
       " '__lt__',\n",
       " '__module__',\n",
       " '__ne__',\n",
       " '__new__',\n",
       " '__reduce__',\n",
       " '__reduce_ex__',\n",
       " '__repr__',\n",
       " '__setattr__',\n",
       " '__setstate__',\n",
       " '__sizeof__',\n",
       " '__str__',\n",
       " '__subclasshook__',\n",
       " '__weakref__',\n",
       " '_abc_impl',\n",
       " '_check_algorithm_metric',\n",
       " '_check_feature_names',\n",
       " '_check_n_features',\n",
       " '_estimator_type',\n",
       " '_fit',\n",
       " '_get_param_names',\n",
       " '_get_tags',\n",
       " '_kneighbors_reduce_func',\n",
       " '_more_tags',\n",
       " '_pairwise',\n",
       " '_repr_html_',\n",
       " '_repr_html_inner',\n",
       " '_repr_mimebundle_',\n",
       " '_validate_data',\n",
       " 'fit',\n",
       " 'get_params',\n",
       " 'kneighbors',\n",
       " 'kneighbors_graph',\n",
       " 'predict',\n",
       " 'predict_proba',\n",
       " 'score',\n",
       " 'set_params']"
      ]
     },
     "execution_count": 6,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "# this step is just to demonstrate the api methods and not a necessary step\n",
    "dir(neighbors.KNeighborsClassifier)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 7,
   "id": "edaa2532",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "KNeighborsClassifier(n_neighbors=3)"
      ]
     },
     "execution_count": 7,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "# Create a model for K-Nearest Neighbours and include parameters\n",
    "model = neighbors.KNeighborsClassifier(n_neighbors=3)\n",
    "# fit the data to the model, both features and labels to train it\n",
    "model.fit(X_train, y_train)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 8,
   "id": "9c479ce4",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "array([0, 1, 0, 1, 1, 1, 0, 0, 1, 1, 0, 1, 0, 0, 0, 1, 0, 0, 1, 1, 1, 0,\n",
       "       1, 0, 1, 1, 0, 0, 0, 0, 1, 0, 1, 1, 0, 1, 1, 0, 0, 1, 0, 1, 1, 1,\n",
       "       0, 0, 0, 0, 0, 1, 0, 1, 1, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 0, 0, 1,\n",
       "       0, 0, 0, 1, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 1, 0, 1, 1, 0,\n",
       "       0, 0, 0, 0, 0, 0, 1, 1, 1, 0, 1, 0, 1, 0, 0, 0, 1, 1, 0, 1, 0, 1,\n",
       "       0, 1, 0, 1, 1, 1, 1, 0, 0, 0, 0, 0, 1, 0, 1, 1, 0, 1, 1, 1, 1, 0,\n",
       "       1, 1, 1, 1, 0, 1, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 1, 0, 0, 1, 0],\n",
       "      dtype=int64)"
      ]
     },
     "execution_count": 8,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "# use the model to classify the datapoints within the test set\n",
    "y_pred2=model.predict(X_test)\n",
    "# print predicted classifications\n",
    "y_pred2"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 9,
   "id": "c3a45ab5",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "668    0\n",
       "324    0\n",
       "624    0\n",
       "690    0\n",
       "473    0\n",
       "      ..\n",
       "355    1\n",
       "534    0\n",
       "344    0\n",
       "296    1\n",
       "462    0\n",
       "Name: Outcome, Length: 154, dtype: int64"
      ]
     },
     "execution_count": 9,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "# print test labels (ground truth) that is compared to classifier\n",
    "y_test"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 10,
   "id": "93c59e31",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "[[65 34]\n",
      " [20 35]]\n",
      "              precision    recall  f1-score   support\n",
      "\n",
      "           0      0.765     0.657     0.707        99\n",
      "           1      0.507     0.636     0.565        55\n",
      "\n",
      "    accuracy                          0.649       154\n",
      "   macro avg      0.636     0.646     0.636       154\n",
      "weighted avg      0.673     0.649     0.656       154\n",
      "\n"
     ]
    }
   ],
   "source": [
    "# display the metrics of the model's classification through confusion matrix and classification report\n",
    "# (accuracy / precision / recall / f1)\n",
    "from sklearn import metrics\n",
    "print(metrics.confusion_matrix(y_test, y_pred2))\n",
    "\n",
    "\n",
    "print(metrics.classification_report(y_test, y_pred2, digits=3))"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 11,
   "id": "40459779",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "     Actual  Predicted\n",
      "668       0          0\n",
      "324       0          1\n",
      "624       0          0\n",
      "690       0          1\n",
      "473       0          1\n",
      "..      ...        ...\n",
      "355       1          1\n",
      "534       0          0\n",
      "344       0          0\n",
      "296       1          1\n",
      "462       0          0\n",
      "\n",
      "[154 rows x 2 columns]\n"
     ]
    }
   ],
   "source": [
    "# use Pandas to create a dataframe to view the ground truth and classifications side by side\n",
    "data = {'Actual': y_test,\n",
    "        'Predicted': y_pred2}\n",
    "df = pd.DataFrame(data)\n",
    "print(df)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 12,
   "id": "4ad19c10",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "image/png": "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\n",
      "text/plain": [
       "<Figure size 432x288 with 2 Axes>"
      ]
     },
     "metadata": {
      "needs_background": "light"
     },
     "output_type": "display_data"
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "              precision    recall  f1-score   support\n",
      "\n",
      "           0      0.765     0.657     0.707        99\n",
      "           1      0.507     0.636     0.565        55\n",
      "\n",
      "    accuracy                          0.649       154\n",
      "   macro avg      0.636     0.646     0.636       154\n",
      "weighted avg      0.673     0.649     0.656       154\n",
      "\n"
     ]
    }
   ],
   "source": [
    "# Use Seaborn to create a confusion matrix heatmap and MatPlotLib to display\n",
    "confusion_matrix = pd.crosstab(df['Actual'], df['Predicted'], rownames=['Actual'], colnames=['Predicted'])\n",
    "sn.heatmap(confusion_matrix, annot=True)\n",
    "plt.show()\n",
    "print(metrics.classification_report(y_test, y_pred2, digits=3))"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 13,
   "id": "11fe93ff",
   "metadata": {},
   "outputs": [],
   "source": [
    "# Create an iterative grid search to tune the parameters\n",
    "import joblib\n",
    "from sklearn.model_selection import GridSearchCV"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 14,
   "id": "deafc454",
   "metadata": {},
   "outputs": [],
   "source": [
    "# Create a function to show the results of the classifier under different parameter values\n",
    "def print_results(results):\n",
    "    print('Best Parameters: {}\\n'.format(results.best_params_))\n",
    "    \n",
    "    means = results.cv_results_['mean_test_score']\n",
    "    stds = results.cv_results_['std_test_score']\n",
    "    for mean, std, params in zip(means, stds, results.cv_results_['params']):\n",
    "        print('{} (+/-{}) for {}'.format(round(mean, 3), round(std * 2, 3), params))"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 16,
   "id": "30e640b6",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Best Parameters: {'n_neighbors': 11}\n",
      "\n",
      "0.708 (+/-0.027) for {'n_neighbors': 3}\n",
      "0.718 (+/-0.027) for {'n_neighbors': 5}\n",
      "0.728 (+/-0.056) for {'n_neighbors': 7}\n",
      "0.736 (+/-0.047) for {'n_neighbors': 9}\n",
      "0.743 (+/-0.069) for {'n_neighbors': 11}\n"
     ]
    }
   ],
   "source": [
    "# Create a model using the KNN algorithm\n",
    "knn = neighbors.KNeighborsClassifier()\n",
    "# Set the parameters to be tuned\n",
    "parameters = {\n",
    "    'n_neighbors' : [3, 5, 7, 9, 11]\n",
    "}\n",
    "# instantiate the grid search\n",
    "cv = GridSearchCV(knn, parameters, cv=5)\n",
    "# fit the training data to the model\n",
    "cv.fit(X_train, y_train.ravel())\n",
    "# display the model evaluation with the different paramter values (K value)\n",
    "print_results(cv)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 17,
   "id": "9ef91a8e",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "{'algorithm': 'auto',\n",
       " 'leaf_size': 30,\n",
       " 'metric': 'minkowski',\n",
       " 'metric_params': None,\n",
       " 'n_jobs': None,\n",
       " 'n_neighbors': 11,\n",
       " 'p': 2,\n",
       " 'weights': 'uniform'}"
      ]
     },
     "execution_count": 17,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "# show the best paramters for classification (not a necesary step unless you are saving best parameter models to compare)\n",
    "cv.best_estimator_.get_params()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "5a903f22",
   "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.9.12"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 5
}
