Clasificación en Python con Scikit-Learn y Pandas

La clasificación es un gran dominio en el campo de la estadística y el aprendizaje automático. En general, la clasificación se puede dividir en dos áreas: Clasificación binaria...

Introducción

La clasificación es un gran dominio en el campo de la estadística y el aprendizaje automático. En general, la clasificación se puede dividir en dos áreas:

  1. Clasificación binaria, donde deseamos agrupar un resultado en uno de dos grupos.

  2. Clasificación multiclase, donde deseamos agrupar un resultado en uno de múltiples (más de dos) grupos.

En esta publicación, el enfoque principal estará en el uso de una variedad de algoritmos de clasificación en estos dos dominios, se pondrá menos énfasis en la teoría detrás de ellos.

Podemos usar bibliotecas en Python como scikit-aprender para modelos de aprendizaje automático y pandas para importar datos como tramas de datos.

Estos se pueden instalar e importar fácilmente a Python con pip:

1
2
$ python3 -m pip install sklearn
$ python3 -m pip install pandas
1
2
import sklearn as sk
import pandas as pd

Clasificación binaria

Para la clasificación binaria, estamos interesados ​​en clasificar los datos en uno de dos grupos binarios; estos generalmente se representan como 0 y 1 en nuestros datos.

Analizaremos los datos relacionados con la enfermedad coronaria (CHD) en Sudáfrica. El objetivo es utilizar diferentes variables como uso de tabaco, antecedentes familiares, niveles de colesterol ldl, uso de alcohol, obesidad y más.

Una descripción completa de este conjunto de datos está disponible en la sección "Data" del sitio web Elementos del Aprendizaje Estadístico.

El siguiente código lee los datos en un marco de datos de Pandas y luego separa el marco de datos en un vector y de la respuesta y una matriz X de variables explicativas:

1
2
3
4
5
6
7
8
9
import pandas as pd
import os

os.chdir('/Users/stevenhurwitt/Documents/Blog/Classification')
heart = pd.read_csv('SAHeart.csv', sep=',', header=0)
heart.head()

y = heart.iloc[:,9]
X = heart.iloc[:,:9]

Al ejecutar este código, solo asegúrese de cambiar la ruta del sistema de archivos en la línea 4 para que se adapte a su configuración.

  sbp   tobacco   ldl    adiposity   famhist   typea   obesity   alcohol   age   chd

0 160 12,00 5,73 23,11 1 49 25,30 97,20 52 1 1 144 0,01 4,41 28,61 0 55 28,87 2,06 63 1 2 118 0,08 3,48 32,28 1 52 29,14 3,81 46 0 3 170 7,50 6,41 38,03 1 51 31,99 24,26 58 1 4 134 13,60 3,50 27,78 1 60 25,99 57,34 49 1

Regresión logística

