Validación cruzada y búsqueda de cuadrícula para la selección de modelos en Python

V

Introducción

Un proceso típico de Machine Learning implica entrenar diferentes modelos en el conjunto de datos y seleccionar el que tenga el mejor rendimiento. Sin embargo, evaluar el rendimiento del algoritmo no siempre es una tarea sencilla. Hay varios factores que pueden ayudarlo a determinar qué algoritmo funciona mejor. Uno de esos factores es el rendimiento en el conjunto de validación cruzada y otro factor más es la elección de parámetros para un algoritmo.

En este artículo exploraremos estos dos factores en detalle. Primero estudiaremos qué es la validación cruzada, por qué es necesaria y cómo realizarla a través de Python Scikit-Learn biblioteca. Luego pasaremos al Algoritmo de búsqueda de cuadrícula y vea cómo se puede utilizar para seleccionar automáticamente los mejores parámetros para un algoritmo.

Validación cruzada

Normalmente, en un proceso de Machine Learning, los datos se dividen en conjuntos de entrenamiento y de prueba; el conjunto de entrenamiento se usa para entrenar el modelo y el conjunto de prueba se usa para evaluar el rendimiento de un modelo. Sin embargo, este enfoque puede generar problemas de variación. En palabras más simples, un problema de varianza se refiere al escenario en el que nuestra precisión obtenida en una prueba es muy diferente a la precisión obtenida en otro conjunto de pruebas utilizando el mismo algoritmo.

La solución a este problema es utilizar Validación cruzada de K-Fold para la evaluación del desempeño donde K es cualquier número. El proceso de validación cruzada de K-Fold es sencillo. Divide los datos en K pliegues. De los pliegues K, los conjuntos K-1 se utilizan para entrenamiento, mientras que el conjunto restante se utiliza para pruebas. El algoritmo se entrena y se prueba K veces, cada vez que se utiliza un nuevo conjunto como conjunto de prueba, mientras que los conjuntos restantes se utilizan para el entrenamiento. Finalmente, el resultado de la validación cruzada de K-Fold es el promedio de los resultados obtenidos en cada serie.

Supongamos que queremos realizar una validación cruzada de 5 veces. Para hacerlo, los datos se dividen en 5 conjuntos, por ejemplo, los llamamos SET A, SET B, SET C, SET D y SET E. El algoritmo se entrena y prueba K veces. En el primer pliegue, SET A a SET D se utilizan como conjunto de entrenamiento y SET E se utiliza como conjunto de prueba como se muestra en la siguiente figura:

En el segundo pliegue, SET A, SET B, SET C y SET E se usan para entrenamiento y SET D se usa como prueba. El proceso continúa hasta que cada conjunto se usa al menos una vez para entrenamiento y una vez para prueba. El resultado final es el promedio de los resultados obtenidos usando todos los pliegues. De esta forma podemos deshacernos de la varianza. Usando la desviación estándar de los resultados obtenidos de cada pliegue, de hecho podemos encontrar la varianza en el resultado general.

Validación cruzada con Scikit-Learn

En esta sección utilizaremos la validación cruzada para evaluar el rendimiento del algoritmo de bosque aleatorio para la clasificación. El problema que vamos a resolver es predecir la calidad del vino en base a 12 atributos. Los detalles del conjunto de datos están disponibles en el siguiente enlace:

https://archive.ics.uci.edu/ml/datasets/wine+quality

Solo usamos los datos para el vino tinto en este artículo.

Siga estos pasos para implementar la validación cruzada usando Scikit-Learn:

1. Importación de bibliotecas necesarias

El siguiente código importa algunas de las bibliotecas necesarias:

import pandas as pd
import numpy as np

2. Importación del conjunto de datos

Descargue el conjunto de datos, que está disponible en línea en este enlace:

https://www.kaggle.com/piyushgoyal443/red-wine-dataset

