sábado, 12 de octubre de 2019

Un primer proyecto de Machine Learning con Python paso a paso, el “Hola Mundo”

En este artículo vamos a realizar un proyecto de Machine Learning con Python. Prepararemos datos con pandas, ajustaremos y evaluaremos modelos con scikit-learn La mejor manera de aprender el aprendizaje automático es diseñando y completando pequeños proyectos. Python puede ser intimidante al principio, es un lenguaje interpretado popular y potente. A diferencia de R, Python es un lenguaje completo y una plataforma que se puede usar tanto para investigación como desarrollo y de sistemas de producción.

Un primer proyecto de Machine Learning con Python paso a paso, el “Hola Mundo”
Mujer trabajando en un CPD
También hay muchos módulos y bibliotecas para elegir, que ofrecen múltiples formas de realizar cada tarea. Podemos sentirnos abrumados. La mejor manera de comenzar a usar Python en ML (Machine Learning) es realizar un proyecto completo.

Un proyecto de ML  puede no ser lineal, pero tiene varios pasos bien conocidos:

1. Definición del problema
2. Preparar datos
3. Evaluar algoritmos
4. Mejorar los resultados
5. Muestra de Resultados

Con esto, tendremos una plantilla para utilizar en proyectos sucesivos.

El Hola mundo del Machine Learning

Un buen proyecto puede ser la clasificación de flores de  iris (por ejemplo, el conjunto de datos de iris).

• Los atributos son numéricos, por lo que debemos descubrir cómo cargar y manejar datos.

• Es un problema de clasificación, que permite practicar con un tipo más fácil de algoritmo de aprendizaje supervisado.

• Es un problema varias clases (multinominales) que puede requerir un manejo especializado.

• Solo tenemos 4 atributos y 150 filas, lo que significa que es pequeño.

• Todos los atributos numéricos están en las mismas unidades y en la misma escala, y no requieren ninguna escala especial o transformaciones para comenzar.

Machine Learning en Python: tutorial paso a paso

En esta sección, vamos a trabajar a través de un pequeño proyecto de ML de principio a fin.
Aquí hay una descripción general de lo que vamos a cubrir:

1. Instalación de la plataforma Python y SciPy
2. Cargar el conjunto de datos
3. Resumir el conjunto de datos
4. Visualizar el conjunto de datos
5. Evaluar algunos algoritmos
6. Hacer predicciones

Instalar bibliotecas SciPy

Hay 5 bibliotecas clave que necesitaremos instalar:
• scipy
• numpy
• matplotlib
• pandas
• sklearn


Hay muchas formas de instalar estas bibliotecas. 
La página de instalación scipy proporciona excelentes instrucciones para instalar las bibliotecas anteriores.
En Windows se recomendaría instalar la versión gratuita de Anaconda que incluye todo lo que necesitamos 

Nota: Este tutorial asume que tenemos instalado scikit-learn versión 0.18 o superior.

Iniciar Python y verificar versiones

Es una buena idea asegurarse de que nuestro entorno Python se haya instalado correctamente y que funcione como se esperaba.

Recomendamos trabajar directamente en el intérprete o escribir nuestros scripts y ejecutarlos en la línea de comandos en lugar de grandes editores IDE. 
Debemos escribir o copiar y pegar el siguiente script en Jupyter,  Colaboratory o cualquier intérprete de Phyton.

# Python version
import sys
print('Python: {}'.format(sys.version))
# scipy
import scipy
print('scipy: {}'.format(scipy.__version__))
# numpy
import numpy
print('numpy: {}'.format(numpy.__version__))
# matplotlib
import matplotlib
print('matplotlib: {}'.format(matplotlib.__version__))
# pandas
import pandas
print('pandas: {}'.format(pandas.__version__))
# scikit-learn
import sklearn
print('sklearn: {}'.format(sklearn.__version__))
  
Esto nos devolverá información sobre las versiones de los paquetes instalados.

Si obtenemos  un error, hay que tratar de arreglarlo, si no podemos ejecutar el script anterior limpiamente, no podremos completar esta guía. Se Podemosrecomiebda buscar el error en  Stack Exchange.

Cargamos los datos

Vamos a utilizar el conjunto de datos de la flor  iris. Este conjunto de datos es famoso porque mucha gente lo utilizan como conjunto de datos para su "hola mundo" en ML.
El conjunto de datos contiene 150 medidas de diferentes flores de tipo iris. Hay cuatro columnas de medidas de las iris en centímetros. La quinta columna es la especie de iris observada. Todas las iris observadas pertenecen a una de las tres especies.
En este paso vamos a cargar los datos de dichas flores desde la URL de un archivo CSV.

