Optimera hyperparametrar med Hyperopt

Slutförd

Hyperopt är ett öppen källkod Python-bibliotek för hyperparameterjustering. Hyperopt installeras automatiskt när du skapar ett kluster med en ML-variant av Databricks Runtime. Följ dessa steg om du vill använda den när du tränar en modell:

  1. Definiera en objektiv funktion för att träna och utvärdera en modell.
  2. Definiera ett sökområde för hyperparameter.
  3. Ange sökalgoritmen.
  4. Kör funktionen Hyperopt fmin för att optimera träningsfunktionen.

Definiera en målfunktion

Hyperopt fungerar genom att iterativt anropa en funktion (kallas ofta för målfunktionen ) som returnerar ett numeriskt värde och justerar parametrarna som skickas till funktionen så att returvärdet minimeras, en metod som ofta kallas optimering. Det första kravet är därför att kapsla in modelltränings- och utvärderingslogik i en funktion som:

  • Accepterar en parameter som innehåller en lista med hyperparametervärden.
  • Tränar en modell med hjälp av de angivna hyperparametervärdena.
  • Utvärderar modellen baserat på ett målmått för förutsägelseprestanda.
  • Returnerar ett numeriskt värde som återspeglar prestandamåttet så att förbättrad modellprestanda sänker returvärdet.

Följande funktion tränar till exempel en maskininlärningsmodell med hjälp av LogisticRegression-algoritmen från Spark MLlib-biblioteket.

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}

I det här exemplet är parametern params en ordlista som innehåller värden för två namngivna värden: Iterationer och regularisering. Dessa värden tilldelas till maxIter - och regParam-hyperparametrar för den logistiska regressionsalgoritm som används för att träna modellen.

Funktionen utvärderar sedan den tränade modellen för att beräkna dess noggrannhetsmått , vilket är ett värde mellan 0,0 och 1,0 som anger andelen förutsägelser som modellen gjorde som var korrekt.

Slutligen returnerar funktionen ett värde som Hyperopt bör minimera för att förbättra modellen. I det här fallet är målmåttet noggrannhet, för vilket ett högre värde anger en bättre modell. så funktionen returnerar det negativa värdet (så ju högre noggrannhet, desto lägre returvärde).

Definiera sökutrymmet för hyperparametrar

Varje gång målfunktionen anropas kräver den att en parameter som innehåller hyperparametervärdena provas. Om du vill prova alla möjliga värdekombinationer måste du definiera ett sökutrymme för Hyperopt för att välja värden från för varje utvärderingsversion.

Hyperopt tillhandahåller uttryck som du kan använda för att definiera ett värdeintervall för varje hyperparameter, inklusive:

  • hp.choice(label, options): Returnerar en av de options du listade.
  • hp.randint(label, upper): Returnerar ett slumpmässigt heltal i intervallet [0, övre].
  • hp.uniform(label, low, high): Returnerar ett värde som är enhetligt mellan low och high.
  • hp.normal(label, mu, sigma): Returnerar ett verkligt värde som normalt distribueras med medelvärde mu och standardavvikelse sigma.

Dricks

Den fullständiga listan över uttryck finns i Hyperopt-dokumentationen.

I följande exempelkod definieras ett sökutrymme för de hyperparametrar som användes i föregående exempel:

from hyperopt import hp

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

Ange sökalgoritmen

Hyperopt använder en sökalgoritm för att välja hyperparametervärden från sökutrymmet och försöka optimera målfunktionen. Det finns två huvudsakliga alternativ i hur Hyperopt-exempel över sökutrymmet:

  • hyperopt.tpe.suggest: Tree of Parzen Estimators (TPE), en Bayesian-metod som anpassningsbart väljer nya inställningar för hyperparameter baserat på tidigare resultat.
  • hyperopt.rand.suggest: Slumpmässig sökning, en icke-adaptiv metod som slumpmässigt tar exempel över sökutrymmet.

Följande exempelkod anger TPE-algoritmen.

from hyperopt import tpe

algo = tpe.suggest

Kör funktionen Hyperopt fmin

För att köra en Hyperopt-körning kan du slutligen använda funktionen fmin , som upprepade gånger anropar målfunktionen med hjälp av hyperparameterkombinationer från sökutrymmet baserat på sökalgoritmen. Målet med funktionen fmin är att minimera värdet som returneras av målfunktionen (och därför optimera modellens prestanda).

I följande exempelkod används funktionen fmin för att anropa den målfunktion som definierades tidigare. Sökutrymmet och algoritmen som definierats i tidigare exempel används och funktionen utvärderas upp till 100 gånger innan funktionen fmin returnerar den kombination av parametervärde som har bäst prestanda som hittades.

from hyperopt import fmin

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

print("Best param values: ", argmin)

Utdata från föregående kod ser ut ungefär som i följande exempel.

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