Una vez que lo hemos descargado, colocamos el archivo en la carpeta “Conjuntos de datos” de nuestra unidad “D” por el bien de este artículo. El nombre del conjunto de datos es “winequality-red.csv”. Tenga en cuenta que deberá cambiar la ruta del archivo para que coincida con la ubicación en la que guardó el archivo en su computadora.

Ejecute el siguiente comando para importar el conjunto de datos:

dataset = pd.read_csv(r"D:/Datasets/winequality-red.csv", sep=';')

El conjunto de datos se separó por punto y coma, por lo tanto, hemos pasado el “;” atributo al parámetro “sep” para que los pandas puedan analizar correctamente el archivo.

3. Análisis de datos

Ejecute el siguiente script para obtener una descripción general de los datos:

dataset.head()

La salida se ve así:

acidez fija acidez volátil ácido cítrico azúcares residuales cloruros dióxido de azufre libre dióxido de azufre total densidad pH sulfatos calidad del alcohol
01234

7.40,700,001,90,07611,034,00.99783,510,569.45
7.80,880,002.60,09825,067,00,99683,200,689,85
7.80,760,042.30.09215.054,00,99703,260,659,85
11,20,280,561,90,07517.060,00,99803,160,589,86
7.40,700,001,90,07611,034,00,99783,510,569.45

4. Procesamiento previo de datos

Ejecute la siguiente secuencia de comandos para dividir los datos en conjuntos de características y etiquetas.

X = dataset.iloc[:, 0:11].values
y = dataset.iloc[:, 11].values

Dado que utilizamos la validación cruzada, no necesitamos dividir nuestros datos en conjuntos de prueba y entrenamiento. Queremos todos los datos en el conjunto de entrenamiento para que podamos aplicar la validación cruzada en eso. La forma más sencilla de hacer esto es establecer el valor de la test_size parámetro a 0. Esto devolverá todos los datos en el conjunto de entrenamiento de la siguiente manera:

from sklearn.model_selection import train_test_split
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0, random_state=0)

5. Escalar los datos

Si observa el conjunto de datos, notará que no está bien escalado. Por ejemplo, la columna “acidez volátil” y “ácido cítrico” tienen valores entre 0 y 1, mientras que la mayoría del resto de las columnas tienen valores más altos. Por lo tanto, antes de entrenar el algoritmo, necesitaremos reducir la escala de nuestros datos.

Aquí usaremos el StandardScalar clase.

from sklearn.preprocessing import StandardScaler
feature_scaler = StandardScaler()
X_train = feature_scaler.fit_transform(X_train)
X_test = feature_scaler.transform(X_test)

6. Capacitación y validación cruzada

El primer paso de la fase de formación y validación cruzada es sencillo. Solo tienes que importar la clase de algoritmo del sklearn biblioteca como se muestra a continuación:

from sklearn.ensemble import RandomForestClassifier
classifier = RandomForestClassifier(n_estimators=300, random_state=0)

A continuación, para implementar la validación cruzada, cross_val_score método del sklearn.model_selection se puede utilizar la biblioteca. los cross_val_score devuelve la precisión de todos los pliegues. Los valores de 4 parámetros deben pasarse al cross_val_score clase. El primer parámetro es el estimador, que básicamente especifica el algoritmo que desea utilizar para la validación cruzada. El segundo y tercer parámetro, X y y, contiene el X_train y y_train datos, es decir, características y etiquetas. Finalmente el número de pliegues se pasa al cv parámetro como se muestra en el siguiente código:

from sklearn.model_selection import cross_val_score
all_accuracies = cross_val_score(estimator=classifier, X=X_train, y=y_train, cv=5)

Una vez que haya ejecutado esto, simplemente imprimamos las precisiones devueltas para cinco pliegues por el cross_val_score método llamando print en all_accuracies.

print(all_accuracies)

Salida:

[ 0.72360248  0.68535826  0.70716511  0.68553459  0.68454259 ]

Para encontrar el promedio de todas las precisiones, simplemente use el mean() método del objeto devuelto por cross_val_score método como se muestra a continuación:

