Otimize os hiperparâmetros com o Hyperopt
Hyperopt é uma biblioteca Python de código aberto 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, siga estas etapas:
- Definir uma função objetiva para treinar e avaliar um modelo.
- Definir o espaço de pesquisa do hiperparâmetro.
- Especificar o algoritmo de pesquisa.
- Execute a função Hyperopt fmin para otimizar a função de treinamento.
Definir uma função objetiva
A hiperoptia funciona chamando iterativamente uma função (muitas vezes referida como a função objetiva) que retorna um valor numérico e ajustando os parâmetros passados para a função para que o valor de retorno seja minimizado, uma abordagem comumente referida como otimização. O primeiro requisito, portanto, é encapsular sua 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âmetro.
- 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 forma que melhorar o desempenho do modelo reduza o valor de retorno.
Por exemplo, a função a seguir treina um modelo de aprendizado de máquina usando o algoritmo LogisticRegression da biblioteca Spark MLlib.
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 é uma lista 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.
A função então avalia o modelo treinado para calcular sua métrica de precisão , que é um valor entre 0,0 e 1,0 indicando a proporção de previsões que o modelo fez que estavam corretas.
Finalmente, a função retorna um valor que a Hyperopt deve minimizar para melhorar o modelo. Neste caso, a métrica alvo é a precisão, para a qual um valor mais alto indica um modelo melhor; Assim, a função retorna o negativo desse valor (portanto, quanto maior a precisão, menor o valor de retorno).
Definir o espaço de pesquisa de hiperparâmetros
Cada vez que a função objetiva é chamada, ela requer um parâmetro contendo os valores de hiperparâmetro a serem tentados. Para especificar o conjunto completo de combinações de valores que podem ser tentadas, você precisa definir um espaço de pesquisa a partir do qual o Hyperopt pode selecionar os valores a serem usados em cada avaliação.
O Hyperopt fornece expressões que você pode usar para definir um intervalo de valores para cada hiperparâmetro, incluindo:
hp.choice(label, options)
: Devolve um dosoptions
que listou.hp.randint(label, upper)
: Devolve um inteiro aleatório no intervalo [0, superior].hp.uniform(label, low, high)
: Devolve um valor uniformemente entrelow
ehigh
.hp.normal(label, mu, sigma)
: Devolve um valor real que é normalmente distribuído com médiamu
e desviosigma
padrão.
Gorjeta
Para obter a lista completa de expressões, consulte a documentação do Hyperopt.
O código de exemplo a seguir 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 do espaço de pesquisa e tentar otimizar a função objetiva. Há duas opções principais em como o Hyperopt fará a amostragem no espaço de pesquisa:
hyperopt.tpe.suggest
: Tree of Parzen Estimators (TPE), uma abordagem bayesiana que seleciona adaptativamente novas configurações de hiperparâmetros com base em resultados anteriores.hyperopt.rand.suggest
: Pesquisa aleatória, uma abordagem não adaptativa que coleta 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 Hyperopt fmin
Finalmente, para executar uma execução Hyperopt, você pode usar a função fmin, que repetidamente chama 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 objetive definida anteriormente. O espaço de pesquisa e o algoritmo definidos em exemplos anteriores são usados, e a função será avaliada até 100 vezes antes que a função fmin retorne a combinação de valor de parâmetro de melhor desempenho que foi 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}