Importar bibliotecas

Primero, importaremos todos los módulos, funciones y objetos que vamos a utilizar en este artículo.

# Load libraries
import pandas
from pandas.plotting import scatter_matrix
import matplotlib.pyplot as plt
from sklearn import model_selection
from sklearn.metrics import classification_report
from sklearn.metrics import confusion_matrix
from sklearn.metrics import accuracy_score
from sklearn.linear_model import LogisticRegression
from sklearn.tree import DecisionTreeClassifier
from sklearn.neighbors import KNeighborsClassifier
from sklearn.discriminant_analysis import LinearDiscriminantAnalysis
from sklearn.naive_bayes import GaussianNB
from sklearn.svm import SVC

Todo debería cargarse sin error. Si tenemos un error, hay que detenerse. Necesitamos un entorno SciPy que funcione antes de continuar. 

Cargar el conjunto de datos

Podemos cargar los datos directamente desde el repositorio de UCI de ML Estamos usando pandas para cargar los datos. También usaremos pandas para explorar los datos con estadísticas descriptivas y visualización de datos.
Hay que tener en cuenta que estamos especificando los nombres de cada columna al cargar los datos. Esto ayudará más adelante cuando exploremos los datos.

# Load dataset
url = "https://raw.githubusercontent.com/jbrownlee/Datasets/master/iris.csv"
names = ['sepal-length', 'sepal-width', 'petal-length', 'petal-width', 'class']
dataset = pandas.read_csv(url, names=names)

El conjunto de datos debería cargarse sin problema.


Cargar un archivo desde nuestro equipo a Colaboratory

Si tenemos problemas de red, podemos descargar el archivo iris.csv en nuestro directorio de trabajo y cargarlo utilizando el mismo método, cambiando la URL por el nombre del archivo local. Si trabajamos con Colaboratory y deseamos subir un archivo de nuestro equipo podemos hacerlo con:

from google.colab import files
uploaded = files.upload()

Esto mostrará un cuadro de diálogo desde el que podemos pulsar el botón elegir
archivos, lo que nos muestra un explorador de nuestro equipo para elegir el
archivo deseado que subiremos a Colaboratory.

Para descargar un arcgivo desd Colaboratory a nuestro equipo hacemos

uploaded = files.download('Archivo_a_descargar.png')

Para ver nuestros datos hacemos esto

print (uploaded['Mi_Documento_CSV.csv'][:200].decode('utf-8') + '...')


Resumir el conjunto de datos

Ahora es el momento de echar un vistazo a los datos.
En este paso vamos a echar un vistazo a los datos de diferentes maneras:

1. Dimensiones del conjunto de datos.
2. Mirar los datos en sí.
3. Resumen estadístico de todos los atributos.
4. Desglose de los datos por la variable de clase.

Cada punto de la lista es un comando. Estos son comandos podemos utilizarlos una y otra vez en proyectos futuros.

Dimensiones del conjunto de datos

Podemos tener una idea rápida de cuántas instancias (filas) y cuántos atributos (columnas) contienen los datos con la propiedad de forma.

# shape
print(dataset.shape)

Deberíamos ver 150 instancias y 5 atributos:

 (150, 5)

También es una buena idea mirar realmente nuestros datos.

# head
print(dataset.head(20))

Deberíamos ver las primeras 20 filas de datos:

Hola Mundo Machine Learning


Resumen estadístico

Ahora podemos echar un vistazo a un resumen de cada atributo. Esto incluye el recuento, la media, los valores mínimo y máximo, así como algunos percentiles.

# descriptions
print(dataset.describe())

Podemos ver que todos los valores numéricos tienen la misma escala (centímetros) y rangos similares entre 0 y 8 centímetros.


Ver un dataset con Python


Distribución de clase

Veamos ahora el número de instancias (filas) que pertenecen a cada clase. Podemos ver esto como un recuento absoluto.

# class distribution
print(dataset.groupby('class').size())

Podemos ver que cada clase tiene el mismo número de instancias (50 o 33% del conjunto de datos).

 clase
Iris-setosa 50
Iris-versicolor 50
Iris-virginica 50

Visualización de datos

Ahora tenemos una idea básica sobre los datos. Necesitamos extender eso con algunas visualizaciones.
Vamos a ver dos tipos de parcelas:

Gráficos univariados para comprender mejor cada atributo.