print(all_accuracies.mean())

El valor medio es 0,6972 o 69,72%.

Finalmente, encontremos la desviación estándar de los datos para ver el grado de varianza en los resultados obtenidos por nuestro modelo. Para hacerlo, llame al std() método en el all_accuracies objeto.

print(all_accuracies.std())

El resultado es: 0.01572 que es 1.57%. Esto es extremadamente bajo, lo que significa que nuestro modelo tiene una varianza muy baja, lo que en realidad es muy bueno, ya que eso significa que la predicción que obtuvimos en un conjunto de prueba no es casual. Por el contrario, el modelo tendrá un rendimiento más o menos similar en todos los equipos de prueba.

Búsqueda de cuadrícula para selección de parámetros

Un modelo de Machine Learning tiene dos tipos de parámetros. El primer tipo de parámetros son los parámetros que se aprenden a través de un modelo de Machine Learning, mientras que el segundo tipo de parámetros son los hiperparámetros que pasamos al modelo de Machine Learning.

En la última sección, al predecir la calidad del vino, usamos el algoritmo Random Forest. El número de estimadores que usamos para el algoritmo fue 300. De manera similar, en el algoritmo KNN tenemos que especificar el valor de K y para el algoritmo SVM tenemos que especificar el tipo de Kernel. Estos estimadores, el valor K y el kernel, son todos tipos de hiperparámetros.

Normalmente establecemos aleatoriamente el valor de estos hiperparámetros y vemos qué parámetros dan como resultado el mejor rendimiento. Sin embargo, la selección aleatoria de parámetros para el algoritmo puede resultar exhaustiva.

Además, no es fácil comparar el rendimiento de diferentes algoritmos configurando aleatoriamente los hiperparámetros porque un algoritmo puede funcionar mejor que el otro con diferentes conjuntos de parámetros. Y si se cambian los parámetros, el algoritmo puede funcionar peor que los otros algoritmos.

Por lo tanto, en lugar de seleccionar aleatoriamente los valores de los parámetros, un mejor enfoque sería desarrollar un algoritmo que encuentre automáticamente los mejores parámetros para un modelo en particular. Grid Search es uno de esos algoritmos.

Búsqueda de cuadrícula con Scikit-Learn

Implementemos el algoritmo de búsqueda de cuadrícula con la ayuda de un ejemplo. El script de esta sección debe ejecutarse después del script que creamos en la última sección.

Para implementar el algoritmo Grid Search necesitamos importar GridSearchCV clase de la sklearn.model_selection biblioteca.

El primer paso que debe realizar es crear un diccionario de todos los parámetros y su correspondiente conjunto de valores que desea probar para obtener el mejor rendimiento. El nombre de los elementos del diccionario corresponde al nombre del parámetro y el valor corresponde a la lista de valores del parámetro.

Creemos un diccionario de parámetros y sus valores correspondientes para nuestro algoritmo Random Forest. Los detalles de todos los parámetros para el algoritmo de bosque aleatorio están disponibles en el Documentos de Scikit-Learn.

Para hacer esto, ejecute el siguiente código:

grid_param = {
    'n_estimators': [100, 300, 500, 800, 1000],
    'criterion': ['gini', 'entropy'],
    'bootstrap': [True, False]
}

Eche un vistazo con atención al código anterior. Aquí creamos grid_param diccionario con tres parámetros n_estimators, criteriony bootstrap. Los valores de los parámetros que queremos probar se pasan en la lista. Por ejemplo, en el script anterior queremos encontrar qué valor (de 100, 300, 500, 800 y 1000) proporciona la mayor precisión.

Del mismo modo, queremos encontrar qué valor da como resultado el rendimiento más alto para el criterion parámetro: “gini” o “entropía”? El algoritmo Grid Search básicamente prueba todas las combinaciones posibles de valores de parámetros y devuelve la combinación con la mayor precisión. Por ejemplo, en el caso anterior, el algoritmo verificará 20 combinaciones (5 x 2 x 2 = 20).

