Otimizar hiperparâmetros com Optuna

Concluído

O Optuna é uma biblioteca python de software livre para otimização de hiperparâmetro. O Optuna é amplamente usado para ajuste de hiperparâmetro eficiente e flexível. Para usá-lo ao treinar um modelo, execute as seguintes etapas:

  1. Defina uma função objetivo para treinar e avaliar um modelo.
  2. Crie um estudo optuna para gerenciar o processo de otimização.
  3. Execute a otimização optuna para pesquisar os melhores hiperparâmetros.

Definir uma função objetiva

O Optuna funciona chamando iterativamente uma função objetiva que retorna um valor numérico a ser minimizado, esse é o destino de otimização. Você precisa encapsular a lógica de treinamento e avaliação do modelo em uma função que:

  • Aceita um parâmetro (normalmente um trial objeto) usado para sugerir valores de hiperparâmetro.
  • Treina um modelo usando os valores de hiperparâmetro sugeridos.
  • Avalia o modelo com base em uma métrica de destino para desempenho preditivo.
  • Retorna um valor numérico que reflete a métrica de desempenho, de modo que melhorar o desempenho do modelo reduz o valor retornado.

Por exemplo, a função a seguir treina um modelo de machine learning usando o algoritmo LogisticRegression da biblioteca Spark MLlib, com hiperparâmetros sugeridos pela Optuna:

def objective(trial):
  from pyspark.ml.classification import LogisticRegression
  from pyspark.ml.evaluation import MulticlassClassificationEvaluator

  data_df = get_training_data()  # This is just an example!
  splits = data_df.randomSplit([0.7, 0.3])
  training_df = splits[0]
  validation_df = splits[1]

  # Suggest hyperparameters using Optuna's trial object
  max_iter = trial.suggest_int('Iterations', 1, 10)
  reg_param = trial.suggest_float('Regularization', 0.0, 1.0)

  # Train a model using the suggested hyperparameters
  lr = LogisticRegression(labelCol="label", featuresCol="features",
              maxIter=max_iter,
              regParam=reg_param)
  model = lr.fit(training_df)

  # Evaluate the model
  predictions = model.transform(validation_df)
  eval = MulticlassClassificationEvaluator(labelCol="label",
                       predictionCol="prediction",
                       metricName="accuracy")
  accuracy = eval.evaluate(predictions)

  # Optuna minimizes the objective, so return negative accuracy
  return -accuracy

Neste exemplo , o parâmetro de avaliação é um objeto Optuna usado para sugerir valores para os hiperparâmetros de iterações e regularização . Esses valores são atribuídos aos parâmetros maxIter e regParam do algoritmo de regressão logística. A função avalia a precisão do modelo treinado e retorna seu valor negativo, para que Optuna maximize a precisão minimizando o valor retornado.

Definir o espaço de pesquisa de hiperparâmetro

Cada vez que a função objetiva é chamada, ela exige um parâmetro que contenha os valores de hiperparâmetros a serem testados. Para explorar combinações de valores diferentes, você precisa definir um espaço de pesquisa para Optuna para amostrar durante cada avaliação.

O Optuna fornece métodos no trial objeto para sugerir valores para cada hiperparâmetro, incluindo:

  • trial.suggest_int(name, low, high): sugere um valor inteiro entre low e high (inclusivo).
  • trial.suggest_float(name, low, high): sugere um valor de ponto flutuante entre low e high.
  • trial.suggest_categorical(name, choices): sugere um valor de uma lista de opções categóricas.

Dica

Para obter a lista completa de métodos de sugestão, consulte a documentação do Optuna.

No exemplo anterior, o espaço de pesquisa é definido diretamente na objective função usando o trial objeto:

def objective(trial):
  max_iter = trial.suggest_int('Iterations', 1, 10)
  reg_param = trial.suggest_float('Regularization', 0.0, 1.0)
  # ... rest of the function ...

Essa abordagem permite ao Optuna amostrar dinamicamente valores de hiperparâmetro para cada avaliação, tornando o espaço de pesquisa flexível e fácil de modificar.

Especificar o algoritmo de pesquisa

O Optuna usa um sampler para selecionar valores de hiperparâmetro no espaço de pesquisa e otimizar a função objetiva. O exemplo mais usado é o TPE (Avaliador parzen) estruturado por árvore, que é um algoritmo de otimização bayesiana que seleciona adaptávelmente novas configurações de hiperparâmetro com base nos resultados anteriores.

Você pode especificar o sampler ao criar um estudo optuna. Por exemplo, para usar o sampler TPE:

import optuna

sampler = optuna.samplers.TPESampler()
study = optuna.create_study(direction="minimize", sampler=sampler)

O Optuna também dá suporte a outros samplers, como a pesquisa optuna.samplers.RandomSampleraleatória. Para a maioria dos casos de uso, o exemplo de TPE padrão é recomendado.

Executar a otimização do Optuna

Por fim, para executar a otimização, use o método study.optimize , que chama repetidamente a função objetiva usando combinações de hiperparâmetro do espaço de pesquisa com base no algoritmo de pesquisa. A meta é minimizar o valor retornado pela função objetiva (e, portanto, otimizar o desempenho do modelo).

O código de exemplo a seguir usa o método study.optimize para chamar a função objetiva definida anteriormente. A função é avaliada até 100 vezes antes que o estudo retorne a combinação de valor de parâmetro de melhor desempenho encontrada.

study.optimize(objective, n_trials=100)

print("Best param values: ", study.best_params)

A saída do código anterior é semelhante ao exemplo a seguir.

Best param values:  {'Iterations': 6, 'Regularization': 0.5461699702338606}