Optimiser les hyperparamètres avec Hyperopt
Hyperopt est une bibliothèque Python open source pour le réglage des hyperparamètres. Hyperopt est automatiquement installé lorsque vous créez un cluster avec une variante ML de Databricks Runtime. Pour l’utiliser lors de l’entraînement d’un modèle, suivez ces étapes :
- Définissez une fonction objective pour entraîner et évaluer un modèle.
- Définir l’espace de recherche des hyperparamètres.
- Spécifier l’algorithme de recherche.
- Exécutez la fonction fmin Hyperopt pour optimiser la fonction d’entraînement.
Définir une fonction objective
Hyperopt fonctionne en appelant de façon itérative une fonction (souvent appelée fonction objective) qui retourne une valeur numérique et en réglant les paramètres passés à la fonction afin que la valeur de retour soit réduite ; une approche communément appelée optimisation. La première exigence consiste donc à encapsuler votre logique d’apprentissage et d’évaluation de modèle dans une fonction qui :
- Accepte un paramètre contenant une liste de valeurs d’hyperparamètre.
- Forme un modèle à l’aide des valeurs d’hyperparamètre fournies.
- Évalue le modèle en fonction d’une métrique cible pour les performances prédictives.
- Retourne une valeur numérique qui reflète la métrique de performances de sorte que l’amélioration des performances du modèle réduit la valeur de retour.
Par exemple, la fonction suivante entraîne un modèle Machine Learning à l’aide de l’algorithme LogisticRegression de la bibliothèque 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}
Dans cet exemple, le paramètre params est un dictionnaire contenant des valeurs pour deux valeurs nommées : itérations et régularisation. Ces valeurs sont affectées aux hyperparamètres maxIter et regParam de l’algorithme de régression logistique utilisé pour entraîner le modèle.
La fonction évalue ensuite le modèle entraîné pour calculer sa métrique accuracy, qui est une valeur comprise entre 0,0 et 1,0 indiquant la proportion des prédictions effectuées par le modèle qui étaient correctes.
Enfin, la fonction retourne une valeur qu’Hyperopt doit réduire pour améliorer le modèle. Dans ce cas, la métrique cible est la précision, pour laquelle une valeur plus élevée indique un meilleur modèle ; ainsi, la fonction retourne le négatif de cette valeur (de sorte que plus la précision est élevée, plus la valeur de retour est faible).
Définir l’espace de recherche des hyperparamètres
Chaque fois que la fonction objective est appelée, elle nécessite qu’un paramètre contenant les valeurs d’hyperparamètre soit vérifié. Si vous souhaitez essayer toutes les combinaisons de valeurs possibles, vous devez définir un espace de recherche dans lequel Hyperopt sélectionne des valeurs pour chaque essai.
Hyperopt fournit des expressions que vous pouvez utiliser pour définir une plage de valeurs pour chaque hyperparamètre, notamment :
hp.choice(label, options)
: Retourne un des élémentsoptions
que vous avez répertoriés.hp.randint(label, upper)
: Retourne un entier aléatoire dans la plage [0, upper].hp.uniform(label, low, high)
: Retourne uniformément une valeur entrelow
ethigh
.hp.normal(label, mu, sigma)
: Retourne une valeur réelle qui est normalement distribuée avec la moyennemu
et l’écart typesigma
.
Conseil
Pour obtenir la liste complète des expressions, consultez la documentation Hyperopt.
L’exemple de code suivant définit un espace de recherche pour les hyperparamètres utilisés dans l’exemple précédent :
from hyperopt import hp
search_space = {
'Iterations': hp.randint('Iterations', 10),
'Regularization': hp.uniform('Regularization', 0.0, 1.0)
}
Spécifier l’algorithme de recherche
Hyperopt utilise un algorithme de recherche pour sélectionner des valeurs d’hyperparamètre dans l’espace de recherche et essayer d’optimiser la fonction objective. Il existe deux choix principaux dans la manière dont Hyperopt échantillonne l’espace de recherche :
hyperopt.tpe.suggest
: Estimateurs d’arborescence de Parzen (TDE), une approche bayésienne qui sélectionne de manière adaptative les nouveaux paramètres d’hyperparamètre en fonction des résultats passés.hyperopt.rand.suggest
: Recherche aléatoire, approche non adaptative qui échantillonne au hasard l’espace de recherche.
L’exemple de code suivant spécifie l’algorithme TPE.
from hyperopt import tpe
algo = tpe.suggest
Exécuter la fonction Hyperopt fmin
Enfin, pour exécuter une exécution Hyperopt, vous pouvez utiliser la fonction fmin, qui appelle à plusieurs reprises la fonction objective à l’aide de combinaisons d’hyperparamètres à partir de l’espace de recherche en fonction de l’algorithme de recherche. L’objectif de la fonction fmin est de réduire la valeur retournée par la fonction objective (et donc d’optimiser les performances du modèle).
L’exemple de code suivant utilise la fonction fmin pour appeler la fonction objective définie précédemment. L’espace de recherche et l’algorithme définis dans les exemples précédents sont utilisés. Par ailleurs, la fonction est évaluée jusqu’à 100 fois avant que la fonction fmin retourne la combinaison de valeurs de paramètre la plus performante trouvée.
from hyperopt import fmin
argmin = fmin(
fn=objective,
space=search_space,
algo=algo,
max_evals=100)
print("Best param values: ", argmin)
La sortie du code précédent ressemble à l’exemple suivant.
Best param values: {'Iterations': 6, 'Regularization': 0.5461699702338606}