Trazados multivariados para comprender mejor las relaciones entre los atributos.


Gráficos univariados

Comenzamos con algunas gráficas univariadas, es decir, gráficas de cada variable individual.
Dado que las variables de entrada son numéricas, podemos crear diagramas de caja y bigotes de cada uno.

 # box and whisker plots
dataset.plot(kind='box', subplots=True, layout=(2,2), sharex=False, sharey=False)
plt.show()

Esto nos da una idea mucho más clara de la distribución de los atributos de entrada:

Parcelas univariadas


También podemos crear un histograma de cada variable de entrada para tener una idea de la distribución.

# histograms
dataset.hist()
plt.show()


Histogramas con Python


Parece que quizás dos de las variables de entrada tienen una distribución gaussiana. Es útil tener en cuenta que podemos usar algoritmos que pueden explotar esta suposición.

Parcelas multivariadas

Ahora podemos ver las interacciones entre las variables.
Primero, veamos los diagramas de dispersión de todos los pares de atributos. Esto puede ser útil para detectar relaciones estructuradas entre variables de entrada.

# scatter plot matrix
scatter_matrix(dataset)
plt.show()


Parcelas multivariadas


Hay que tener en cuenta que la agrupación diagonal de algunos pares de atributos.  sugiere una alta correlación y una relación predecible.

Evaluar los algoritmos

Ahora crearemos algunos modelos de datos y estimaremos su precisión en datos nuevos. Esto es lo que vamos a cubrir en este paso:

1. Separar un conjunto de datos de validación.
2. Configurar un subconjunto de prueba para utilizar la validación cruzada 10 veces.
3. Construir 5 modelos diferentes para predecir a que especie pertenece una flor a partir de sus medidas
4. Seleccionar el mejor modelo.

Crear un conjunto de datos de validación

Necesitamos saber que el modelo que creamos es bueno. Más tarde, utilizaremos métodos estadísticos para estimar la precisión de los modelos que creamos en datos nuevos. También queremos una estimación más concreta de la precisión del mejor modelo en datos nuevos al evaluarlo en datos  reales.
Es decir, vamos a retener algunos datos que los algoritmos no verán y usaremos estos datos para tener una segunda idea independiente de cuán preciso podría ser realmente el mejor modelo.
Dividiremos el conjunto de datos cargado en dos, el 80% de los cuales utilizaremos para entrenar nuestros modelos y el 20% que retendremos como conjunto de datos de validación.

# Split-out validation dataset
array = dataset.values
X = array[:,0:4]
Y = array[:,4]
validation_size = 0.20
seed = 7
X_train, X_validation, Y_train, Y_validation = model_selection.train_test_split(X, Y, test_size=validation_size, random_state=seed)

Ahora tenemos datos de entrenamiento en X_train y en Y_train para preparar modelos y conjuntos y en X_validation e Y_validation que podemos usar más adelante.
Observar que usamos un segmento de python para seleccionar las columnas en la matriz NumPy. 

Prueba del modelo

Utilizaremos la validación cruzada 10 veces para estimar la precisión. Esto dividirá nuestro conjunto de datos en 10 partes, entrenará en 9 y probará en 1 y repetirá para todas las combinaciones de divisiones de prueba de entrenamiento.

# Test options and evaluation metric
seed = 7
scoring = 'accuracy'

La semilla aleatoria específica no importa, puede ser cualquier número.

Estamos utilizando la métrica de ‘precisión‘ para evaluar modelos. Esta es una relación del número de instancias correctamente predichas dividido por el número total de instancias en el conjunto de datos multiplicado por 100 para dar un porcentaje (por ejemplo, 95% de precisión). Usaremos la variable de puntuación cuando ejecutemos build y evaluamos cada modelo a continuación.

Construir modelos

No sabemos qué algoritmos serían buenos para este problema o qué configuraciones usar. A partir de las gráficas, tenemos una idea de que algunas de las clases son parcialmente separables linealmente en algunas dimensiones, por lo que generalmente esperaremos buenos resultados.

Vamos a evaluar 6 algoritmos diferentes:
• Regresión logística (LR)
• Análisis discriminante lineal (LDA)
• Vecinos K-Nearest (KNN).
• Árboles de clasificación y regresión (CART).
• Naive Bayes Gaussiano (NB).
• Máquinas de vectores de soporte (SVM).