El algoritmo de búsqueda de cuadrícula puede ser muy lento, debido a la gran cantidad de combinaciones para probar. Además, la validación cruzada aumenta aún más el tiempo de ejecución y la complejidad.

Una vez creado el diccionario de parámetros, el siguiente paso es crear una instancia del GridSearchCV clase. Necesita pasar valores para el estimator parámetro, que básicamente es el algoritmo que desea ejecutar. los param_grid parámetro toma el diccionario de parámetros que acabamos de crear como parámetro, el scoring parámetro toma las métricas de rendimiento, el cv El parámetro corresponde al número de pliegues, que es 5 en nuestro caso, y finalmente el n_jobs El parámetro se refiere al número de CPU que desea utilizar para la ejecución. Un valor de -1 para n_jobs parámetro significa que utiliza toda la potencia de cálculo disponible. Esto puede ser útil si tiene una gran cantidad de datos.

Eche un vistazo al siguiente código:

gd_sr = GridSearchCV(estimator=classifier,
                     param_grid=grid_param,
                     scoring='accuracy',
                     cv=5,
                     n_jobs=-1)

Una vez el GridSearchCV se inicializa la clase, el último paso es llamar al fit método de la clase y pasarle el conjunto de entrenamiento y prueba, como se muestra en el siguiente código:

gd_sr.fit(X_train, y_train)

Este método puede tardar algún tiempo en ejecutarse porque tenemos 20 combinaciones de parámetros y una validación cruzada de 5 veces. Por lo tanto, el algoritmo se ejecutará un total de 100 veces.

Una vez que el método completa la ejecución, el siguiente paso es verificar los parámetros que devuelven la mayor precisión. Para hacerlo, imprima el sr.best_params_ atributo del GridSearchCV objeto, como se muestra a continuación:

best_parameters = gd_sr.best_params_
print(best_parameters)

Salida:

{'bootstrap': True, 'criterion': 'gini', 'n_estimators': 1000}

El resultado muestra que la mayor precisión se logra cuando el n_estimators son 1000, bootstrap es True y criterion es “gini”.

Nota: Sería una buena idea agregar más estimadores y ver si el desempeño aumenta aún más desde el valor más alto permitido de n_estimators fue elegido.

El último y último paso del algoritmo Grid Search es encontrar la precisión obtenida utilizando los mejores parámetros. Anteriormente teníamos una precisión media del 69,72% con 300 n_estimators.

Para encontrar la mejor precisión lograda, ejecute el siguiente código:

best_result = gd_sr.best_score_
print(best_result)

La precisión alcanzada es: 0,6985 del 69,85%, que es solo ligeramente mejor que el 69,72%. Para mejorar esto aún más, sería bueno probar los valores de otros parámetros del algoritmo Random Forest, como max_features, max_depth, max_leaf_nodes, etc. para ver si la precisión mejora o no.

Conclusión

En este artículo estudiamos dos técnicas muy utilizadas para la evaluación del desempeño y la selección del modelo de un algoritmo. La validación cruzada de K-Fold se puede utilizar para evaluar el rendimiento de un modelo manejando el problema de varianza del conjunto de resultados. Además, para identificar el mejor algoritmo y los mejores parámetros, podemos utilizar el algoritmo Grid Search.

 

About the author

Ramiro de la Vega

Bienvenido a Pharos.sh

Soy Ramiro de la Vega, Estadounidense con raíces Españolas. Empecé a programar hace casi 20 años cuando era muy jovencito.

Espero que en mi web encuentres la inspiración y ayuda que necesitas para adentrarte en el fantástico mundo de la programación y conseguir tus objetivos por difíciles que sean.

Add comment

Sobre mi

Últimos Post

Etiquetas

Esta web utiliza cookies propias para su correcto funcionamiento. Al hacer clic en el botón Aceptar, aceptas el uso de estas tecnologías y el procesamiento de tus datos para estos propósitos. Más información
Privacidad