Importación de los paquetes básicos
[sourcecode language=»python» wraplines=»false» collapse=»false»]
import itertools
import numpy as np
import matplotlib.pyplot as plt
from matplotlib.ticker import NullFormatter
import pandas as pd
import numpy as np
import matplotlib.ticker as ticker
from sklearn import preprocessing
%matplotlib inline
[/sourcecode]
Importación de los datos
Imagina un proveedor de telecomunicaciones que ha segmentado la base de sus clientes por servicio, categorizando a los clientes en cuatro grupos. Si los datos demográficos se pueden usar para predecir la pertenencia de grupo del envío, la compañía podría personalizar las ofertas para los prospectos. Es un problema de clasificación. Este ejemplo hace foco en datos demográficos, sean region, edad, estado civil, para predecir patrones de uso. El campo objetivo (target), llamado custcat, tiene cuatro valores posibles que corresponden a los cuatro grupos de clientes: 1- Servicio Básico 2- E-Servicio 3- Servicio Plus 4- Servicio Total
Nuestro objetivo es construir un clasificador para predecir la clase de casos desconocidos. Utilizaremos un tipo específico de clasificación llamado K vecino más cercano.
[sourcecode language=»python» wraplines=»false» collapse=»false» firstline=»10″]
!wget -O teleCust1000t.csv https://s3-api.us-geo.objectstorage.softlayer.net/cf-courses-data/CognitiveClass/ML0101ENv3/labs/teleCust1000t.csv
df = pd.read_csv(‘teleCust1000t.csv’)
df.head()
[/sourcecode]
region | tenure | age | marital | address | income | ed | employ | retire | gender | reside | custcat | |
---|---|---|---|---|---|---|---|---|---|---|---|---|
0 | 2 | 13 | 44 | 1 | 9 | 64.0 | 4 | 5 | 0.0 | 0 | 2 | 1 |
1 | 3 | 11 | 33 | 1 | 7 | 136.0 | 5 | 5 | 0.0 | 0 | 6 | 4 |
2 | 3 | 68 | 52 | 1 | 24 | 116.0 | 1 | 29 | 0.0 | 1 | 2 | 3 |
3 | 2 | 33 | 33 | 0 | 12 | 33.0 | 2 | 0 | 0.0 | 1 | 1 | 1 |
4 | 2 | 23 | 30 | 1 | 9 | 30.0 | 1 | 2 | 0.0 | 0 | 4 | 3 |
Veamos cuántos de cada clase están en nuestro set de datos
[sourcecode language=»python» wraplines=»false» collapse=»false» firstline=»13″]
df[‘custcat’].value_counts()
[/sourcecode]
3 281 1 266 4 236 2 217 Name: custcat, dtype: int64
Puedes explorar fácilmente tus datos utilizando técnicas de visualización:
[sourcecode language=»python» wraplines=»false» collapse=»false» firstline=»14″]
df.hist(column=’income’, bins=50)
[/sourcecode]
Definamos feature sets, X:
[sourcecode language=»python» wraplines=»false» collapse=»false» firstline=»15″]
df.columns
[/sourcecode]
Index(['region', 'tenure', 'age', 'marital', 'address', 'income', 'ed', 'employ', 'retire', 'gender', 'reside', 'custcat'], dtype='object')
Para utilizar la librería scikit-learn, tenemos que convertir el data frame de Panda en un Numpy array:
[sourcecode language=»python» wraplines=»false» collapse=»false» firstline=»16″]
X = df[[‘region’, ‘tenure’,’age’, ‘marital’, ‘address’, ‘income’, ‘ed’, ‘employ’,’retire’, ‘gender’, ‘reside’]] .values #.astype(float)
X[0:5]
[/sourcecode]
array([[ 2., 13., 44., 1., 9., 64., 4., 5., 0., 0., 2.], [ 3., 11., 33., 1., 7., 136., 5., 5., 0., 0., 6.], [ 3., 68., 52., 1., 24., 116., 1., 29., 0., 1., 2.], [ 2., 33., 33., 0., 12., 33., 2., 0., 0., 1., 1.], [ 2., 23., 30., 1., 9., 30., 1., 2., 0., 0., 4.]])
¿Cuáles son nuestras etiquetas?
[sourcecode language=»python» wraplines=»false» collapse=»false» firstline=»18″]
y = df[‘custcat’].values
y[0:5]
[/sourcecode]
array([1, 4, 3, 1, 3])
Normalizar los Datos
La estandarización de datos haciendo que la media sea 0 y la varianza uno es buena práctica, especialmente para algoritmos tales como KNN el cual se basa en distancia de casos:
[sourcecode language=»python» wraplines=»false» collapse=»false» firstline=»20″]
X = preprocessing.StandardScaler().fit(X).transform(X.astype(float))
X[0:5]
[/sourcecode]
array([[-0.02696767, -1.055125 , 0.18450456, 1.0100505 , -0.25303431, -0.12650641, 1.0877526 , -0.5941226 , -0.22207644, -1.03459817, -0.23065004], [ 1.19883553, -1.14880563, -0.69181243, 1.0100505 , -0.4514148 , 0.54644972, 1.9062271 , -0.5941226 , -0.22207644, -1.03459817, 2.55666158], [ 1.19883553, 1.52109247, 0.82182601, 1.0100505 , 1.23481934, 0.35951747, -1.36767088, 1.78752803, -0.22207644, 0.96655883, -0.23065004], [-0.02696767, -0.11831864, -0.69181243, -0.9900495 , 0.04453642, -0.41625141, -0.54919639, -1.09029981, -0.22207644, 0.96655883, -0.92747794], [-0.02696767, -0.58672182, -0.93080797, 1.0100505 , -0.25303431, -0.44429125, -1.36767088, -0.89182893, -0.22207644, -1.03459817, 1.16300577]])
Dividimos la muestra en los conjuntos de datos para el entrenamiento y para la prueba de exactitud
[sourcecode language=»python» wraplines=»false» collapse=»false» firstline=»22″]
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 (‘Set de Entrenamiento:’, X_train.shape, y_train.shape)
print (‘Set de Prueba:’, X_test.shape, y_test.shape)
[/sourcecode]
Set de Entrenamiento: (800, 11) (800,) Set de Prueba: (200, 11) (200,)
Clasificación
importar librería del Clasificador que implementa k-vecinos más cercanos.
[sourcecode language=»python» wraplines=»false» collapse=»false» firstline=»26″]
from sklearn.neighbors import KNeighborsClassifier
[/sourcecode]
Para el entrenamiento vamos a comenzar con el algoritmo con k=4 por ahora:
[sourcecode language=»python» wraplines=»false» collapse=»false» firstline=»27″]
k = 4
#Entrenar el Modelo y Predecir
neigh = KNeighborsClassifier(n_neighbors = k).fit(X_train,y_train)
neigh
[/sourcecode]
KNeighborsClassifier(algorithm='auto', leaf_size=30, metric='minkowski', metric_params=None, n_jobs=None, n_neighbors=4, p=2, weights='uniform')
Usamos el modelo para predecir el set de prueba:
[sourcecode language=»python» wraplines=»false» collapse=»false» firstline=»31″]
yhat = neigh.predict(X_test)
yhat[0:5]
[/sourcecode]
array([1, 1, 3, 2, 4])
Para evaluar la certeza usamos la función classification accuracy score que computa la certeza del subconjunto. Esta función es igual a la función jaccard_similarity_score. Básicamente, calcula cómo se relacionan las etiquetas actuales con las etiquetas predichas dentro del set de pruebas.
[sourcecode language=»python» wraplines=»false» collapse=»false» firstline=»33″]
from sklearn import metrics
print("Entrenar el set de Certeza: ", metrics.accuracy_score(y_train, neigh.predict(X_train)))
print("Probar el set de Certeza: ", metrics.accuracy_score(y_test, yhat))
[/sourcecode]
Entrenar el set de Certeza: 0.5475 Probar el set de Certeza: 0.32
Para un K=6 tenemos los siguientes resultados
[sourcecode language=»python» wraplines=»false» collapse=»false» firstline=»36″]
k = 6
neigh6 = KNeighborsClassifier(n_neighbors = k).fit(X_train,y_train)
yhat6 = neigh6.predict(X_test)
print("Certeza del Set de Entrenamiento: ", metrics.accuracy_score(y_train, neigh6.predict(X_train)))
print("Certeza del Set de Prueba: ", metrics.accuracy_score(y_test, yhat6))
[/sourcecode]
Certeza del Set de Entrenamiento: 0.51625 Certeza del Set de Prueba: 0.31
Cálculo del mejor k
Elegimos k =1, lo utilizamos como parte del entrenamiento para modelar, y calculamos la certeza de la predicción utilizando todas las muestras del set de pruebas. Repetir este proceso, aumentando el k, y viendo luego, cual es el mejor k para el modelo.
[sourcecode language=»python» wraplines=»false» collapse=»false» firstline=»41″]
Ks = 10
mean_acc = np.zeros((Ks-1))
std_acc = np.zeros((Ks-1))
ConfustionMx = [];
for n in range(1,Ks):
#Entrenar el Modelo y Predecir
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
[/sourcecode]
array([0.3 , 0.29 , 0.315, 0.32 , 0.315, 0.31 , 0.335, 0.325, 0.34 ])
Dibujo de la certeza del modelo para diferentes números de vecinos
[sourcecode language=»python» wraplines=»false» collapse=»false» firstline=»52″]
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.10)
plt.legend((‘Certeza ‘, ‘+/- 3xstd’))
plt.ylabel(‘Certeza ‘)
plt.xlabel(‘Número de Vecinos (K)’)
plt.tight_layout()
plt.show()
[/sourcecode]
[sourcecode language=»python» wraplines=»false» collapse=»false» firstline=»59″]
print( "La mejor aproximación de certeza fue con ", mean_acc.max(), "con k=", mean_acc.argmax()+1)
[/sourcecode]
La mejor aproximación de certeza fue con 0.34 con k= 9