Google+ Seguidores

jueves, 21 de diciembre de 2017

Reconocimiento de dígitos escritos a mano - Machine Learning con Python

Introducción:

Llevo un tiempo estudiando el tema de "Machine Learning" o "Aprendizaje Automático". La verdad es que es un tema muy interesante, en algunos momentos, al llegar a temas más avanzados me costaba un poco, pero luego me reponía.

Hoy quisiera mostrarles un pequeño ejemplo del uso de la libreria Scikit-Learn, la cual nos proporciona una gran variedad de algoritmos de aprendizaje automático.

Si aun no cuentas con la librería Scikit-Learn, pueden descargarla ingresando al siguiente enlace: http://scikit-learn.org/stable/install.html.

Imagen relacionada

Reconocimiento de dígitos escritos a mano:

Una vez que tengamos instalado el modulo Scikit-Learn, podemos empezar con el ejercicio.

En el día de hoy, entrenaremos a un algoritmo para puede clasificar un dígito escrito a mano. 

Todo esto, lo haremos con Scikit-learn, un software de aprendizaje automático para el lenguaje de programación Python. Presenta varios algoritmos de clasificación, regresión y agrupación, incluyendo Máquinas de Vectores de Soporte (SVM), K-means, bosques aleatorios, entre otros.

En el día de hoy, trabajaremos con Máquinas de Soporte de Vectores (SVM), antes de realizar el ejemplo de hoy, es bueno un poco de teoría.

Máquinas de Soporte de Vectores (SVM):

En pocas palabras, son un conjunto de algoritmos de aprendizaje supervisado. 
Estos métodos están apropiadamente relacionados con problemas de clasificación y regresión. Dado un conjunto de ejemplos de entrenamiento podemos etiquetar las clases y entrenar una SVM para construir un modelo que prediga la clase de una nueva muestra.

Como en la mayoría de los métodos de clasificación supervisada, los datos de entrada son vistos como un vector p-dimensional(una lista ordenada de p-números).

El ejemplo de Hoy:

El objetivo de hoy sera entrenar un algoritmo capaz de determinar que digito es este:

../../_images/sphx_glr_plot_digits_last_image_001.png

Bien, hagamos el ejemplo de clasificación. Esto es simplemente una demostración de lo que podemos realizar con Scikit-Learn.

Bueno, lo primero que haremos sera importar las librerías necesarias.

from sklearn.datasets import load_digits

En este primera linea importo el set de datos "digits", con este set de datos entrenaremos a nuestro algoritmo.

from sklearn.model_selection import train_test_split

Es bueno separar los datos de entrenamiento y los datos de prueba, para ello usaremos a "train_test_split", el cual nos permitira separar nuestro datos en "train" y "test".

from sklearn.svm import SVC

Por ultimo importamos al algoritmo SVC de svm.

Perfecto, ya hemos importado todo lo que usaremos, es momento de darle uso.

Lo primero que haré, sera definir una variable la cual contendrá el set de datos "digits":
digits = load_digits()

Luego, separare los datos de entrenamiento y los datos de prueba:
x_train, x_test, y_train, y_test = train_test_split(digits.data, digits.target)

Como pueden observar, definimos 4 variables (x_train, x_test, y_train, y_test) a las cuales el método "train_test_split" le asigna datos automáticamente. 

Los datos que hemos separado, son los datos que se encuentran dentro de digits, en data se encuentran los conjunto de datos los cuales conforman a los dígitos. En target se encuentras las etiquetas que se le asigna a cada conjunto de datos, las etiquetas que contiene target van desde el cero (0) al nueve (9).

El procedimiento de separación de entrenamiento y prueba podríamos hacerlo manualmente, pero este método de Scikit-Learn nos facilita el trabajo.


Muy bien, ya tenemos los datos, lo único que falta es entrenar a nuestro algoritmo, en una variable denominada "clf" definiré a nuestro algoritmo:

clf = SVC(gamma=0.001, C=100)

