Otimizar hiperparâmetros com o Hyperopt
O Hyperopt é uma biblioteca de código aberto do Python para ajuste de hiperparâmetros. O Hyperopt é instalado automaticamente quando você cria um cluster com uma variante de ML do Databricks Runtime. Para usá-lo ao treinar um modelo, execute as seguintes etapas:
- Defina uma função objetivo para treinar e avaliar um modelo.
- Defina o espaço de pesquisa do hiperparâmetro.
- Especifique o algoritmo de pesquisa.
- Execute a função fmin do Hyperopt para otimizar a função de treinamento.
Definir uma função objetiva
O Hyperopt funciona chamando iterativamente uma função (geralmente chamada de função objetiva) que retorna um valor numérico e ajustando os parâmetros passados para a função para que o valor retornado seja minimizado; uma abordagem normalmente conhecida como otimização. Portanto, o primeiro requisito é encapsular a lógica de treinamento e avaliação do modelo em uma função que:
- Aceita um parâmetro que contém uma lista de valores de hiperparâmetros.
- Treina um modelo usando os valores de hiperparâmetros fornecidos.
- 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 a melhora do desempenho do modelo reduza o valor retornado.
Por exemplo, a função a seguir treina um modelo de aprendizado de máquina usando o algoritmo LogisticRegression da biblioteca MLlib do Spark.
def objective(params):
from pyspark.ml.classification import LogisticRegression
from pyspark.ml.evaluation import MulticlassClassificationEvaluator
from hyperopt import STATUS_OK
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]
# Train a model using the provided hyperparameter values
lr = LogisticRegression(labelCol="label", featuresCol="features",
maxIter=params['Iterations'],
regParam=params['Regularization'])
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)
# Hyperopt *minimizes* the function, so return *negative* accuracy.
return {'loss': -accuracy, 'status': STATUS_OK}
Neste exemplo, o parâmetro params é um dicionário que contém valores para dois valores nomeados: Iterações e Regularização. Esses valores são atribuídos aos hiperparâmetros maxIter e regParam do algoritmo de regressão logística usado para treinar o modelo.
Em seguida, a função avalia o modelo treinado para calcular a métrica de precisão dele, que é um valor entre 0,0 e 1,0 que indica a proporção de previsões feitas pelo modelo que estavam corretas.
Por fim, a função retorna um valor que o Hyperopt deve minimizar a fim de aprimorar o modelo. Nesse caso, a métrica de destino é a precisão, em que valores mais altos indicam modelos melhores; portanto, a função retorna o negativo desse valor (portanto, quanto maior a precisão, menor 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 experimentar todas as combinações de valores possíveis, você precisa definir um espaço de pesquisa para o Hyperopt para selecionar valores de cada avaliação.
O Hyperopt fornece expressões que podem ser usadas para definir um intervalo de valores para cada hiperparâmetro, incluindo:
hp.choice(label, options)
: retorna um dosoptions
que você listou.hp.randint(label, upper)
: retorna um inteiro aleatório no intervalo [0, upper].hp.uniform(label, low, high)
: retorna um valor uniforme entrelow
ehigh
.hp.normal(label, mu, sigma)
: retorna um valor real que normalmente é distribuído com médiamu
e desvio padrãosigma
.
Dica
Para obter a lista completa de expressões, confira a Documentação do Hyperopt.
O seguinte código de exemplo define um espaço de pesquisa para os hiperparâmetros usados no exemplo anterior:
from hyperopt import hp
search_space = {
'Iterations': hp.randint('Iterations', 10),
'Regularization': hp.uniform('Regularization', 0.0, 1.0)
}
Especificar o algoritmo de pesquisa
O Hyperopt usa um algoritmo de pesquisa para selecionar valores de hiperparâmetros no espaço de pesquisa e tentar otimizar a função objetiva. Há duas opções principais de como a Hyperopt é amostrada no espaço de pesquisa:
hyperopt.tpe.suggest
: TPE (Árvore de Avaliadores de Parzen), uma abordagem bayesiana que seleciona de maneira adaptativa novas configurações de hiperparâmetros com base em resultados anteriores.hyperopt.rand.suggest
: pesquisa aleatória, uma abordagem não adaptativa que obtém amostras aleatoriamente no espaço de pesquisa.
O código de exemplo a seguir especifica o algoritmo TPE.
from hyperopt import tpe
algo = tpe.suggest
Execute a função fmin do Hyperopt
Por fim, para executar uma execução do Hyperopt, você pode usar a função fmin, que chama repetidamente a função objetiva usando combinações de hiperparâmetros do espaço de pesquisa com base no algoritmo de pesquisa. O objetivo da função fmin é minimizar o valor retornado pela função objetiva (e, portanto, otimizar o desempenho do modelo).
O código de exemplo a seguir usa a função fmin para chamar a função objetiva definida anteriormente. O espaço de pesquisa e o algoritmo definidos em exemplos anteriores são usados e a função é avaliada até 100 vezes antes que a função fmin retorna a combinação de valor de parâmetro de melhor desempenho encontrada.
from hyperopt import fmin
argmin = fmin(
fn=objective,
space=search_space,
algo=algo,
max_evals=100)
print("Best param values: ", argmin)
A saída do código anterior é semelhante ao exemplo a seguir.
Best param values: {'Iterations': 6, 'Regularization': 0.5461699702338606}