Python para todos (5): Termina tu primer experimento de Machine Learning con Python

Tuesday, April 17, 2018

Python para todos (5): Termina tu primer experimento de Machine Learning con Python

Llegamos por fin a la última parte del experimento de Machine Learning con Python para todos los públicos. Hemos ido paso a paso, a lo largo de 5 post, aclarando dudas, aprendiendo sobre la marcha, sin prisa, pero sin pausa. En este último post seleccionamos los algoritmos, construimos el modelo, y lo ponemos a prueba con el dataset de validación. Hemos construido un buen modelo, y lo mejor de todo, le hemos perdido miedo a Python. Así que...¡ a seguir aprendiendo! 


Montañero llegando a la cima.
Figura 0: Montañero llegando a la cima.

Los pasos que vamos a dar a partir de ahora son los siguientes:
  1. Carga de los datos y módulos/librerías necesarias para este ejemplo.
  2. Exploración de los datos .
  3. Evaluación de diferentes algoritmos para seleccionar el modelos más adecuado a este caso.
  4. Aplicación del modelo para hacer predicciones a partir de lo "aprendido".
Para que no sea demasiado largo, en este 4º post realizaremos los dos primeros pasos y, en el siguiente y último (¡todo llega!), el tercero y el cuarto. 

3. Selección del algoritmos.


Ha llegado el momento de crear modelos a partir de los datos conocidos y estimar su precisión sobre datos nuevos. Para ello vamos a dar los siguientes pasos.:
  • Separaremos una parte de los datos para crear un dataset de validación
  • Usaremos validación cruzada de 10 interacciones para estimar la precisión
  • Construiremos 5 modelos diferentes para predecir, a partir de las medidas de las flores recogidas en el dataset, a qué especie pertenece una flor nueva
  • Seleccionaremos el mejor modelo

3.1 Creación del conjunto de datos de validación.


¿Cómo sabemos si nuestro modelo es bueno?. Para conocer qué tipo de métricas podemos usar para evaluar la "bondad" de un modelo basado en Machine Learning, os recomendamos leer este post que publicamos recientemente sobre la Matriz de Confusión. Usaremos métodos estadísticos para estimar la precisión de los modelos, pero también tendremos que evaluarlos sobre datos "nuevos". Para ello, tal y como hicimos en un experimento anterior de Machine Learning, esta vez en Azure Machine Learning Studio, reservaremos un 20% de los datos del dataset original. Así, aplicándolo a este conjunto de validación, podremos comprobar cómo funciona el modelo que hemos generado entrenando, el algoritmo que elijamos en este caso, con el 80% restante. Este procedimiento es lo que se conoce como método de retención (holdout method).

Con el siguiente código, que, como hemos hecho hasta ahora podemos teclear o copiar y pegar en nuestro Jupyter Notebook, separamos los datos en los conjuntos de entrenamiento X_train, Y_train, y los de validación X_validation, Y_validation.


Este método resulta práctico porque es muy rápido a la hora de computar. Sin embargo, no es muy preciso, ya que los resultados varían mucho si elegimos datos de entrenamiento diferentes. Debido a estas carencias surgió el concepto de validación cruzada.

3.2 Validación cruzada


El objetivo de la validación cruzada o cross-validation es garantizar que los resultados que obtengamos sean independientes de la partición entre datos de entrenamiento y datos de validación, y por eso se usa mucho en para validar modelos generados en proyectos de IA.  Consiste en repetir y calcular la media aritmética de las medidas de evaluación que obtenemos sobre diferentes particiones. En este caso, vamos a utilizar un proceso de validación cruzada con 10 interacciones. Eso significa que nuestro conjunto de datos de entrenamiento, se divide en 10 partes, entrena en 9, valida en 1 y repite el proceso 10 veces. En la imagen podemos ver un ejemplo muy visual de cómo sería el proceso con 4 interacciones.

Figura 1: Validación Cruzada, 4 iteraciones.
Figura 1: Validación Cruzada, (By Joan.domenech91 CC BY-SA 3.0)

Para evaluar el modelo, elegimos para la variable de estimación scoring la métrica accuracy (precisión), que representa el ratio entre el número de instancias que el modelo ha predicho correctamente, frente al número total de instancias del dataset, multiplicado por 100 para dar un resultado porcentual.

Para ello, añadimos el siguiente código:


3.3 Construcción de los modelos


Como a priori no sabemos qué algoritmos pueden funcionar mejor para este problema, vamos a probar con 6 diferentes, tanto lineales (LR, LDA), como no lineales (KNN, CART, NB y SVM). Las gráficas iniciales ya indican que podemor ir por buen camino, porque que se aprecia que algunas clases van a ser linealmente separables en alguna dimensión. Vamos a evaluar los siguientes algoritmos:
  • Regresión logística (LR)
  • Análisis del Discriminante lineal (LDA)
  • K- Vecinos más cercanos (KNN)
  • Árboles de clasificación y regresión (CART)
  • Gaussiana Naive Bayes (NB)
  • Máquinas de vectores de soporte (SVM)