[Regresión logística] (https://en.wikipedia.org/wiki/Logistic_regression) es un tipo de Modelo lineal generalizado (GLM) que utiliza un modelo logístico función para modelar una variable binaria basada en cualquier tipo de variables independientes.

Para ajustar una regresión logística binaria con sklearn, usamos el módulo Regresión logística con multi_class establecido en "ovr" y ajuste X e y.

Luego podemos usar el método predict para predecir las probabilidades de nuevos datos, así como el método score para obtener la precisión media de la predicción:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
import sklearn as sk
from sklearn.linear_model import LogisticRegression
import pandas as pd
import os

os.chdir('/Users/stevenhurwitt/Documents/Blog/Classification')
heart = pd.read_csv('SAHeart.csv', sep=',',header=0)
heart.head()

y = heart.iloc[:,9]
X = heart.iloc[:,:9]

LR = LogisticRegression(random_state=0, solver='lbfgs', multi_class='ovr').fit(X, y)
LR.predict(X.iloc[460:,:])
round(LR.score(X,y), 4)
1
array([1, 1])

Máquinas de vectores de soporte

Máquinas de vectores de soporte (SVM) son un tipo de algoritmo de clasificación que son más flexibles - pueden hacer clasificación lineal, pero pueden usar otras funciones base no lineales. El siguiente ejemplo usa un clasificador lineal para ajustar un hiperplano que separa los datos en dos clases:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
import sklearn as sk
from sklearn import svm
import pandas as pd
import os

os.chdir('/Users/stevenhurwitt/Documents/Blog/Classification')
heart = pd.read_csv('SAHeart.csv', sep=',',header=0)

y = heart.iloc[:,9]
X = heart.iloc[:,:9]

SVM = svm.LinearSVC()
SVM.fit(X, y)
SVM.predict(X.iloc[460:,:])
round(SVM.score(X,y), 4)
1
array([0, 1])

Bosques aleatorios

Los bosques aleatorios son un método de aprendizaje conjunto que se adapta a varios árboles de decisión en subconjuntos de los datos y promediar los resultados. Podemos volver a ajustarlos usando sklearn y usarlos para predecir resultados, así como obtener una precisión de predicción media:

1
2
3
4
5
6
7
import sklearn as sk
from sklearn.ensemble import RandomForestClassifier

RF = RandomForestClassifier(n_estimators=100, max_depth=2, random_state=0)
RF.fit(X, y)
RF.predict(X.iloc[460:,:])
round(RF.score(X,y), 4)
1
0.7338

Redes neuronales

Redes neuronales son un algoritmo de aprendizaje automático que consiste en colocar muchas capas ocultas que se utilizan para representar neuronas que están conectadas con funciones de activación sinápticas. Básicamente, utilizan un modelo muy simplificado del cerebro para modelar y predecir datos.

Usamos sklearn para mantener la coherencia en esta publicación, sin embargo, las bibliotecas como [tensorflow] (https://www.tensorflow.org/) y [Keras] (https://keras.io/) son más adecuadas para ajustar y personalización de redes neuronales, de las cuales hay algunas variedades utilizadas para diferentes propósitos:

1
2
3
4
5
6
7
import sklearn as sk
from sklearn.neural_network import MLPClassifier

NN = MLPClassifier(solver='lbfgs', alpha=1e-5, hidden_layer_sizes=(5, 2), random_state=1)
NN.fit(X, y)
NN.predict(X.iloc[460:,:])
round(NN.score(X,y), 4)
1
0.6537

Clasificación multiclase

Si bien la clasificación binaria por sí sola es increíblemente útil, hay momentos en los que nos gustaría modelar y predecir datos que tienen más de dos clases. Muchos de los mismos algoritmos se pueden utilizar con ligeras modificaciones.

Además, es común dividir los datos en conjuntos de entrenamiento y prueba. Esto significa que usamos una determinada parte de los datos para ajustar el modelo (el conjunto de entrenamiento) y guardamos la parte restante para evaluar la precisión predictiva del modelo ajustado (el conjunto de prueba).

No hay una regla oficial a seguir al decidir sobre una proporción dividida, aunque en la mayoría de los casos querrás que se dedique alrededor del 70 % para el conjunto de entrenamiento y alrededor del 30 % para el conjunto de prueba.

Para explorar tanto las clasificaciones multiclase como los datos de entrenamiento/prueba, veremos otro [conjunto de datos del sitio web Elements of Statistical Learning](https://web.stanford.edu/~hastie/ElemStatLearn/data .html). Estos son los datos utilizados para determinar cuál de los once sonidos de las vocales se pronunció:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
import pandas as pd

vowel_train = pd.read_csv('vowel.train.csv', sep=',', header=0)
vowel_test = pd.read_csv('vowel.test.csv', sep=',', header=0)

vowel_train.head()

y_tr = vowel_train.iloc[:,0]
X_tr = vowel_train.iloc[:,1:]

y_test = vowel_test.iloc[:,0]
X_test = vowel_test.iloc[:,1:]
  y   x.1      x.2     x.3      x.4     x.5      x.6     x.7      x.8      x.9      x.10

0 1 -3.639 0.418 -0.670 1.779 -0.168 1.627 -0.388 0.529 -0.874 -0.814 1 2 -3.327 0.496 -0.694 1.365 -0.265 1.933 -0.363 0.510 -0.621 -0.488 2 3 -2.120 0.894 -1.576 0.147 -0.707 1.559 -0.579 0.676 -0.809 -0.049 3 4 -2.287 1.809 -1.498 1.012 -1.053 1.060 -0.567 0.235 -0.091 -0.795 4 5 -2.598 1.938 -0.846 1.062 -1.633 0.764 0.394 -0.150 0.277 -0.396

Ahora ajustaremos modelos y los probaremos como se hace normalmente en estadística/aprendizaje automático: entrenándolos en el conjunto de entrenamiento y evaluándolos en el conjunto de prueba.

Además, dado que se trata de una clasificación multiclase, será necesario cambiar algunos argumentos dentro de cada algoritmo:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
import pandas as pd
import sklearn as sk
from sklearn.linear_model import LogisticRegression
from sklearn import svm
from sklearn.ensemble import RandomForestClassifier
from sklearn.neural_network import MLPClassifier

vowel_train = pd.read_csv('vowel.train.csv', sep=',',header=0)
vowel_test = pd.read_csv('vowel.test.csv', sep=',',header=0)

y_tr = vowel_train.iloc[:,0]
X_tr = vowel_train.iloc[:,1:]

y_test = vowel_test.iloc[:,0]
X_test = vowel_test.iloc[:,1:]

LR = LogisticRegression(random_state=0, solver='lbfgs', multi_class='multinomial').fit(X_tr, y_tr)
LR.predict(X_test)
round(LR.score(X_test,y_test), 4)

SVM = svm.SVC(decision_function_shape="ovo").fit(X_tr, y_tr)
SVM.predict(X_test)
round(SVM.score(X_test, y_test), 4)

RF = RandomForestClassifier(n_estimators=1000, max_depth=10, random_state=0).fit(X_tr, y_tr)
RF.predict(X_test)
round(RF.score(X_test, y_test), 4)

NN = MLPClassifier(solver='lbfgs', alpha=1e-5, hidden_layer_sizes=(150, 10), random_state=1).fit(X_tr, y_tr)
NN.predict(X_test)
round(NN.score(X_test, y_test), 4)
1
0.5455

Aunque las implementaciones de estos modelos fueron bastante ingenuas (en la práctica, hay una variedad de parámetros que pueden y deben variar para cada modelo), aún podemos comparar la precisión predictiva entre los modelos. Esto nos dirá cuál es el más preciso para este conjunto de datos de prueba y entrenamiento específico:


Precisión predictiva del modelo Regresión Logística 46,1% Máquina de vectores de soporte 64.07% Bosque aleatorio 57.58% Red Neuronal 54,55%


Esto nos muestra que para los datos de vocales, una SVM que usa la función de base radial predeterminada fue la más precisa.

Conclusión

Para resumir esta publicación, comenzamos explorando la forma más simple de clasificación: binaria. Esto nos ayudó a modelar datos donde nuestra respuesta podría tomar uno de dos estados.

Luego avanzamos más en la clasificación de clases múltiples, cuando la variable de respuesta puede tomar cualquier número de estados.

También vimos cómo ajustar y evaluar modelos con conjuntos de entrenamiento y prueba. Además, podríamos explorar formas adicionales de refinar el ajuste del modelo entre varios algoritmos.