{ "cells": [ { "cell_type": "markdown", "metadata": { "button": false, "new_sheet": false, "run_control": { "read_only": false } }, "source": [ "# K-Nearest Neighbors\n", "---" ] }, { "cell_type": "markdown", "metadata": { "button": false, "new_sheet": false, "run_control": { "read_only": false } }, "source": [ "Lets load required libraries" ] }, { "cell_type": "code", "execution_count": 1, "metadata": { "button": false, "new_sheet": false, "run_control": { "read_only": false } }, "outputs": [], "source": [ "# primary data structure libraries\n", "import pandas as pd\n", "import numpy as np\n", "\n", "# primary plotting library\n", "import matplotlib as mpl\n", "import matplotlib.pyplot as plt\n", "from matplotlib.ticker import NullFormatter\n", "import matplotlib.ticker as ticker\n", "\n", "# primary machine learning library\n", "from sklearn import preprocessing\n", "from sklearn.model_selection import train_test_split\n", "from sklearn.neighbors import KNeighborsClassifier\n", "from sklearn import metrics\n", "\n", "# optional: for ggplot-like style of plots\n", "mpl.style.use(['ggplot']) \n", "%matplotlib inline" ] }, { "cell_type": "markdown", "metadata": { "button": false, "new_sheet": false, "run_control": { "read_only": false } }, "source": [ "
\n", "

About the dataset

\n", "
" ] }, { "cell_type": "markdown", "metadata": { "button": false, "new_sheet": false, "run_control": { "read_only": false } }, "source": [ "Imagine a telecommunications provider has segmented its customer base by service usage patterns, categorizing the customers into four groups. If demographic data can be used to predict group membership, the company can customize offers for individual prospective customers. It is a classification problem. That is, given the dataset, with predefined labels, we need to build a model to be used to predict class of a new or unknown case. \n", "\n", "The example focuses on using demographic data, such as region, age, and marital, to predict usage patterns. \n", "\n", "The target field, called __custcat__, has four possible values that correspond to the four customer groups, as follows:\n", " 1- Basic Service\n", " 2- E-Service\n", " 3- Plus Service\n", " 4- Total Service\n", "\n", "Our objective is to build a classifier, to predict the class of unknown cases. We will use a specific type of classification called K nearest neighbour.\n" ] }, { "cell_type": "markdown", "metadata": { "button": false, "new_sheet": false, "run_control": { "read_only": false } }, "source": [ "### Load Data From CSV File " ] }, { "cell_type": "code", "execution_count": 2, "metadata": { "button": false, "new_sheet": false, "run_control": { "read_only": false } }, "outputs": [ { "data": { "text/html": [ "
\n", "\n", "\n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", "
regiontenureagemaritaladdressincomeedemployretiregenderresidecustcat
0213441964.0450.0021
13113317136.0550.0064
236852124116.01290.0123
32333301233.0200.0111
4223301930.0120.0043
\n", "
" ], "text/plain": [ " region tenure age marital address income ed employ retire gender \\\n", "0 2 13 44 1 9 64.0 4 5 0.0 0 \n", "1 3 11 33 1 7 136.0 5 5 0.0 0 \n", "2 3 68 52 1 24 116.0 1 29 0.0 1 \n", "3 2 33 33 0 12 33.0 2 0 0.0 1 \n", "4 2 23 30 1 9 30.0 1 2 0.0 0 \n", "\n", " reside custcat \n", "0 2 1 \n", "1 6 4 \n", "2 2 3 \n", "3 1 1 \n", "4 4 3 " ] }, "execution_count": 2, "metadata": {}, "output_type": "execute_result" } ], "source": [ "df = pd.read_csv('teleCust1000t.csv')\n", "df.head()" ] }, { "cell_type": "markdown", "metadata": { "button": false, "new_sheet": false, "run_control": { "read_only": false } }, "source": [ "
\n", "

Data Visualization and Analysis

\n", "
\n" ] }, { "cell_type": "markdown", "metadata": { "button": false, "new_sheet": false, "run_control": { "read_only": false } }, "source": [ "#### Let’s see how many of each class is in our data set " ] }, { "cell_type": "code", "execution_count": 3, "metadata": { "button": false, "new_sheet": false, "run_control": { "read_only": false } }, "outputs": [ { "data": { "text/plain": [ "3 281\n", "1 266\n", "4 236\n", "2 217\n", "Name: custcat, dtype: int64" ] }, "execution_count": 3, "metadata": {}, "output_type": "execute_result" } ], "source": [ "df['custcat'].value_counts()" ] }, { "cell_type": "markdown", "metadata": { "button": false, "new_sheet": false, "run_control": { "read_only": false } }, "source": [ "281 Plus Service, 266 Basic-service, 236 Total Service, and 217 E-Service customers" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "You can easily explore your data using visualization techniques:" ] }, { "cell_type": "code", "execution_count": 4, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "array([[]], dtype=object)" ] }, "execution_count": 4, "metadata": {}, "output_type": "execute_result" }, { "data": { "image/png": "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\n", "text/plain": [ "
" ] }, "metadata": { "needs_background": "light" }, "output_type": "display_data" } ], "source": [ "df.hist(column='income', bins=50)" ] }, { "cell_type": "markdown", "metadata": { "button": false, "new_sheet": false, "run_control": { "read_only": false } }, "source": [ "### Feature set" ] }, { "cell_type": "markdown", "metadata": { "button": false, "new_sheet": false, "run_control": { "read_only": false } }, "source": [ "Lets define feature sets, X:" ] }, { "cell_type": "code", "execution_count": 5, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "Index(['region', 'tenure', 'age', 'marital', 'address', 'income', 'ed',\n", " 'employ', 'retire', 'gender', 'reside', 'custcat'],\n", " dtype='object')" ] }, "execution_count": 5, "metadata": {}, "output_type": "execute_result" } ], "source": [ "df.columns" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "To use scikit-learn library, we have to convert the Pandas data frame to a Numpy array:" ] }, { "cell_type": "code", "execution_count": 6, "metadata": { "button": false, "new_sheet": false, "run_control": { "read_only": false } }, "outputs": [ { "data": { "text/plain": [ "array([[ 2., 13., 44., 1., 9., 64., 4., 5., 0., 0., 2.],\n", " [ 3., 11., 33., 1., 7., 136., 5., 5., 0., 0., 6.],\n", " [ 3., 68., 52., 1., 24., 116., 1., 29., 0., 1., 2.],\n", " [ 2., 33., 33., 0., 12., 33., 2., 0., 0., 1., 1.],\n", " [ 2., 23., 30., 1., 9., 30., 1., 2., 0., 0., 4.]])" ] }, "execution_count": 6, "metadata": {}, "output_type": "execute_result" } ], "source": [ "X = df[['region', 'tenure','age', 'marital', 'address', 'income', 'ed', 'employ','retire', 'gender', 'reside']] .values #.astype(float)\n", "X[0:5]\n" ] }, { "cell_type": "markdown", "metadata": { "button": false, "new_sheet": false, "run_control": { "read_only": false } }, "source": [ "What are our labels?" ] }, { "cell_type": "code", "execution_count": 7, "metadata": { "button": false, "new_sheet": false, "run_control": { "read_only": false } }, "outputs": [ { "data": { "text/plain": [ "array([1, 4, 3, 1, 3], dtype=int64)" ] }, "execution_count": 7, "metadata": {}, "output_type": "execute_result" } ], "source": [ "y = df['custcat'].values\n", "y[0:5]" ] }, { "cell_type": "markdown", "metadata": { "button": false, "new_sheet": false, "run_control": { "read_only": false } }, "source": [ "## Normalize Data " ] }, { "cell_type": "markdown", "metadata": { "button": false, "new_sheet": false, "run_control": { "read_only": false } }, "source": [ "Data Standardization give data zero mean and unit variance, it is good practice, especially for algorithms such as KNN which is based on distance of cases:" ] }, { "cell_type": "code", "execution_count": 8, "metadata": { "button": false, "new_sheet": false, "run_control": { "read_only": false } }, "outputs": [ { "data": { "text/plain": [ "array([[-0.02696767, -1.055125 , 0.18450456, 1.0100505 , -0.25303431,\n", " -0.12650641, 1.0877526 , -0.5941226 , -0.22207644, -1.03459817,\n", " -0.23065004],\n", " [ 1.19883553, -1.14880563, -0.69181243, 1.0100505 , -0.4514148 ,\n", " 0.54644972, 1.9062271 , -0.5941226 , -0.22207644, -1.03459817,\n", " 2.55666158],\n", " [ 1.19883553, 1.52109247, 0.82182601, 1.0100505 , 1.23481934,\n", " 0.35951747, -1.36767088, 1.78752803, -0.22207644, 0.96655883,\n", " -0.23065004],\n", " [-0.02696767, -0.11831864, -0.69181243, -0.9900495 , 0.04453642,\n", " -0.41625141, -0.54919639, -1.09029981, -0.22207644, 0.96655883,\n", " -0.92747794],\n", " [-0.02696767, -0.58672182, -0.93080797, 1.0100505 , -0.25303431,\n", " -0.44429125, -1.36767088, -0.89182893, -0.22207644, -1.03459817,\n", " 1.16300577]])" ] }, "execution_count": 8, "metadata": {}, "output_type": "execute_result" } ], "source": [ "X = preprocessing.StandardScaler().fit(X).transform(X.astype(float))\n", "X[0:5]" ] }, { "cell_type": "markdown", "metadata": { "button": false, "new_sheet": false, "run_control": { "read_only": false } }, "source": [ "### Train Test Split \n", "Out of Sample Accuracy is the percentage of correct predictions that the model makes on data that that the model has NOT been trained on. Doing a train and test on the same dataset will most likely have low out-of-sample accuracy, due to the likelihood of being over-fit.\n", "\n", "It is important that our models have a high, out-of-sample accuracy, because the purpose of any model, of course, is to make correct predictions on unknown data. So how can we improve out-of-sample accuracy? One way is to use an evaluation approach called Train/Test Split.\n", "Train/Test Split involves splitting the dataset into training and testing sets respectively, which are mutually exclusive. After which, you train with the training set and test with the testing set. \n", "\n", "This will provide a more accurate evaluation on out-of-sample accuracy because the testing dataset is not part of the dataset that have been used to train the data. It is more realistic for real world problems.\n" ] }, { "cell_type": "code", "execution_count": 9, "metadata": { "button": false, "new_sheet": false, "run_control": { "read_only": false } }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "Train set: (800, 11) (800,)\n", "Test set: (200, 11) (200,)\n" ] } ], "source": [ "X_train, X_test, y_train, y_test = train_test_split( X, y, test_size=0.2, random_state=4)\n", "print ('Train set:', X_train.shape, y_train.shape)\n", "print ('Test set:', X_test.shape, y_test.shape)" ] }, { "cell_type": "markdown", "metadata": { "button": false, "new_sheet": false, "run_control": { "read_only": false } }, "source": [ "
\n", "

Classification

\n", "
" ] }, { "cell_type": "markdown", "metadata": { "button": false, "new_sheet": false, "run_control": { "read_only": false } }, "source": [ "### Training\n", "\n", "Lets start the algorithm with k=4 for now:" ] }, { "cell_type": "code", "execution_count": 10, "metadata": { "button": false, "new_sheet": false, "run_control": { "read_only": false } }, "outputs": [ { "data": { "text/plain": [ "KNeighborsClassifier(n_neighbors=4)" ] }, "execution_count": 10, "metadata": {}, "output_type": "execute_result" } ], "source": [ "k = 4\n", "#Train Model and Predict \n", "neigh = KNeighborsClassifier(n_neighbors = k).fit(X_train,y_train)\n", "neigh" ] }, { "cell_type": "markdown", "metadata": { "button": false, "new_sheet": false, "run_control": { "read_only": false } }, "source": [ "### Predicting\n", "we can use the model to predict the test set:" ] }, { "cell_type": "code", "execution_count": 11, "metadata": { "button": false, "new_sheet": false, "run_control": { "read_only": false } }, "outputs": [ { "data": { "text/plain": [ "array([1, 1, 3, 2, 4], dtype=int64)" ] }, "execution_count": 11, "metadata": {}, "output_type": "execute_result" } ], "source": [ "yhat = neigh.predict(X_test)\n", "yhat[0:5]" ] }, { "cell_type": "markdown", "metadata": { "button": false, "new_sheet": false, "run_control": { "read_only": false } }, "source": [ "### Accuracy evaluation\n", "In multilabel classification, __accuracy classification score__ is a function that computes subset accuracy. This function is equal to the jaccard_similarity_score function. Essentially, it calculates how closely the actual labels and predicted labels are matched in the test set." ] }, { "cell_type": "code", "execution_count": 12, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "Train set Accuracy: 0.5475\n", "Test set Accuracy: 0.32\n" ] } ], "source": [ "print(\"Train set Accuracy: \", metrics.accuracy_score(y_train, neigh.predict(X_train)))\n", "print(\"Test set Accuracy: \", metrics.accuracy_score(y_test, yhat))" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "We'll build the model again, but this time with k=6" ] }, { "cell_type": "code", "execution_count": 13, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "Train set Accuracy: 0.51625\n", "Test set Accuracy: 0.31\n" ] } ], "source": [ "k = 6\n", "neigh6 = KNeighborsClassifier(n_neighbors = k).fit(X_train,y_train)\n", "yhat6 = neigh6.predict(X_test)\n", "print(\"Train set Accuracy: \", metrics.accuracy_score(y_train, neigh6.predict(X_train)))\n", "print(\"Test set Accuracy: \", metrics.accuracy_score(y_test, yhat6))" ] }, { "cell_type": "markdown", "metadata": { "button": false, "new_sheet": false, "run_control": { "read_only": false } }, "source": [ "#### What about other K?\n", "K in KNN, is the number of nearest neighbors to examine. It is supposed to be specified by the User. So, how can we choose right value for K?\n", "The general solution is to reserve a part of your data for testing the accuracy of the model. Then chose k =1, use the training part for modeling, and calculate the accuracy of prediction using all samples in your test set. Repeat this process, increasing the k, and see which k is the best for your model.\n", "\n", "We can calculate the accuracy of KNN for different Ks." ] }, { "cell_type": "code", "execution_count": 14, "metadata": { "button": false, "new_sheet": false, "run_control": { "read_only": false } }, "outputs": [ { "data": { "text/plain": [ "array([0.3 , 0.29 , 0.315, 0.32 , 0.315, 0.31 , 0.335, 0.325, 0.34 ])" ] }, "execution_count": 14, "metadata": {}, "output_type": "execute_result" } ], "source": [ "Ks = 10\n", "mean_acc = np.zeros((Ks-1))\n", "std_acc = np.zeros((Ks-1))\n", "ConfustionMx = [];\n", "for n in range(1,Ks):\n", " #Train Model and Predict \n", " neigh = KNeighborsClassifier(n_neighbors = n).fit(X_train,y_train)\n", " yhat=neigh.predict(X_test)\n", " mean_acc[n-1] = metrics.accuracy_score(y_test, yhat)\n", " std_acc[n-1]=np.std(yhat==y_test)/np.sqrt(yhat.shape[0])\n", "mean_acc" ] }, { "cell_type": "markdown", "metadata": { "button": false, "new_sheet": false, "run_control": { "read_only": false } }, "source": [ "#### Plot model accuracy for Different number of Neighbors " ] }, { "cell_type": "code", "execution_count": 15, "metadata": { "button": false, "new_sheet": false, "run_control": { "read_only": false } }, "outputs": [ { "data": { "image/png": "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\n", "text/plain": [ "
" ] }, "metadata": { "needs_background": "light" }, "output_type": "display_data" } ], "source": [ "plt.plot(range(1,Ks),mean_acc,'g')\n", "plt.fill_between(range(1,Ks),mean_acc - 1 * std_acc,mean_acc + 1 * std_acc, alpha=0.10)\n", "plt.legend(('Accuracy ', '+/- 3xstd'))\n", "plt.ylabel('Accuracy ')\n", "plt.xlabel('Number of Nabors (K)')\n", "plt.tight_layout()\n", "plt.show()" ] }, { "cell_type": "code", "execution_count": 16, "metadata": { "button": false, "new_sheet": false, "run_control": { "read_only": false }, "scrolled": true }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "The best accuracy was of 0.34 with k = 9\n" ] } ], "source": [ "print( \"The best accuracy was of\", mean_acc.max(), \"with k =\", mean_acc.argmax()+1) " ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## Thanks for reading :)\n", "Created by [Saeed Aghabozorgi](https://www.linkedin.com/in/saeedaghabozorgi/) and modified by [Tarun Kamboj](https://www.linkedin.com/in/kambojtarun/)." ] } ], "metadata": { "kernelspec": { "display_name": "Python 3", "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.7.6" } }, "nbformat": 4, "nbformat_minor": 2 }