Customer Classification using K-Nearest Neighbors
We will build a classifier to predict the class of new or unknown customers for a telecommunications provider. We will use a specific type of classification called K-Nearest Neighbors.
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.
The example focuses on using demographic data, such as region, age, and marital, to predict usage patterns.
The target field, called custcat, has four possible values that correspond to the four customer groups, as follows:
- 1- Basic Service
- 2- E-Service
- 3- Plus Service
- 4- Total Service
In this blog post, we will build a classifier to predict the class of unknown cases. We will use a specific type of classification called K-Nearest Neighbors.
K-Nearest Neighbors is an algorithm for supervised learning, where the data is trained with data points corresponding to their classification. Once a point is predicted, it takes into account the 'K' nearest points to it to determine its classification.
import itertools
import numpy as np
import matplotlib.pyplot as plt
from matplotlib.ticker import NullFormatter
import pandas as pd
from sklearn import preprocessing
%matplotlib inline
df = pd.read_csv('teleCust1000t.csv')
df.head()
df.shape
How many customers of each class are present in the dataset?
df['custcat'].value_counts()
There are
- 281 customers in the 'Plus Service' category
- 266 in the 'Basic Service' category
- 236 in the 'Total Service' category
- 217 in the 'E-Service' category.
Explore the data using histograms.
viz = df[['income', 'age', 'employ', 'reside']]
viz.hist()
plt.show()
Define the feature set, X.
df.columns
To use the scikit-learn library, convert the Pandas dataframe to a Numpy array.
X = df[['region', 'tenure', 'age', 'marital', 'address', 'income', 'ed',
'employ', 'retire', 'gender', 'reside']].values
X[0:5]
y = df['custcat'].values
y[0:5]
X = preprocessing.StandardScaler().fit(X).transform(X.astype(float))
X[0:5]
from sklearn.model_selection import train_test_split
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.2, random_state=4)
print('Train set: ', X_train.shape, y_train.shape)
print('Test set: ', X_test.shape, y_test.shape)
from sklearn.neighbors import KNeighborsClassifier
k = 4
neigh = KNeighborsClassifier(n_neighbors=k).fit(X_train, y_train)
neigh
yhat = neigh.predict(X_test)
yhat[0:5]
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.
from sklearn import metrics
print('Train set accuracy: ', metrics.accuracy_score(y_train, neigh.predict(X_train)))
print('Test set accuracy: ', metrics.accuracy_score(y_test, yhat))
Ks = 10
mean_acc = np.zeros((Ks-1))
std_acc = np.zeros((Ks-1))
ConfusionMx = [];
for n in range(1, Ks):
# train model and predict
neigh = KNeighborsClassifier(n_neighbors = n).fit(X_train, y_train)
yhat = neigh.predict(X_test)
mean_acc[n-1] = metrics.accuracy_score(y_test, yhat)
std_acc[n-1] = np.std(yhat==y_test) / np.sqrt(yhat.shape[0])
mean_acc
Plot model accuracy for different number of Neighbors
plt.plot(range(1,Ks), mean_acc, 'g')
plt.fill_between(range(1,Ks), mean_acc - 1*std_acc,mean_acc + 1*std_acc, alpha=0.1)
plt.legend(('Accuracy ', '+/- 3xstd'))
plt.ylabel('Accuracy')
plt.xlabel('Number of Neighbors (K)')
plt.tight_layout()
plt.show()
print('The best accuracy was with', mean_acc.max(), 'with k=', mean_acc.argmax()+1)
Evaluate the above code with k=16.
k = 9
neigh = KNeighborsClassifier(n_neighbors=k).fit(X_train, y_train)
neigh
yhat = neigh.predict(X_test)
yhat[0:5]
from sklearn import metrics
print('Train set accuracy: ', metrics.accuracy_score(y_train, neigh.predict(X_train)))
print('Test set accuracy: ', metrics.accuracy_score(y_test, yhat))