Los algoritmos de aprendizaje automático tienen hiperparámetros que permiten que los algoritmos se adapten a conjuntos de datos específicos.
Aunque el impacto de los hiperparámetros puede entenderse en general, es posible que no se conozca su efecto específico en un conjunto de datos y sus interacciones durante el aprendizaje. Por lo tanto, es importante ajustar los valores de los hiperparámetros del algoritmo como parte de un proyecto de aprendizaje automático.
Es común utilizar algoritmos de optimización ingenuos para ajustar hiperparámetros, como una búsqueda en cuadrícula y una búsqueda aleatoria. Un enfoque alternativo es utilizar un algoritmo de optimización estocástico, como un algoritmo estocástico de escalada de colinas.
En este tutorial, descubrirá cómo optimizar manualmente los hiperparámetros de los algoritmos de aprendizaje automático.
Después de completar este tutorial, sabrá:
- Se pueden usar algoritmos de optimización estocástica en lugar de la cuadrícula y la búsqueda aleatoria para la optimización de hiperparámetros.
- Cómo utilizar un algoritmo estocástico de escalada de colinas para ajustar los hiperparámetros del algoritmo Perceptron.
- Cómo optimizar manualmente los hiperparámetros del algoritmo de aumento de gradiente XGBoost.
Empecemos.
Descripción general del tutorial
Este tutorial se divide en tres partes; son:
- Optimización manual de hiperparámetros
- Optimización de hiperparámetros de Perceptron
- Optimización del hiperparámetro XGBoost
Optimización manual de hiperparámetros
Los modelos de aprendizaje automático tienen hiperparámetros que debe establecer para personalizar el modelo para su conjunto de datos.
A menudo, se conocen los efectos generales de los hiperparámetros en un modelo, pero la mejor forma de establecer un hiperparámetro y combinaciones de hiperparámetros que interactúan para un conjunto de datos dado es un desafío.
Un mejor enfoque es buscar objetivamente diferentes valores para los hiperparámetros del modelo y elegir un subconjunto que dé como resultado un modelo que logre el mejor rendimiento en un conjunto de datos determinado. Esto se denomina optimización de hiperparámetros o ajuste de hiperparámetros.
Se puede utilizar una variedad de algoritmos de optimización diferentes, aunque dos de los métodos más simples y comunes son la búsqueda aleatoria y la búsqueda en cuadrícula.
- Búsqueda aleatoria. Defina un espacio de búsqueda como un dominio limitado de valores de hiperparámetros y puntos de muestreo aleatorios en ese dominio.
- Búsqueda de cuadrícula. Defina un espacio de búsqueda como una cuadrícula de valores de hiperparámetros y evalúe cada posición en la cuadrícula.
La búsqueda en cuadrícula es ideal para combinaciones de verificación puntual que se sabe que funcionan bien en general. La búsqueda aleatoria es excelente para descubrir y obtener combinaciones de hiperparámetros que no habría adivinado intuitivamente, aunque a menudo requiere más tiempo para ejecutarse.
Para obtener más información sobre la cuadrícula y la búsqueda aleatoria para el ajuste de hiperparámetros, consulte el tutorial:
La búsqueda en cuadrícula y aleatoria son algoritmos de optimización primitivos, y es posible utilizar cualquier optimización que nos guste para ajustar el rendimiento de un algoritmo de aprendizaje automático. Por ejemplo, es posible utilizar algoritmos de optimización estocástica. Esto puede ser deseable cuando se requiere un rendimiento bueno o excelente y hay suficientes recursos disponibles para ajustar el modelo.
A continuación, veamos cómo podríamos usar un algoritmo estocástico de escalada de colinas para ajustar el rendimiento del algoritmo Perceptron.
Optimización de hiperparámetros de Perceptron
El algoritmo Perceptron es el tipo más simple de red neuronal artificial.
Es un modelo de una sola neurona que se puede utilizar para problemas de clasificación de dos clases y proporciona la base para el desarrollo posterior de redes mucho más grandes.
En esta sección, exploraremos cómo optimizar manualmente los hiperparámetros del modelo Perceptron.
Primero, definamos un problema de clasificación binaria sintética que podamos usar como foco de optimización del modelo.
Podemos usar la función make_classification () para definir un problema de clasificación binaria con 1,000 filas y cinco variables de entrada.
El siguiente ejemplo crea el conjunto de datos y resume la forma de los datos.
# definir un conjunto de datos de clasificación binaria desde sklearn.conjuntos de datos importar hacer_clasificación # definir conjunto de datos X, y = make_classification(n_samples=1000, n_features=5, n_informativo=2, n_redundante=1, estado_aleatorio=1) # resumir la forma del conjunto de datos imprimir(X.forma, y.forma) |
La ejecución del ejemplo imprime la forma del conjunto de datos creado, lo que confirma nuestras expectativas.
Scikit-learn proporciona una implementación del modelo Perceptron a través de la clase Perceptron.
Antes de ajustar los hiperparámetros del modelo, podemos establecer una línea de base en el rendimiento utilizando los hiperparámetros predeterminados.
Evaluaremos el modelo utilizando buenas prácticas de validación cruzada k-fold estratificada repetida a través de la clase RepeatedStratifiedKFold.
El ejemplo completo de evaluación del modelo Perceptron con hiperparámetros predeterminados en nuestro conjunto de datos de clasificación binaria sintética se enumera a continuación.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 dieciséis 17 |
# hiperparámetros predeterminados de perceptron para clasificación binaria desde numpy importar significar desde numpy importar std desde sklearn.conjuntos de datos importar make_classification desde sklearn.model_selection importar cross_val_score desde sklearn.model_selection importar Repetido Estratificado KFold desde sklearn.Modelo lineal importar Perceptrón # definir conjunto de datos X, y = make_classification(n_samples=1000, n_features=5, n_informativo=2, n_redundante=1, estado_aleatorio=1) # definir modelo modelo = Perceptrón() # definir el procedimiento de evaluación CV = Repetido Estratificado KFold(n_splits=10, n_repeats=3, estado_aleatorio=1) # evaluar modelo puntuaciones = cross_val_score(modelo, X, y, puntuación=‘precisión’, CV=CV, n_jobs=–1) # informe de resultado imprimir(‘Precisión media:% .3f (% .3f)’ % (significar(puntuaciones), std(puntuaciones))) |
La ejecución de los informes de ejemplo evalúa el modelo e informa la desviación estándar y media de la precisión de la clasificación.
Nota: Sus resultados pueden variar dada la naturaleza estocástica del algoritmo o procedimiento de evaluación, o las diferencias en la precisión numérica. Considere ejecutar el ejemplo varias veces y compare el resultado promedio.
En este caso, podemos ver que el modelo con hiperparámetros predeterminados logró una precisión de clasificación de alrededor del 78,5 por ciento.
Esperamos poder lograr un mejor rendimiento que este con hiperparámetros optimizados.
Precisión media: 0,786 (0,069) |
A continuación, podemos optimizar los hiperparámetros del modelo Perceptron utilizando un algoritmo estocástico de escalada de colinas.
Hay muchos hiperparámetros que podríamos optimizar, aunque nos centraremos en dos que quizás tengan el mayor impacto en el comportamiento de aprendizaje del modelo; son:
- Tasa de aprendizaje (eta0).
- Regularización (alfa).
La tasa de aprendizaje controla la cantidad de actualización del modelo en función de los errores de predicción y controla la velocidad de aprendizaje. El valor predeterminado de eta es 1.0. los valores razonables son mayores que cero (por ejemplo, mayores que 1e-8 o 1e-10) y probablemente menores que 1.0
Por defecto, el Perceptron no usa ninguna regularización, pero habilitaremos «red elástica”Regularización que aplica tanto la regularización L1 como la L2 durante el aprendizaje. Esto alentará al modelo a buscar pesos de modelo pequeños y, a su vez, a menudo un mejor rendimiento.
Afinaremos el «alfa«Hiperparámetro que controla la ponderación de la regularización, p. Ej. la cantidad que impacta el aprendizaje. Si se establece en 0.0, es como si no se estuviera usando ninguna regularización. Los valores razonables están entre 0.0 y 1.0.
Primero, necesitamos definir la función objetivo para el algoritmo de optimización. Evaluaremos una configuración utilizando la precisión de clasificación media con validación cruzada estratificada repetida de k-veces. Buscaremos maximizar la precisión en las configuraciones.
los objetivo() La función a continuación implementa esto, tomando el conjunto de datos y una lista de valores de configuración. Los valores de configuración (tasa de aprendizaje y ponderación de regularización) se descomprimen, se utilizan para configurar el modelo, que luego se evalúa y se devuelve la precisión media.
# función objetiva def objetivo(X, y, cfg): # descomprimir config eta, alfa = cfg # definir modelo modelo = Perceptrón(multa=‘red elástica’, alfa=alfa, eta0=eta) # definir el procedimiento de evaluación CV = Repetido Estratificado KFold(n_splits=10, n_repeats=3, estado_aleatorio=1) # evaluar modelo puntuaciones = cross_val_score(modelo, X, y, puntuación=‘precisión’, CV=CV, n_jobs=–1) # calcular la precisión media resultado = significar(puntuaciones) regreso resultado |
A continuación, necesitamos una función para dar un paso en el espacio de búsqueda.
El espacio de búsqueda está definido por dos variables (eta y alfa). Un paso en el espacio de búsqueda debe tener alguna relación con los valores anteriores y debe estar vinculado a valores sensibles (por ejemplo, entre 0 y 1).
Usaremos un «Numero de pie”Hiperparámetro que controla qué tan lejos se permite que el algoritmo se mueva de la configuración existente. Se elegirá una nueva configuración probabilísticamente utilizando una distribución gaussiana con el valor actual como la media de la distribución y el tamaño del paso como la desviación estándar de la distribución.
Podemos usar la función randn () NumPy para generar números aleatorios con una distribución gaussiana.
los paso() La función siguiente implementa esto y dará un paso en el espacio de búsqueda y generará una nueva configuración utilizando una configuración existente.
# dar un paso en el espacio de búsqueda def paso(cfg, Numero de pie): # desempaquetar la configuración eta, alfa = cfg # paso eta new_eta = eta + randn() * paso_Talla # comprobar los límites de eta si new_eta <= 0.0: new_eta = 1e–8 # paso alfa new_alpha = alfa + randn() * paso_Talla # comprobar los límites de alfa si new_alpha < 0.0: new_alpha = 0.0 # devuelve la nueva configuración regreso [[new_eta, new_alpha] |
A continuación, necesitamos implementar el algoritmo estocástico de escalada de colinas que llamará a nuestro objetivo() función para evaluar las soluciones candidatas y nuestra paso() función para dar un paso en el espacio de búsqueda.
La búsqueda genera primero una solución inicial aleatoria, en este caso con valores eta y alfa en el rango 0 y 1. La solución inicial se evalúa y se toma como la mejor solución de trabajo actual.
... # punto de partida de la búsqueda solución = [[rand(), rand()] # evaluar el punto inicial solution_eval = objetivo(X, y, solución) |
A continuación, el algoritmo itera para un número fijo de iteraciones proporcionado como un hiperparámetro para la búsqueda. Cada iteración implica dar un paso y evaluar la nueva solución candidata.
... # Da un paso candidato = paso(solución, Numero de pie) # evaluar el punto candidato candidte_eval = objetivo(X, y, candidato) |
Si la nueva solución es mejor que la solución de trabajo actual, se toma como la nueva solución de trabajo actual.
... # comprobar si debemos mantener el nuevo punto si candidte_eval > = solution_eval: # almacenar el nuevo punto solución, solution_eval = candidato, sincero_eval # informe de progreso imprimir(‘>% d, cfg =% s% .5f’ % (I, solución, solution_eval)) |
Al final de la búsqueda, se devuelve la mejor solución y su rendimiento.
Uniendo esto, el Montañismo() La función siguiente implementa el algoritmo estocástico de escalada de colinas para ajustar el algoritmo Perceptron, tomando el conjunto de datos, la función objetivo, el número de iteraciones y el tamaño del paso como argumentos.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 dieciséis 17 18 19 |
# algoritmo de búsqueda local de escalada def Montañismo(X, y, objetivo, nitro, Numero de pie): # punto de partida de la búsqueda solución = [[rand(), rand()] # evaluar el punto inicial solution_eval = objetivo(X, y, solución) # corre la subida de la colina por I en abarcar(nitro): # Da un paso candidato = paso(solución, Numero de pie) # evaluar el punto candidato candidte_eval = objetivo(X, y, candidato) # comprobar si debemos mantener el nuevo punto si candidte_eval > = solution_eval: # almacenar el nuevo punto solución, solution_eval = candidato, sincero_eval # informe de progreso imprimir(‘>% d, cfg =% s% .5f’ % (I, solución, solution_eval)) regreso [[solución, solution_eval] |
Luego podemos llamar al algoritmo e informar los resultados de la búsqueda.
En este caso, ejecutaremos el algoritmo durante 100 iteraciones y usaremos un tamaño de paso de 0.1, elegido después de un poco de prueba y error.
... # definir las iteraciones totales nitro = 100 # tamaño de paso en el espacio de búsqueda Numero de pie = 0,1 # realizar la búsqueda de escalada cfg, puntaje = Montañismo(X, y, objetivo, nitro, Numero de pie) imprimir(‘¡Hecho!’) imprimir(‘cfg =% s: Precisión media:% f’ % (cfg, puntaje)) |
Al unir esto, el ejemplo completo de sintonización manual del algoritmo Perceptron se enumera a continuación.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 dieciséis 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 sesenta y cinco 66 67 68 69 70 |
# buscar manualmente hiperparámetros de perceptrón para la clasificación binaria desde numpy importar significar desde numpy.aleatorio importar randn desde numpy.aleatorio importar rand desde sklearn.conjuntos de datos importar make_classification desde sklearn.model_selection importar cross_val_score desde sklearn.model_selection importar Repetido Estratificado KFold desde sklearn.Modelo lineal importar Perceptrón # función objetiva def objetivo(X, y, cfg): # descomprimir config eta, alfa = cfg # definir modelo modelo = Perceptrón(multa=‘red elástica’, alfa=alfa, eta0=eta) # definir el procedimiento de evaluación CV = Repetido Estratificado KFold(n_splits=10, n_repeats=3, estado_aleatorio=1) # evaluar modelo puntuaciones = cross_val_score(modelo, X, y, puntuación=‘precisión’, CV=CV, n_jobs=–1) # calcular la precisión media resultado = significar(puntuaciones) regreso resultado # dar un paso en el espacio de búsqueda def paso(cfg, Numero de pie): # desempaquetar la configuración eta, alfa = cfg # paso eta new_eta = eta + randn() * paso_Talla # comprobar los límites de eta si new_eta <= 0.0: new_eta = 1e–8 # paso alfa new_alpha = alfa + randn() * paso_Talla # comprobar los límites de alfa si new_alpha < 0.0: new_alpha = 0.0 # devuelve la nueva configuración regreso [[new_eta, new_alpha] # algoritmo de búsqueda local de escalada def Montañismo(X, y, objetivo, nitro, Numero de pie): # punto de partida de la búsqueda solución = [[rand(), rand()] # evaluar el punto inicial solution_eval = objetivo(X, y, solución) # corre la subida de la colina por I en abarcar(nitro): # Da un paso candidato = paso(solución, Numero de pie) # evaluar el punto candidato candidte_eval = objetivo(X, y, candidato) # comprobar si debemos mantener el nuevo punto si candidte_eval > = solution_eval: # almacenar el nuevo punto solución, solution_eval = candidato, sincero_eval # informe de progreso imprimir(‘>% d, cfg =% s% .5f’ % (I, solución, solution_eval)) regreso [[solución, solution_eval] # definir conjunto de datos X, y = make_classification(n_samples=1000, n_features=5, n_informativo=2, n_redundante=1, estado_aleatorio=1) # definir las iteraciones totales nitro = 100 # tamaño de paso en el espacio de búsqueda Numero de pie = 0,1 # realizar la búsqueda de escalada cfg, puntaje = Montañismo(X, y, objetivo, nitro, Numero de pie) imprimir(‘¡Hecho!’) imprimir(‘cfg =% s: Precisión media:% f’ % (cfg, puntaje)) |
La ejecución del ejemplo informa la configuración y el resultado cada vez que se observa una mejora durante la búsqueda. Al final de la ejecución, se informa la mejor configuración y resultado.
Nota: Sus resultados pueden variar dada la naturaleza estocástica del algoritmo o procedimiento de evaluación, o las diferencias en la precisión numérica. Considere ejecutar el ejemplo varias veces y compare el resultado promedio.
En este caso, podemos ver que el mejor resultado implicó usar una tasa de aprendizaje ligeramente superior a 1 en 1.004 y un peso de regularización de aproximadamente 0.002 logrando una precisión media de aproximadamente 79.1 por ciento, mejor que la configuración predeterminada que logró una precisión de aproximadamente 78.5 por ciento. .
¿Puede obtener un mejor resultado?
Déjame saber abajo en los comentarios.
> 0, cfg =[0.5827274503894747, 0.260872709578015] 0,70533 > 4, cfg =[0.5449820307807399, 0.3017271170801444] 0,70567 > 6, cfg =[0.6286475606495414, 0.17499090243915086] 0,71933 > 7, cfg =[0.5956196828965779, 0.0] 0,78633 > 8, cfg =[0.5878361167354715, 0.0] 0,78633 > 10, cfg =[0.6353507984485595, 0.0] 0,78633 > 13, cfg =[0.5690530537610675, 0.0] 0,78633 > 17, cfg =[0.6650936023999641, 0.0] 0,78633 > 22, cfg =[0.9070451625704087, 0.0] 0,78633 > 23, cfg =[0.9253366187387938, 0.0] 0,78633 > 26, cfg =[0.9966143540220266, 0.0] 0,78633 > 31, cfg =[1.0048613895650054, 0.002162219228449132] 0,79133 ¡Hecho! cfg =[1.0048613895650054, 0.002162219228449132]: Precisión media: 0,791333 |
Ahora que estamos familiarizados con cómo utilizar un algoritmo de escalada estocástico para ajustar los hiperparámetros de un algoritmo de aprendizaje automático simple, veamos cómo ajustar un algoritmo más avanzado, como XGBoost.
Optimización del hiperparámetro XGBoost
XGBoost es la abreviatura de Extreme Gradient Boosting y es una implementación eficiente del algoritmo de aprendizaje automático de aumento de gradiente estocástico.
El algoritmo de aumento de gradiente estocástico, también llamado máquinas de aumento de gradiente o aumento de árbol, es una poderosa técnica de aprendizaje automático que funciona bien o incluso mejor en una amplia gama de problemas desafiantes de aprendizaje automático.
Primero, se debe instalar la biblioteca XGBoost.
Puede instalarlo usando pip, de la siguiente manera:
Una vez instalado, puede confirmar que se instaló correctamente y que está utilizando una versión moderna ejecutando el siguiente código:
# xgboost importar xgboost imprimir(«xgboost», xgboost.__versión__) |
Al ejecutar el código, debería ver el siguiente número de versión o superior.
Aunque la biblioteca XGBoost tiene su propia API Python, podemos usar modelos XGBoost con la API scikit-learn a través de la clase contenedora XGBClassifier.
An instance of the model can be instantiated and used just like any other scikit-learn class for model evaluation. Por ejemplo:
... # define model model = XGBClassifier() |
Before we tune the hyperparameters of XGBoost, we can establish a baseline in performance using the default hyperparameters.
We will use the same synthetic binary classification dataset from the previous section and the same test harness of repeated stratified k-fold cross-validation.
The complete example of evaluating the performance of XGBoost with default hyperparameters is listed below.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 dieciséis 17 |
# xgboost with default hyperparameters for binary classification desde numpy import mean desde numpy import std desde sklearn.datasets import make_classification desde sklearn.model_selection import cross_val_score desde sklearn.model_selection import RepeatedStratifiedKFold desde xgboost import XGBClassifier # define dataset X, y = make_classification(n_samples=1000, n_features=5, n_informative=2, n_redundant=1, random_state=1) # define model model = XGBClassifier() # define evaluation procedure cv = RepeatedStratifiedKFold(n_splits=10, n_repeats=3, random_state=1) # evaluate model scores = cross_val_score(model, X, y, scoring=‘accuracy’, cv=cv, n_jobs=–1) # report result print(‘Mean Accuracy: %.3f (%.3f)’ % (mean(scores), std(scores))) |
Running the example evaluates the model and reports the mean and standard deviation of the classification accuracy.
Nota: Your results may vary given the stochastic nature of the algorithm or evaluation procedure, or differences in numerical precision. Consider running the example a few times and compare the average outcome.
In this case, we can see that the model with default hyperparameters achieved a classification accuracy of about 84.9 percent.
We would hope that we can achieve better performance than this with optimized hyperparameters.
Mean Accuracy: 0.849 (0.040) |
Next, we can adapt the stochastic hill climbing optimization algorithm to tune the hyperparameters of the XGBoost model.
There are many hyperparameters that we may want to optimize for the XGBoost model.
For an overview of how to tune the XGBoost model, see the tutorial:
We will focus on four key hyperparameters; they are:
- Learning Rate (learning_rate)
- Number of Trees (n_estimators)
- Subsample Percentage (subsample)
- Tree Depth (max_depth)
los learning rate controls the contribution of each tree to the ensemble. Sensible values are less than 1.0 and slightly above 0.0 (e.g. 1e-8).
los number of trees controls the size of the ensemble, and often, more trees is better to a point of diminishing returns. Sensible values are between 1 tree and hundreds or thousands of trees.
los subsample percentages define the random sample size used to train each tree, defined as a percentage of the size of the original dataset. Values are between a value slightly above 0.0 (e.g. 1e-8) and 1.0
los tree depth is the number of levels in each tree. Deeper trees are more specific to the training dataset and perhaps overfit. Shorter trees often generalize better. Sensible values are between 1 and 10 or 20.
First, we must update the objective() function to unpack the hyperparameters of the XGBoost model, configure it, and then evaluate the mean classification accuracy.
# objective function def objective(X, y, cfg): # unpack config lrate, n_tree, subsam, depth = cfg # define model model = XGBClassifier(learning_rate=lrate, n_estimators=n_tree, subsample=subsam, max_depth=depth) # define evaluation procedure cv = RepeatedStratifiedKFold(n_splits=10, n_repeats=3, random_state=1) # evaluate model scores = cross_val_score(model, X, y, scoring=‘accuracy’, cv=cv, n_jobs=–1) # calculate mean accuracy result = mean(scores) return result |
Next, we need to define the step() function used to take a step in the search space.
Each hyperparameter is quite a different range, therefore, we will define the step size (standard deviation of the distribution) separately for each hyperparameter. We will also define the step sizes in line rather than as arguments to the function, to keep things simple.
The number of trees and the depth are integers, so the stepped values are rounded.
The step sizes chosen are arbitrary, chosen after a little trial and error.
The updated step function is listed below.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 dieciséis 17 18 19 20 21 22 23 24 25 26 |
# take a step in the search space def step(cfg): # unpack config lrate, n_tree, subsam, depth = cfg # learning rate lrate = lrate + randn() * 0.01 si lrate <= 0.0: lrate = 1e–8 si lrate > 1: lrate = 1.0 # number of trees n_tree = round(n_tree + randn() * 50) si n_tree <= 0.0: n_tree = 1 # subsample percentage subsam = subsam + randn() * 0.1 si subsam <= 0.0: subsam = 1e–8 si subsam > 1: subsam = 1.0 # max tree depth depth = round(depth + randn() * 7) si depth <= 1: depth = 1 # return new config return [[lrate, n_tree, subsam, depth] |
Finally, the hillclimbing() algorithm must be updated to define an initial solution with appropriate values.
In this case, we will define the initial solution with sensible defaults, matching the default hyperparameters, or close to them.
... # starting point for the search solution = step([[0.1, 100, 1.0, 7]) |
Tying this together, the complete example of manually tuning the hyperparameters of the XGBoost algorithm using a stochastic hill climbing algorithm is listed below.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 dieciséis 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 sesenta y cinco 66 67 68 69 70 71 72 73 74 75 76 77 78 79 |
# xgboost manual hyperparameter optimization for binary classification desde numpy import mean desde numpy.aleatorio import randn desde numpy.aleatorio import rand desde numpy.aleatorio import randint desde sklearn.datasets import make_classification desde sklearn.model_selection import cross_val_score desde sklearn.model_selection import RepeatedStratifiedKFold desde xgboost import XGBClassifier # objective function def objective(X, y, cfg): # unpack config lrate, n_tree, subsam, depth = cfg # define model model = XGBClassifier(learning_rate=lrate, n_estimators=n_tree, subsample=subsam, max_depth=depth) # define evaluation procedure cv = RepeatedStratifiedKFold(n_splits=10, n_repeats=3, random_state=1) # evaluate model scores = cross_val_score(model, X, y, scoring=‘accuracy’, cv=cv, n_jobs=–1) # calculate mean accuracy result = mean(scores) return result # take a step in the search space def step(cfg): # unpack config lrate, n_tree, subsam, depth = cfg # learning rate lrate = lrate + randn() * 0.01 si lrate <= 0.0: lrate = 1e–8 si lrate > 1: lrate = 1.0 # number of trees n_tree = round(n_tree + randn() * 50) si n_tree <= 0.0: n_tree = 1 # subsample percentage subsam = subsam + randn() * 0.1 si subsam <= 0.0: subsam = 1e–8 si subsam > 1: subsam = 1.0 # max tree depth depth = round(depth + randn() * 7) si depth <= 1: depth = 1 # return new config return [[lrate, n_tree, subsam, depth] # hill climbing local search algorithm def hillclimbing(X, y, objective, n_iter): # starting point for the search solution = step([[0.1, 100, 1.0, 7]) # evaluate the initial point solution_eval = objective(X, y, solution) # run the hill climb por I en range(n_iter): # take a step candidate = step(solution) # evaluate candidate point candidte_eval = objective(X, y, candidate) # check if we should keep the new point si candidte_eval >= solution_eval: # store the new point solution, solution_eval = candidate, candidte_eval # report progress print(‘>%d, cfg=[%s] %.5f’ % (I, solution, solution_eval)) return [[solution, solution_eval] # define dataset X, y = make_classification(n_samples=1000, n_features=5, n_informative=2, n_redundant=1, random_state=1) # define the total iterations n_iter = 200 # perform the hill climbing search cfg, score = hillclimbing(X, y, objective, n_iter) print(‘Done!’) print(‘cfg=[%s]: Mean Accuracy: %f’ % (cfg, score)) |
Running the example reports the configuration and result each time an improvement is seen during the search. At the end of the run, the best configuration and result are reported.
Nota: Your results may vary given the stochastic nature of the algorithm or evaluation procedure, or differences in numerical precision. Consider running the example a few times and compare the average outcome.
In this case, we can see that the best result involved using a learning rate of about 0.02, 52 trees, a subsample rate of about 50 percent, and a large depth of 53 levels.
This configuration resulted in a mean accuracy of about 87.3 percent, better than the default configuration that achieved an accuracy of about 84.9 percent.
Can you get a better result?
Let me know in the comments below.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 dieciséis 17 18 19 |
>0, cfg=[[0.1058242692126418, 67, 0.9228490731610172, 12]]0.85933 >1, cfg=[[0.11060813799692253, 51, 0.859353656735739, 13]]0.86100 >4, cfg=[[0.11890247679234153, 58, 0.7135275461723894, 12]]0.86167 >5, cfg=[[0.10226257987735601, 61, 0.6086462443373852, 17]]0.86400 >15, cfg=[[0.11176962034280596, 106, 0.5592742266405146, 13]]0.86500 >19, cfg=[[0.09493587069112454, 153, 0.5049124222437619, 34]]0.86533 >23, cfg=[[0.08516531024154426, 88, 0.5895201311518876, 31]]0.86733 >46, cfg=[[0.10092590898175327, 32, 0.5982811365027455, 30]]0.86867 >75, cfg=[[0.099469211050998, 20, 0.36372573610040404, 32]]0.86900 >96, cfg=[[0.09021536590375884, 38, 0.4725379807796971, 20]]0.86900 >100, cfg=[[0.08979482274655906, 65, 0.3697395430835758, 14]]0.87000 >110, cfg=[[0.06792737273465625, 89, 0.33827505722318224, 17]]0.87000 >118, cfg=[[0.05544969684589669, 72, 0.2989721608535262, 23]]0.87200 >122, cfg=[[0.050102976159097, 128, 0.2043203965148931, 24]]0.87200 >123, cfg=[[0.031493266763680444, 120, 0.2998819062922256, 30]]0.87333 >128, cfg=[[0.023324201169625292, 84, 0.4017169945431015, 42]]0.87333 >140, cfg=[[0.020224220443108752, 52, 0.5088096815056933, 53]]0.87367 Done! cfg=[[0.020224220443108752, 52, 0.5088096815056933, 53]]: Mean Accuracy: 0.873667 |
Otras lecturas
This section provides more resources on the topic if you are looking to go deeper.
Tutorials
APIs
Articles
Resumen
In this tutorial, you discovered how to manually optimize the hyperparameters of machine learning algorithms.
Specifically, you learned:
- Stochastic optimization algorithms can be used instead of grid and random search for hyperparameter optimization.
- How to use a stochastic hill climbing algorithm to tune the hyperparameters of the Perceptron algorithm.
- How to manually optimize the hyperparameters of the XGBoost gradient boosting algorithm.
Do you have any questions?
Ask your questions in the comments below and I will do my best to answer.