• Skip to primary navigation
  • Skip to main content
  • Skip to primary sidebar

The Machine Learners

Descubriendo la IA

  • Inicio
  • Libros ML
  • Contacto
  • Sobre Nosotros

Optuna: ¿El futuro de la búsqueda de hiperparámetros?

Descubre y aprende a usar la librería Optuna, la manera más eficiente de tunear hiperparámetros de nuestro modelo de Machine Learning.

Optuna hiperparámetros
Optuna

Índice

  • 1 ¿En que consiste la búsqueda de hiperparámetros?
  • 2 Introducción a la optimización de hiperparámetros
  • 3 Búsqueda de hiperparámetros con Optuna – Regresión Logística
    • 3.1 Introducción
    • 3.2 Definición del objetivo y del estudio
    • 3.3 Análisis de resultados
  • 4 Optuna. Árbol de decisión
    • 4.1 Definición del objetivo y del estudio
    • 4.2 Visualización de los estudios

¿En que consiste la búsqueda de hiperparámetros?

A la hora de diseñar modelos de Machine Learning, la optimización del modelo es siempre un tema muy importante. Es un proceso en general muy tedioso y que se suele dejar muy al final del ciclo de producción por la cantidad de tiempo que requiere. Si este tema os pilla un poco fuera de lugar, os recomendamos este otro post en el que hablamos del tema en mayor detalle.

Encuentra tu modelo perfecto (Búsqueda de hiperparámetros)

Estos procesos en realidad no son más que escoger una serie de valores para cada hiperparámetro, realizar las combinaciones posibles y empezar a probar distintos valores. Algunos métodos realizan una búsqueda exhaustiva y otros eligen solo ciertos elementos del espacio de búsqueda. Son métodos muy efectivos y que en general nos permiten obtener los hiperparámetros óptimos (cuasi óptimos).

Sin embargo, para modelos muy complejos o con unos datos de un tamaño inusual, se convierte en un proceso que puede durar fácilmente unas cuantas horas sino se tiene una capacidad de computación decente. Algunos modelos como los XGBoost tienen una elevadísima cantidad de hiperparámetros. Dependiendo de la complejidad de los datos y del problema a resolver, la optimización de estos hiperparámetros se podría eternizar…

XGBoost, el algoritmo que lo peta en las competiciones de Kaggle

Entonces… ¿Existe alguna alternativa?¿O estamos resignados a necesitar tal cantidad de tiempo para encontrar el modelo óptimo?

Afortunadamente, existen un montón de mentes maravillosas que se han dado cuenta de este problema y han ideado diversas propuestas para resolverlo.

Introducción a la optimización de hiperparámetros

En el post de hoy hablaremos de la optimización de hiperparámetros avanzada. 

Estos métodos de optimización de hiperparámetros se basan en redes bayesianas. No nos vamos a marear demasiado con la parte teórica que tienen por detrás pero básicamente la idea es definir un modelo probabilístico donde la función objetivo es la métrica que se utiliza como evaluación del modelo. El algoritmo va orientando la búsqueda óptima del hiperparámetro en función de los resultados obtenidos logrando una rápida convergencia hacia los valores óptimos.

Sin ahondar más en detalles, las tres librerías más utilizadas de optimización de hiperparámetros son las siguientes:

  • Hyperopt
  • Optuna
  • Scikit Optimize

En este post nos centraremos en Optuna por su simplicidad y su potencial. Para su instalación basta con instalarlo mediante nuestro gestor de dependencias (pip install optuna)

Búsqueda de hiperparámetros con Optuna – Regresión Logística

Introducción

Supongamos que nuestro objetivo es tratar de afinar el comportamiento de una regresión logística. Los parámetros con los que jugaremos serán las iteraciones máximas antes de converger y la regularización aplicada. Si quieres conocer más en detalle cómo funciona la regresión logística te invito a leer este post. 

¿En qué consiste la regresión logística? ¿Qué es la regularización?

En primer lugar importamos las librerías :

import pandas as pd
import numpy as np
from sklearn import datasets
from sklearn.model_selection import train_test_split

from matplotlib import pyplot as plt
from sklearn.linear_model import LogisticRegression
from sklearn.tree import DecisionTreeClassifier

from sklearn.model_selection import cross_val_score,RepeatedStratifiedKFold,StratifiedKFold
from sklearn.metrics import classification_report, confusion_matrix
import xgboost as xgb
from collections import Counter


import optuna
from optuna.samplers import TPESampler
from sklearn.datasets import make_classification

Como conjunto de datos vamos a utilizar los que nos proporciona sklearn con load_boston pero con una pequeña modificación para utilizarlos como clasificación.

data = datasets.load_boston()
X = data.data
y_cont = data.target
y=[2 if i <19  else 1 if i<24 else 0 for i in y_cont ]

Creamos un modelo de regresión logística sin optimizar para tener un marco de referencia sobre el que trabajar.Observamos que nos da una accuracy bastante decente de 0.71-0.72 tanto en training como en test.

Definición del objetivo y del estudio

Vale, es hora de meterse de lleno con Optuna. A la hora de utilizar esta librería, siempre tenemos que definir 3 componentes principales :

  • El objetivo. En esta sección se indica cual es el objetivo de la optimización y qué parámetros se utilizarán en dicha optimización. Esta función deberá devolver un valor objetivo o score, que podrá ser la métrica que deseemos. Dentro del estudio se definen los parámetros a evaluar dentro de la red. En este caso C, definido en un rango de valores de distribución logistica y el parámetro l1_ratio, con un rango de valores de distribución uniforme.