Ahora en "clf" se encuentra la instancia del algoritmo SVC. A SVC le e asignado un par de parámetros. El primero es "gamma" el cual asigna el coeficiente del kernel, y el parámetro C el cual es el parámetro de penalización del termino de error. Estos parámetros tiene un papel muy importante, ya que muchos de ellos ayudan a que el algoritmo se sienta más seguro al momento de clasificar los datos.

Perfecto, llego el momento de entrenar a nuestro algoritmo, lo cual es más fácil que ir a entrenar al gimnasio.

clf.fit(x_train, y_train)
Out[22]:
SVC(C=100, cache_size=200, class_weight=None, coef0=0.0,
  decision_function_shape=None, degree=3, gamma=0.001, kernel='rbf',
  max_iter=-1, probability=False, random_state=None, shrinking=True,
  tol=0.001, verbose=False)

Con el método "fit", entrenamos a nuestro algoritmo. Al método le pasamos como argumento los datos de entrenamiento de x e y.

Listo, ahora es bueno saber que tan bien aprendió nuestro algoritmo, esto lo haremos utilizando el método "score" para obtener el porcentaje de que tan bien clasificador es nuestro algoritmo:

clf.score(x_test, y_test)
Out[23]:
0.98888888888888893

Perfecto, vemos que nuestro algoritmo aprendió muy bien, con un 98% .

Al método "score" le pasamos como argumento los datos de entrenamiento (test) de x e y.

Quisiera que pruebes algo tu mismo, elimina los parámetros "gamma" y "C" al algoritmo, cuando lo entrenes y veas el porcentaje, veras que puede llegar a aprender menos del 50%, aquí es donde saber manejar los parámetros es de mucha ayuda.

De igual manera, que el algoritmo aprenda un 99% o incluso más del 100%, no es muy bueno, a esto se le conoce como sobre ajuste, pero esto es una historia para otro día.

Muy bien, vemos que el algoritmo aprendió muy bien, es momento de pasarle el dato desconocido al cual el deberá clasificar:

#Predicción
clf.predict(digits.data[-1:])
Out[28]:
array([8])

Con el método predict, predecimos a que categoría ira el dato que le pasemos como argumento. El conjunto de datos que use, fue el que se encuentra en la posición -1 de la lista.

Y como resultado, tenemos la etiqueta con la cual se etiqueto al dato que quisimos predecir. El algoritmo determino que el dígito escrito a mano es el numero 8.

Pero ¿Donde demonios esta el numero?. El numero son unos puntos que se encuentran en un hiperplano. Los dígitos como tal no se encuentran en formato png o jpeg.

Para saber que a que dígito etiquetaremos, podemos ver una representación gráfica de los dígitos usando matplotlib:
import matplotlib.pyplot as plt

from sklearn.datasets import load_digits

digits = load_digits()

plt.figure(1, figsize=(3, 3))
plt.imshow(digits.images[-1], cmap=plt.cm.gray_r, interpolation='nearest')
plt.show()

Este bloque de código, muestra la gráfica de los datos. Este es el dígito que el algoritmo etiqueto como el numero 8. ¿Que dices, si te parece un 8?.
Pueden probar viendo los otros dígitos, cambiando el indice de digits.images (el primer argumento de imshow).


Bueno, este es un ejemplo muy sencillo, me quede con las ganas de explicarles más cada concepto, pero no puedo hacerlo en un solo articulo.

Puedes descargar el código completo del ejemplo ingresando al siguiente enlace: Reconocimiento de dígitos escritos a mano.

Si te pareció interesante y quieres una serie de Machine Learning con Python, déjamelo saber.

Comparte tu experiencia con nosotros dejando un buen comentario y dinos que te pareció el articulo.

Mi nombre es Bill Gates, y fue un placer compartir mis conocimientos con todos ustedes :D.

1 comentario :
Write comentarios
  1. Un post muy interesante, hay una cosa que no me ha quedado clara, para que el programa identifique el dígito que hemos escrito a mano, ¿habría que sacar una foto a dicho dígito y despues transformar esa fotografía en un vector hiperdimensional?

    ResponderEliminar

Tu comentario es importante y nos motiva a seguir escribiendo...

Powered by Blogger .