Esta es una buena mezcla de algoritmos lineales simples (LR y LDA), y no lineales (KNN, CART, NB y SVM). Restablecemos la inicialización de números aleatorios antes de cada ejecución para garantizar que la evaluación de cada algoritmo se realice utilizando exactamente las mismas divisiones de datos. Nos aseguraremos de que los resultados sean directamente comparables.
Vamos a construir y evaluar nuestros modelos:

# Spot Check Algorithms
models = []
models.append(('LR', LogisticRegression(solver='liblinear', multi_class='ovr')))
models.append(('LDA', LinearDiscriminantAnalysis()))
models.append(('KNN', KNeighborsClassifier()))
models.append(('CART', DecisionTreeClassifier()))
models.append(('NB', GaussianNB()))
models.append(('SVM', SVC(gamma='auto')))
# evaluate each model in turn
results = []
names = []
for name, model in models:
  kfold = model_selection.KFold(n_splits=10, random_state=seed)
  cv_results = model_selection.cross_val_score(model, X_train, Y_train, cv=kfold, scoring=scoring)
  results.append(cv_results)
  names.append(name)
  msg = "%s: %f (%f)" % (name, cv_results.mean(), cv_results.std())
  print(msg)


Seleccionar el mejor modelo

Ahora tenemos 6 modelos y estimaciones de precisión para cada uno. Necesitamos comparar los modelos entre sí y seleccionar el más preciso.
Al ejecutar el ejemplo anterior, obtenemos los siguientes resultados sin procesar:


Comparar algoritmos con Python


Hay que tener en cuenta que nuestros resultados pueden diferir. 
En este caso, podemos ver que parece que Support Vector Machines (SVM) tiene la mayor puntuación de precisión estimada.
También podemos crear una gráfica de los resultados de la evaluación del modelo y comparar la dispersión y la precisión media de cada modelo. Hay una población de medidas de precisión para cada algoritmo porque cada algoritmo se evaluó 10 veces (validación cruzada 10 veces).

 # Compare Algorithms
fig = plt.figure()
fig.suptitle('Algorithm Comparison')
ax = fig.add_subplot(111)
plt.boxplot(results)
ax.set_xticklabels(names)
plt.show()

Podemos ver que las gráficas de caja y bigotes se aplastan en la parte superior del rango, y muchas muestras alcanzan el 100% de precisión.

Seleccionar el mejor modelo

Hacer predicciones

El algoritmo KNN es muy simple y fue un modelo preciso basado en nuestras pruebas. Ahora queremos tener una idea de la precisión del modelo en nuestro conjunto de validación.
Esto nos dará una verificación final independiente de la precisión del mejor modelo. Es valioso mantener un conjunto de validación en caso de que nos hayamos desplazado durante el entrenamiento, ya sea con un ajuste excesivo al conjunto de entrenamiento o con una pérdida de datos. Ambos darán como resultado un resultado demasiado optimista.
Podemos ejecutar el modelo KNN directamente en el conjunto de validación y resumir los resultados como un puntaje de precisión final, una matriz de confusión y un informe de clasificación.

# Make predictions on validation dataset
knn = KNeighborsClassifier()
knn.fit(X_train, Y_train)
predictions = knn.predict(X_validation)
print(accuracy_score(Y_validation, predictions))
print(confusion_matrix(Y_validation, predictions))
print(classification_report(Y_validation, predictions))

Podemos ver que la precisión es 0.9 o 90%. La matriz de confusión proporciona una indicación de los tres errores cometidos. Finalmente, el informe de clasificación proporciona un desglose de cada clase por precisión, recuerdo, puntaje f1 y soporte que muestra excelentes resultados (dado que el conjunto de datos de validación fue pequeño).

Hacer predicciones con python


No necesitamos entenderlo todo. (al menos no en este momento) Nuestro objetivo es ejecutar el tutorial de principio a fin y obtener un resultado. No es necesario que comprendamos todo a la primera. 
Podemos hacer un uso intensivo de la sintaxis de ayuda ("FunctionName") en Python para conocer todas las funciones que estamos utilizando.

Tampoco necesitamos saber cómo funcionan los algoritmos. Es importante conocer las limitaciones y cómo configurar algoritmos de aprendizaje automático. Pero aprender sobre algoritmos podemos hacerlo más tarde. 
No necesitamos ser programadores de Python. 

Aquí no cubrimos todos los pasos en un proyecto de Machine Learning porque este es nuestro primer proyecto y debemos centrarnos en los pasos clave. Es decir, cargar datos, mirar los datos, evaluar algunos algoritmos y hacer algunas predicciones. 

No hay comentarios:

Publicar un comentario