def objective(trial):
    # Define the search space
    

    c_space=trial.suggest_loguniform('C',10e-1, 100)
    l1_rat_space=trial.suggest_uniform('l1_ratio',0.1, 1)
    


    clf =LogisticRegression(max_iter = 4000,penalty='elasticnet',solver='saga',
                            random_state=2,C=c_space,l1_ratio=l1_rat_space)

    
    score = cross_val_score(clf, X_train, y_train, scoring='accuracy',
                            cv=4).mean()

    return score
  • El estudio. Se crea el estudio asignándole un nombre , una dirección de optimización y el algoritmo a utilizar como sampler. La dirección de optimización dependerá de la métrica utilizada. Si se utilizan métricas como la accuracy  o el valor AUC, se querrá maximizar. Si por el contrario se utilizan medidas de error como el rmse o el logloss, queremos minimizar la función objetivo. El algoritmo a utilizar dependerá de la aproximación teórica que se le quiera dar. El sampler por defecto es el BaseSampler pero a mi particularmente me gusta usar el TPESampler ya que su estructura similar a un árbol mejora su rendimiento.
study_rl = optuna.create_study(study_name="rlog_artif",
                            direction="maximize",
                              pruner=optuna.pruners.HyperbandPruner(max_resource="auto"),
                            sampler=TPESampler())
  • Optimización. Utilizando el estudio y el objetivo definidos, se procede a realizar la optimización. En esta sección también se podrá acotar el estudio indicando cuántas iteraciones realizar o incluso limitando el tiempo de ejecución.
study_rl.optimize(objective, n_trials=50)

Análisis de resultados

En la salida de la consola (o del notebook) podemos ir viendo las ejecuciones de nuestro modelo.

Cuando termina, podemos acceder a los parámetros óptimos de la optimización y el valor de accuracy conseguido. 

Observamos que los parámetros seleccionados como ganadores son :

modelo_1=LogisticRegression(C=9.478273641313464,l1_ratio=0.9131139036576349,penalty='elasticnet',solver='saga')
modelo_1.fit(X_train,y_train)
modelo_1.score(X_test,y_test)

Y que la accuracy obtenida es de 0.74. Podemos observar A simple vista parece que nuestro modelo no ha mejorado mucho… ¿Puede ser porque la regresión logística ya no da más de si? Probemos con un árbol de decisión.

Optuna. Árbol de decisión

baseline2=DecisionTreeClassifier(random_state=2)
baseline2.fit(X_train,y_train)
baseline2.score(X_test,y_test)

En este caso el baseline nos da ya una accuracy de 0.74. Vayamos con Optuna a ver si podemos exprimirlo más.

Al igual que antes, lanzamos las tres partes.

Definición del objetivo y del estudio

start_time = time.time()
def objective(trial):
    # Define the search space
    

    max_depth = trial.suggest_int('max_depth', 5, X_train.shape[1])
    min_samples_split = trial.suggest_int('min_samples_split', 2, 20)
    min_samples_leaf = trial.suggest_int('min_samples_leaf', 2, 20)
    min_impurity_decrease  = trial.suggest_float('min_impurity_decrease', 0, 1)

    
    model = DecisionTreeClassifier(random_state=2,
        max_depth=max_depth, min_samples_split=min_samples_split, min_samples_leaf=min_samples_leaf,
                                   min_impurity_decrease=min_impurity_decrease
      )

    
    score = cross_val_score(model, X_train, y_train, scoring='accuracy',
                            cv=4).mean()

    return score

study_DT = optuna.create_study(study_name="dectree_artf",
                            direction="maximize",
                            sampler=TPESampler())
study_DT.optimize(objective, n_trials=1000)
print("--- {} minutos para el tuneo---".format((time.time() - start_time)/60))
modelo2=DecisionTreeClassifier(max_depth=5,min_samples_split=12,min_samples_leaf=3
                               ,min_impurity_decrease=0.0007123522700617675)
modelo2.fit(X_train,y_train)
modelo2.score(X_test,y_test)

En este caso, conseguimos subir la accuracy hasta un 0.78.

Visualización de los estudios

Otro de los grandes potenciales que tiene esta librería, aparte de la optimización de los parámetros , es la visualización de los resultados.Con plot_optimization_history podemos observar la evolución de nuestra optimización.

Visualización de hiperparámetros con Optuna

Con el parámetro plot_param_importances también se puede ver el impacto de cada parámetro en la función objetivo, algo fundamental para posteriores análisis.

Es una maravilla que nos facilita el proceso muchísimo…

¿Y tú a que esperas para usarlo? Cuéntanos que te parece en los comentarios!

  • Estructuras de Datos en Python
  • Variables en Python: Todo lo que necesitas saber
  • Mejor editor de código para Python
  • Instala Anaconda para tus proyectos de Data Science

Reader Interactions

Deja una respuesta Cancelar la respuesta

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *

Primary Sidebar

Suscríbete

Síguenos en Medium.

Entradas Recientes

  • Qué es Python – El lenguaje de la ciencia de datos
  • Cómo evitar la maldición de la dimensionalidad utilizando T-SNE
  • Aprende a utilizar OCR con Amazon Textract
  • Cómo extraer datos de Instagram usando técnicas de Web scrapping
  • Introducción a las series temporales (2): modelo ARIMA con R

Copyright © 2022 The Machine Learners