Gestión de flujos de trabajo de aprendizaje automático con pipelines de Scikit-Learn Parte 2: Integración de la búsqueda de cuadrículas

Otra técnica simple pero poderosa que podemos combinar con los pipelines para mejorar el rendimiento es la búsqueda de cuadrículas (grid search), que intenta optimizar las combinaciones de modelos de hiperparámetros.

Matthew Mayo
Ciencia y Datos
5 min readMay 23, 2018

--

En nuestra última publicación analizamos los pipelines de Scikit-learn como un método para simplificar los flujos de trabajo de aprendizaje automático. Diseñado como una forma manejable de aplicar una serie de transformaciones de datos seguidas por la aplicación de un estimador, los pipelines se notaron como una herramienta simple útil principalmente para:

  • Conveniencia en la creación de un flujo de trabajo coherente y fácil de entender
  • Aplicación de la implementación del flujo de trabajo y el orden deseado de las aplicaciones de paso
  • Reproducibilidad
  • Valor en la persistencia de objetos enteros de la tubería (va a la reproducibilidad y la conveniencia)

Otra técnica simple pero poderosa que podemos combinar con los pipelines para mejorar el rendimiento es la búsqueda de cuadrículas , que intenta optimizar las combinaciones de modelos de hiperparámetros. La búsqueda exhaustiva de la cuadrícula o red, en oposición a los esquemas alternativos de optimización de combinación de hiperparámetros, como la optimización aleatoria, evalúa y compara todas las combinaciones posibles de valores hiperparámetros deseados, un ejercicio en crecimiento exponencial. La compensación en lo que podría terminar siendo tiempos de ejecución exorbitantes sería (afortunadamente) el mejor modelo optimizado posible.

De la documentación oficial :

La búsqueda en cuadrícula proporcionada por GridSearchCV genera de manera exhaustiva candidatos de una red de valores de parámetros especificada con el parámetro param_grid. Por ejemplo, el siguiente param_grid:

param_grid = [
{'C': [1, 10, 100, 1000], 'kernel': ['linear']},
{'C': [1, 10, 100, 1000], 'gamma': [0.001, 0.0001], 'kernel': ['rbf']},
]

especifica que se deben explorar dos cuadrículas: una con un kernel lineal y valores de C en [1, 10, 100, 1000], y la segunda con un kernel de RBF, y el producto cruzado de valores C que varían en [1, 10 , 100, 1000] y valores gamma en [0.001, 0.0001].

Primero recordemos el código de la publicación anterior y ejecutemos un extracto modificado. Dado que utilizaremos un solo pipeline para este ejercicio, no necesitamos un conjunto completo como en la última publicación. Usaremos el conjunto de datos del iris una vez más.

Vamos a darle vida a esta tubería tan simple.

$ python3 pipelines-2a.py

Y la precisión e hiperparámetros devueltos del modelo:

Test accuracy: 0.867Model hyperparameters:
{'min_impurity_decrease': 0.0, 'min_weight_fraction_leaf': 0.0, 'max_leaf_nodes': None, 'max_depth': None,
'min_impurity_split': None, 'random_state': 42, 'class_weight': None, 'min_samples_leaf': 1, 'splitter': 'best',
'max_features': None, 'presort': False, 'min_samples_split': 2, 'criterion': 'gini'}

Nótese, una vez más, que estamos aplicando escalas de características, reducción de dimensionalidad (utilizando PCA para proyectar datos en un espacio bidimensional) y finalmente aplicando nuestro estimador final.

Ahora agreguemos la búsqueda de cuadrículas a nuestra cartera, con la esperanza de optimizar los hiperparámetros de nuestro modelo y mejorar su precisión. ¿Los parámetros predeterminados del modelo son la mejor opción? Vamos a averiguar.