Antes de cada ejecución resetearemos el valor inicial (seed) para asegurarnos que la evaluación de cada algoritmo se realiza usando el mismo conjunto de datos (data split), para asegurarnos de que los resultados sean directamente comparables. Añadimos, por tanto, el siguiente código:


3.4 Elegimos el modelo que funciona mejor


Si ejecutamos las celdas (Cell/Run Cells) podemos observar los estimadores para cada modelo. De esta forma, los podemos comparar y elegir el mejor. Si observamos los resultados obtenidos, podemos ver que el modelo que da un mayor valor de precisión es KNN (98%)

Resultados de precisión de los distintos algoritmos.
Figura 2: Resultados de precisión de los distintos algoritmos.

También podemos hacer una gráfica con los resultados de evaluación de los modelos y comparar su distribución y la precisión media para cada modelo (ya que se cada algoritmo se evalúa en 10 iteracciones por el tipo de validación cruzada que hemos elegido). Para ello, añadimos el siguiente código:


Obtenemos como resultado:

Box and Whisker plots de comparación de algoritmos.
Figura 3: Box and Whisker plots de comparación de algoritmos.


En el diagrama de caja y bigotes se aprecia claramente cómo la precisión para muchas de las muestras en los modelos KNN, NB y SVM llega a ser del 100%, mientras que el modelo que ofrece menor precisión es la regresión lineal LR.

4. Aplicamos el modelo para hacer predicciones.


Ha llegado el momento de poner a prueba el modelo creado a partir de los datos de entrenamiento. Para ello, lo que hacemos es aplicarlo a esa parte del dataset original que separamos al principio como dataset de validación. Como tenemos los valores correctos de clasificación, y no se han usado en el entrenamiento del modelo, si comparamos los valores reales con predichos por el modelo sabremos si el modelo es bueno o  no. Para ello, aplicamos el modelo elegido (el que nos haya dado mayor precisión en el paso anterior) directamente a éste dataset, y resumimos los resultados con un valor de precisión final (final validation score), una matriz de confusión y un informe de clasificación.

Para aplicar el  modelo basado en el algoritmo SVM, no tenemos más que ejecutar el siguiente código:

Obtenemos algo similar a esto:


Evaluación del algoritmo sobre el dataset de validación.
Figura 4: Evaluación del algoritmo sobre el dataset de validación.

Como vemos, la precisión es 0.93, un 93%, un dato muy bueno. La matriz de confusión,  por su parte, nos indica el número de puntos para los cuales la predicción del modelo ha sido correcta (valores en la diagonal: 7+10+11=28), y los elementos fuera la diagonal son los errores de predicción (2). Por tanto, podemos concluir que es un buen modelo que podemos aplicar con tranquilidad a un nuevo dataset.

Hemos basado el modelo en el algoritmo SVM, pero los valores de precisión para KNN también son muy buenos. ¿Os animáis a hacer éste último paso aplicando este otro algoritmo?

Con este paso, podríamos dar por terminado nuestro primer experimento de Machine Learning con Python. Nuestra recomendación: vuelve a hacer todo el experimento, toma nota de las dudas que te surjan, intenta buscar respuestas por tu cuenta, prueba a hacer pequeños cambios en el código, como el último que hemos propuesto y.... En plataformas como Coursera, edX, DataCamp, o CodeAcademy puedes encontrar cursos gratuitos para seguir avanzando. ¡No dejes de aprender!.

Todos los post de este tutorial, aquí:
Agradecimientos a Jason Browniie, autor de experimento original en el que se basa esta serie.


4 comments:

  1. En la sección 3.3 falta el código

    ReplyDelete
    Replies
    1. Gracias por avisarnos Pudgo, ya lo hemos subido. Y enhorabuena por llegar al final de experimento.

      Delete
  2. Al llegar a la seccion 3.3 y ejecutar el codigo me devuelve el siguiente error (no se que puedo estar haciendo mal):

    in ()
    4 for name, model in models:
    5 kfold = model_selection.KFold(n_splits=10, random_state=seed)
    ----> 6 cv_results = model_selection.cross_val_score(model, X_train, Y_train, cv=kfold, scoring=scoring)
    7 results.append(cv_results)
    8 names.append(name)

    NameError: name 'X_train' is not defined

    ReplyDelete
  3. Hola Raul, como puedes ver en el error que te da dice algo así como que no está definido lo que es ´X-train´. Y, efectivamente, faltaban unas líneas de código que ya he añadido. El problema, como pasó con la otra parte que faltaba, es que para añadir el código y que sea editable, hay que añadir un script en Blogger que no se ve en el modo edición y...los debí borrar sin darme cuenta. Ya esta todo correcto. Gracias por seguir hasta el final y por advertirnos.

    ReplyDelete