Red neuronal con sklearn

En esta entrada vamos a implementar una red neuronal con la biblioteca de Python SciKit Learn. Las redes neuronales se han convertido en un clasificador estadístico extremadamente popular debido a su versatilidad y robustez para predecir datos ruidosos, esto lo haremos con la popular biblioteca para aprendizaje de máquina, SciKit Learn.

En la década de 1940 por McCulloch y Pitts desarrollaron un perceptrón para poder clasificar patrones, desde entonces y pasando por un largo impasse en los 60s y 70s, las redes neuronales han superado una gran cantidad de retos técnicos, convirtiéndose en uno de los clasificadores preferidos por empresas como Facebook, Google y muchísimas otras quienes ocupan lo que comúnmente denominamos DeepLearning.

En este ejemplo usaremos una red neuronal multicapa para clasificar las diferentes variedades descritas en el conjunto de datos de la flor Iris, que también viene con sklearn.

Primero cargamos nuestros datos.

#!-*-coding:utf8-*-
import sys
from sklearn.model_selection import train_test_split
from sklearn.datasets import load_iris
from sklearn.neural_network import MLPClassifier
from sklearn.grid_search import GridSearchCV
from sklearn.metrics import classification_report
from numpy import array

iris = load_iris()
iris_d = iris['data']
targets = []
for v in iris['target']:
 z = [0,0,0]
 z[v] = 1
 targets.append(z)
iris_t = array(targets)
Xtr, Xts, Ytr, Yts = train_test_split( iris_d, iris_t )

La mayor complicación técnica con una red neuronal es ajustar los pesos entre neuronas, para hacer esto usualmente se ocupa descenso del gradiente (aunque se pueden utilizar otros métodos de optimización como los algoritmos genéticos). Para buscar los mejores parámetros para este ejemplo tenemos que hacer lo siguiente:

if(sys.argv[1]=='busca'):
## Ajuste de parametros
 params = {"alpha" : [0.1, 0.01, 0.001], "max_iter" : [50, 100, 200],\
 "batch_size" : [5, 10, 20], "activation" : ['relu','tanh'],\
 "hidden_layer_sizes": [10, 20, 50, 100]}
 clf = MLPClassifier()
 gs = GridSearchCV( clf, params, n_jobs=2, verbose=1, scoring='precision_macro' )
 gs.fit(Xtr,Ytr)
 print(gs.best_params_)

Finalmente hacemos la clasificación

elif(sys.argv[1]=='entrena'):
# El resultado de esto son los siguientes parámetros
 params = {'alpha': 0.01, 'activation': 'relu', 'max_iter': 200, 'batch_size': 10,\
 'hidden_layer_sizes': 50}
 clf = MLPClassifier()
 clf.set_params(**params)
 clf.fit(Xtr, Ytr)
 for v, p in zip(Xts, Yts):
 print "{0} vs {1}".format( clf.predict_proba(v.reshape(1,-1)), p )
 print("Reporte")
 print(classification_report(Yts, clf.predict(Xts)))

Para evaluar la eficiencia del clasificador podemos usar la tabla de confusión, con sklearn la salida de esta clasificación es la siguiente:

[[ 0.00234185 0.89763272 0.03804086]] vs [0 1 0]
[[ 9.99308220e-01 8.41076111e-03 4.58573504e-07]] vs [1 0 0]
[[ 3.72051018e-04 8.41891613e-01 5.55910875e-02]] vs [0 1 0]
[[ 4.81020589e-05 2.85644639e-01 7.05813423e-01]] vs [0 0 1]
Reporte  
           precision recall f1-score support

        0       1.00   1.00     1.00      13
        1       1.00   1.00     1.00      13
        2       1.00   1.00     1.00      12

avg / total     1.00   1.00     1.00      38