Optymalizowanie hiperparametrów za pomocą funkcji Hyperopt

Ukończone

Hyperopt to biblioteka języka Python typu open source do dostrajania hiperparametrów. Funkcja Hyperopt jest instalowana automatycznie podczas tworzenia klastra z wariantem uczenia maszynowego środowiska Databricks Runtime. Aby użyć go podczas trenowania modelu, wykonaj następujące kroki:

  1. Definiowanie funkcji celu w celu trenowania i oceniania modelu.
  2. Zdefiniuj obszar wyszukiwania hiperparametrów.
  3. Określ algorytm wyszukiwania.
  4. Uruchom funkcję hyperopt fmin , aby zoptymalizować funkcję trenowania.

Definiowanie funkcji objective

Funkcja Hyperopt działa iteracyjnie wywołując funkcję (często nazywaną funkcją obiektywną ), która zwraca wartość liczbową i dostraja parametry przekazywane do funkcji, tak aby wartość zwracana była zminimalizowana; podejście często określane jako optymalizacja. Pierwszym wymaganiem jest zatem hermetyzacja logiki trenowania i oceny modelu w funkcji, która:

  • Akceptuje parametr zawierający listę wartości hiperparametrów.
  • Trenuje model przy użyciu podanych wartości hiperparametrów.
  • Ocenia model na podstawie docelowej metryki pod kątem wydajności predykcyjnej.
  • Zwraca wartość liczbową, która odzwierciedla metrykę wydajności, tak aby poprawa wydajności modelu obniżyła wartość zwracaną.

Na przykład poniższa funkcja szkoli model uczenia maszynowego przy użyciu algorytmu LogisticsRegression z biblioteki MLlib platformy 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}

W tym przykładzie parametr params jest słownikiem zawierającym wartości dwóch nazwanych wartości: iteracji i regularyzacji. Te wartości są przypisywane do hiperparametrów maxIter i regParam algorytmu regresji logistycznej używanego do trenowania modelu.

Następnie funkcja ocenia wytrenowany model, aby obliczyć jego metrykę dokładności , która jest wartością z zakresu od 0,0 do 1,0 wskazującą odsetek przewidywań wykonanych przez model.

Na koniec funkcja zwraca wartość, którą funkcja Hyperopt powinna zminimalizować, aby poprawić model. W takim przypadku metryka docelowa jest dokładnością, dla której wyższa wartość wskazuje lepszy model; dlatego funkcja zwraca wartość ujemną tej wartości (więc im większa dokładność, tym niższa wartość zwracana).

Definiowanie przestrzeni wyszukiwania hiperparametrów

Za każdym razem, gdy wywoływana jest funkcja objective, wymaga ona parametru zawierającego wartości hiperparametrów, które mają być wypróbowane. Aby wypróbować wszystkie możliwe kombinacje wartości, należy zdefiniować miejsce wyszukiwania dla funkcji Hyperopt, aby wybrać wartości z każdej wersji próbnej.

Funkcja Hyperopt udostępnia wyrażenia, których można użyć do zdefiniowania zakresu wartości dla każdego hiperparametru, w tym:

  • hp.choice(label, options): zwraca jeden z wymienionych elementów options .
  • hp.randint(label, upper): Zwraca losową liczbę całkowitą w zakresie [0, górny].
  • hp.uniform(label, low, high): Zwraca wartość jednolicie między low i high.
  • hp.normal(label, mu, sigma): Zwraca wartość rzeczywistą, która jest zwykle rozłożona ze średnią mu i odchyleniem sigmastandardowym.

Napiwek

Pełną listę wyrażeń można znaleźć w dokumentacji funkcji Hyperopt.

Poniższy przykładowy kod definiuje miejsce wyszukiwania dla hiperparametrów używanych w poprzednim przykładzie:

from hyperopt import hp

search_space = {
    'Iterations': hp.randint('Iterations', 10),
    'Regularization': hp.uniform('Regularization', 0.0, 1.0)
}

Określanie algorytmu wyszukiwania

Funkcja Hyperopt używa algorytmu wyszukiwania, aby wybrać wartości hiperparametryczne z obszaru wyszukiwania i spróbować zoptymalizować funkcję celu. Istnieją dwie główne opcje dotyczące sposobu, w jaki próbki funkcji Hyperopt w przestrzeni wyszukiwania:

  • hyperopt.tpe.suggest: Drzewo narzędzia do szacowania Parzen (TPE), podejście bayesowskie, które adaptacyjnie wybiera nowe ustawienia hiperparametrów na podstawie poprzednich wyników.
  • hyperopt.rand.suggest: Wyszukiwanie losowe, podejście nieadapcyjne, które losowo próbkuje w przestrzeni wyszukiwania.

Poniższy przykładowy kod określa algorytm TPE.

from hyperopt import tpe

algo = tpe.suggest

Uruchamianie funkcji Hyperopt fmin

Na koniec, aby wykonać uruchomienie funkcji Hyperopt, można użyć funkcji fmin , która wielokrotnie wywołuje funkcję celu przy użyciu kombinacji hiperparametrów z przestrzeni wyszukiwania na podstawie algorytmu wyszukiwania. Celem funkcji fmin jest zminimalizowanie wartości zwracanej przez funkcję objective (i w związku z tym optymalizację wydajności modelu).

Poniższy przykładowy kod używa funkcji fmin do wywołania wcześniej zdefiniowanej funkcji objective . Używana jest przestrzeń wyszukiwania i algorytm zdefiniowany w poprzednich przykładach, a funkcja jest obliczana do 100 razy, zanim funkcja fmin zwróci kombinację wartości parametru o najlepszej wydajności, która została znaleziona.

from hyperopt import fmin

argmin = fmin(
  fn=objective,
  space=search_space,
  algo=algo,
  max_evals=100)

print("Best param values: ", argmin)

Dane wyjściowe z poprzedniego kodu wyglądają podobnie jak w poniższym przykładzie.

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