Como nuestro modelo usa un estimador de árbol de decisión, utilizaremos la grilla de búsqueda para optimizar los siguientes hiperparámetros:

  • criterion — Esta es la función utilizada para evaluar la calidad de la división; usaremos ambas opciones disponibles en Scikit-learn: impureza de Gini y ganancia de información (entropía)
  • min_samples_leaf : este es el número mínimo de muestras requeridas para un nodo hoja válido; usaremos el rango entero de 1 a 5
  • max_depth — Es la profundidad máxima del árbol; usaremos el rango entero de 1 a 5
  • min_samples_split — Este es el número mínimo de muestras requeridas para dividir un nodo no hoja; usaremos el rango entero de 1 a 5
  • presort : indica si se preseleccionan o no los datos para acelerar la ubicación de las mejores divisiones durante la adaptación; esto no tiene ningún efecto en la precisión del modelo resultante (solo en tiempos de entrenamiento), pero se ha incluido para el beneficio de usar un hiperparámetro True / False en nuestro modelo de búsqueda de cuadrícula (¿diversión, ¿verdad?!?)

Aquí está el código para usar una búsqueda exhaustiva de la cuadrícula en nuestro ejemplo de pipeline adaptado.

De importancia, tenga en cuenta que nuestra tubería es el estimador en el objeto de búsqueda de la cuadrícula, y que está en el nivel del objeto de búsqueda de la grilla que encajamos en nuestro modelo(s). También ten en cuenta que nuestro espacio de parámetros de cuadrícula se define en un diccionario y luego se alimenta a nuestro objeto de búsqueda de cuadrículas.

¿Qué más está sucediendo durante la creación del objeto de búsqueda de cuadrícula? Para calificar nuestros modelos resultantes (hay un potencial de 2 * 5 * 5 * 5 * 2 = 500), direccionaremos nuestra búsqueda de cuadrícula para evaluarlos por su precisión en el conjunto de prueba. También hemos denotado una estrategia de división de validación cruzada de 10 pliegues. Tenga en cuenta lo siguiente sobre GridSearchCV:

Los parámetros del estimador utilizado para aplicar estos métodos se optimizan mediante una búsqueda de grillas con validación cruzada en una cuadrícula de parámetros.

Finalmente, por supuesto, nuestro modelo está en forma.

Deberás consultar la documentación oficial del módulo GridSearchCV para obtener información sobre todas las otras configuraciones útiles, incluido, entre otros, el paralelismo.

Probémoslo.

$ python3 pipelines-2b.py

Y aquí está el resultado:

Best accuracy: 0.925Best params:
{'clf__min_samples_split': 2, 'clf__criterion': 'gini', 'clf__max_depth': 2,
'clf__min_samples_leaf': 1, 'clf__presort': True}

El script informa la exactitud alcanzada más alta (0.925), que es claramente mejor que el valor predeterminado de 0.867, para un cálculo no excesivo, al menos no en términos absolutos, dado nuestro conjunto de datos de juguete. Nuestro enfoque exhaustivo, que incluía 500 modelos en este caso, podría haber tenido impactos computacionales mucho más graves en un conjunto de datos formidable, como se podría imaginar.

El script también informa la configuración de hiperparámetro óptima para el modelo con la mayor precisión, que se puede ver arriba. Esta diferencia en nuestro ejemplo simple debería ser evidencia suficiente para sugerir que los valores por defecto de Scikit-learn no deben seguirse a ciegas.

Todo esto parece demasiado simple. Y es. Scikit-Learn es casi demasiado fácil de usar, una vez que sepas qué opciones hay disponibles. Nuestro uso de conjuntos de datos de juguete tampoco lo hace parecer más complejo.

Pero míralo de esta manera: los pipelines y la búsqueda de cuadrículas van juntas como el chocolate y la mantequilla de maní, y ahora que hemos analizado los conceptos básicos de cómo funcionan juntos, podemos enfrentar algunos desafíos más difíciles. ¿Datos más complejos? Por supuesto. ¿Comparar una variedad de estimadores y numerosos espacios de búsqueda de parámetros para cada uno para encontrar el modelo “verdadero” más optimizado posible? ¿Por qué no? Mezcla una combinación de transformaciones de pipelines en la mezcla para divertirse y obtener ganancias. ¡Yasss!

Únete a nosotros la próxima vez cuando vayamos más allá de los conceptos básicos de configuración y los conjuntos de datos de juguetes.

Originalmente publicado en inglés en KDnuggets.

--

--

Matthew Mayo
Ciencia y Datos

I turn coffee into code in desperate need of refactoring, which I then refactor. #MachineLearning Researcher & Editor @kdnuggets #NeuralNetworks