Megosztás a következőn keresztül:


Hiperparaméter finomhangolása a Hálóban (előzetes verzió)

A hiperparaméter-finomhangolás a gépi tanulási modell azon paramétereinek optimális értékeinek megkeresése, amelyek hatással vannak a teljesítményére. Ez kihívást jelenthet és időigényes lehet, különösen összetett modellek és nagy adathalmazok kezelése esetén. Ebben a cikkben bemutatjuk, hogyan végezhet hiperparaméter-finomhangolást a Fabricben.

Ebben az oktatóanyagban a kaliforniai lakásadatkészletet fogjuk használni, amely információkat tartalmaz a medián házértékéről és a különböző kaliforniai összeírási blokkok egyéb funkcióiról. Az adatok előtöredezettsége után betanítunk egy SynapseML LightGBM-modellt, amely a funkciók alapján előrejelzi a ház értékét. Ezután a FLAML-t, egy gyors és könnyű AutoML-kódtárat használunk a LightGBM-modell legjobb hiperparamétereinek megtalálásához. Végül összehasonlítjuk a hangolt modell eredményeit az alapértelmezett paramétereket használó alapmodelllel.

Fontos

Ez a funkció előzetes verzióban érhető el.

Előfeltételek

  • Microsoft Fabric-előfizetés lekérése. Vagy regisztráljon egy ingyenes Microsoft Fabric-próbaverzióra.

  • Jelentkezzen be a Microsoft Fabricbe.

  • A kezdőlap bal oldalán található élménykapcsolóval válthat a Synapse Adattudomány felületre.

    Képernyőkép a felületváltó menüjéről, amelyen látható, hogy hol válassza ki a Adattudomány.

  • Hozzon létre egy új Fabric-környezetet , vagy győződjön meg arról, hogy a Fabric Runtime 1.2 -en (Spark 3.4 (vagy újabb) és Delta 2.4-en fut.
  • Hozzon létre egy új jegyzetfüzetet.
  • Csatolja a jegyzetfüzetet egy tóházhoz. A jegyzetfüzet bal oldalán válassza a Hozzáadás lehetőséget egy meglévő tóház hozzáadásához, vagy hozzon létre egy újat.

Adathalmazok betanítása és tesztelése

Ebben a szakaszban előkészítjük a LightGBM-modell betanítási és tesztelési adatkészleteit. A Kaliforniai lakásadatkészletet a Sklearnből használjuk. Létrehozunk egy Spark-adatkeretet az adatokból, és egy VectorAssembler használatával egyesítjük a funkciókat egyetlen vektoroszlopban.

from sklearn.datasets import fetch_california_housing
from pyspark.sql import SparkSession

# Load the Scikit-learn California Housing dataset
sklearn_dataset = fetch_california_housing()

# Convert the Scikit-learn dataset to a Pandas DataFrame
import pandas as pd
pandas_df = pd.DataFrame(sklearn_dataset.data, columns=sklearn_dataset.feature_names)
pandas_df['target'] = sklearn_dataset.target

# Create a Spark DataFrame from the Pandas DataFrame
spark_df = spark.createDataFrame(pandas_df)

# Display the data
display(spark_df)

Ezután véletlenszerűen felosztjuk az adatokat három részhalmazra: betanításra, ellenőrzésre és tesztelésre, az adatok 85%-ával, 12,75%-ával és 2,25%-ával. A hiperparaméter finomhangolásához és a modell kiértékelési tesztkészletéhez a betanítási és érvényesítési készletet használjuk.

from pyspark.ml.feature import VectorAssembler

# Combine features into a single vector column
featurizer = VectorAssembler(inputCols=sklearn_dataset.feature_names, outputCol="features")
data = featurizer.transform(spark_df)["target", "features"]

# Split the data into training, validation, and test sets
train_data, test_data = data.randomSplit([0.85, 0.15], seed=41)
train_data_sub, val_data_sub = train_data.randomSplit([0.85, 0.15], seed=41)

Az ML-kísérlet beállítása

MLflow konfigurálása

A hiperparaméterek finomhangolása előtt meg kell határoznunk egy olyan betanítási függvényt, amely képes a hiperparaméterek különböző értékeinek betanítására, valamint egy LightGBM-modell betanítására a betanítási adatokon. Az ellenőrzési adatok modellteljesítményét is ki kell értékelnünk az R2 pontszámmal, amely azt méri, hogy a modell mennyire illeszkedik az adatokhoz.

Ehhez először importáljuk a szükséges modulokat, és beállítjuk az MLflow-kísérletet. Az MLflow egy nyílt forráskódú platform, amely lehetővé teszi a teljes gépi tanulási életciklus kezelését. Segít nyomon követni és összehasonlítani a különböző modellek és hiperparaméterek eredményeit.

# Import MLflow and set up the experiment name
import mlflow

mlflow.set_experiment("flaml_tune_sample")

# Enable automatic logging of parameters, metrics, and models
mlflow.autolog(exclusive=False)

Naplózási szint beállítása

Itt úgy konfiguráljuk a naplózási szintet, hogy a Synapse.ml tár szükségtelen kimenetét letiltsa, így a naplók tisztábbak maradnak.

import logging
 
logging.getLogger('synapse.ml').setLevel(logging.ERROR)

Alapmodell betanítása

Ezután meghatározzuk a betanítási függvényt, amely négy hiperparamétert vesz fel bemenetként: alfa, learningRate, numLeaves és numIterations. Ezek azok a hiperparaméterek, amelyeket később a FLAML használatával szeretnénk hangolni.

A betanítási függvény két adatkeretet is fogad bemenetként: train_data és val_data, amelyek a betanítási és érvényesítési adathalmazok. A betanított függvény két kimenetet ad vissza: a betanított modellt és az érvényesítési adatok R2-pontszámát.

# Import LightGBM and RegressionEvaluator
from synapse.ml.lightgbm import LightGBMRegressor
from pyspark.ml.evaluation import RegressionEvaluator

def train(alpha, learningRate, numLeaves, numIterations, train_data=train_data_sub, val_data=val_data_sub):
    """
    This train() function:
     - takes hyperparameters as inputs (for tuning later)
     - returns the R2 score on the validation dataset

    Wrapping code as a function makes it easier to reuse the code later for tuning.
    """
    with mlflow.start_run() as run:

        # Capture run_id for prediction later
        run_details = run.info.run_id

        # Create a LightGBM regressor with the given hyperparameters and target column
        lgr = LightGBMRegressor(
            objective="quantile",
            alpha=alpha,
            learningRate=learningRate,
            numLeaves=numLeaves,
            labelCol="target",
            numIterations=numIterations,
            dataTransferMode="bulk"
        )

        # Train the model on the training data
        model = lgr.fit(train_data)

        # Make predictions on the validation data
        predictions = model.transform(val_data)
        # Define an evaluator with R2 metric and target column
        evaluator = RegressionEvaluator(predictionCol="prediction", labelCol="target", metricName="r2")
        # Compute the R2 score on the validation data
        eval_metric = evaluator.evaluate(predictions)

        mlflow.log_metric("r2_score", eval_metric)

    # Return the model and the R2 score
    return model, eval_metric, run_details

Végül a betanítása függvénnyel betanítunk egy alapmodellt a hiperparaméterek alapértelmezett értékeivel. Emellett kiértékeljük az alapmodellt a tesztadatokon, és kinyomtatjuk az R2 pontszámot.

# Train the baseline model with the default hyperparameters
init_model, init_eval_metric, init_run_id = train(alpha=0.2, learningRate=0.3, numLeaves=31, numIterations=100, train_data=train_data, val_data=test_data)
# Print the R2 score of the baseline model on the test data
print("R2 of initial model on test dataset is: ", init_eval_metric)

Hiperparaméter finomhangolása a FLAML használatával

A FLAML egy gyors és könnyű AutoML-kódtár, amely automatikusan megtalálja az adott modell és adatkészlet legjobb hiperparamétereit. Alacsony költségű keresési stratégiát használ, amely igazodik a kiértékelési metrika visszajelzéseihez. Ebben a szakaszban a FLAML használatával hangoljuk az előző szakaszban definiált LightGBM-modell hiperparamétereit.

Dallamfüggvény definiálása

A FLAML használatához meg kell határoznunk egy dallamfüggvényt, amely bemenetként egy konfigurációs szótárat használ, és egy szótárt ad vissza, amely kulcsként a kiértékelési metrikát, a metrikaértéket pedig értékként adja vissza.

A konfigurációs szótár tartalmazza a hangolni kívánt hiperparamétereket és azok értékeit. A hangolás függvény a korábban definiált betanított függvényt fogja használni a modell betanítása és kiértékelése a megadott konfigurációval.

# Import FLAML
import flaml

# Define the tune function
def flaml_tune(config):
    # Train and evaluate the model with the given config
    _, metric, run_id = train(**config)
    # Return the evaluation metric and its value
    return {"r2": metric}

Keresési terület meghatározása

Ezután meg kell határoznunk a módosítani kívánt hiperparaméterek keresési területét. A keresési terület egy szótár, amely leképzi a hiperparaméterek nevét a vizsgálandó értékek tartományára. A FLAML néhány kényelmes funkciót biztosít a különböző tartománytípusok, például az egységes, a loguniform és a randint definiálásához.

Ebben az esetben a következő négy hiperparamétert szeretnénk hangolni: alfa, learningRate, numLeaves és numIterations.

# Define the search space
params = {
    # Alpha is a continuous value between 0 and 1
    "alpha": flaml.tune.uniform(0, 1),
    # Learning rate is a continuous value between 0.001 and 1
    "learningRate": flaml.tune.uniform(0.001, 1),
    # Number of leaves is an integer value between 30 and 100
    "numLeaves": flaml.tune.randint(30, 100),
    # Number of iterations is an integer value between 100 and 300
    "numIterations": flaml.tune.randint(100, 300),
}

Hiperparaméter-próba definiálása

Végül meg kell határoznunk egy hiperparaméteres próbaverziót, amely a FLAML használatával optimalizálja a hiperparamétereket. Át kell adnunk a dallamfüggvényt, a keresési területet, az időkeretet, a minták számát, a metrika nevét, a módot és a részletességi szintet a flaml.tune.run függvénynek. A próbaverzió eredményeinek nyomon követéséhez beágyazott MLflow-futtatás is szükséges.

A flaml.tune.run function rendszer egy elemzési objektumot ad vissza, amely a legjobb konfigurációt és a legjobb metrikaértéket tartalmazza.

# Start a nested MLflow run
with mlflow.start_run(nested=True, run_name="Child Run: "):
    # Run the hyperparameter trial with FLAML
    analysis = flaml.tune.run(
        # Pass the tune function
        flaml_tune,
        # Pass the search space
        params,
        # Set the time budget to 120 seconds
        time_budget_s=120,
        # Set the number of samples to 100
        num_samples=100,
        # Set the metric name to r2
        metric="r2",
        # Set the mode to max (we want to maximize the r2 score)
        mode="max",
        # Set the verbosity level to 5
        verbose=5,
        )

A próbaidőszak befejezése után megtekintheti a legjobb konfigurációt és a legjobb metrikaértéket az elemzési objektumból.

# Get the best config from the analysis object
flaml_config = analysis.best_config
# Print the best config
print("Best config: ", flaml_config)
print("Best score on validation data: ", analysis.best_result["r2"])

Eredmények összehasonlítása

Miután megtalálta a legjobb hiperparamétereket a FLAML használatával, ki kell értékelnünk, hogy mennyivel javítják a modell teljesítményét. Ehhez a betanítási függvény használatával létrehozunk egy új modellt a legjobb hiperparaméterekkel a teljes betanítási adatkészleten. Ezután a tesztadatkészlet használatával kiszámítjuk az R2-pontszámot az új modell és az alapmodell esetében is.

# Train a new model with the best hyperparameters 
flaml_model, flaml_metric, flaml_run_id = train(train_data=train_data, val_data=test_data, **flaml_config)

# Print the R2 score of the baseline model on the test dataset
print("On the test dataset, the initial (untuned) model achieved R^2: ", init_eval_metric)
# Print the R2 score of the new model on the test dataset
print("On the test dataset, the final flaml (tuned) model achieved R^2: ", flaml_metric)

Végső modell mentése

Miután befejeztük a hiperparaméter-próbaidőszakot, menthetjük a végleges, finomhangolt modellt ml-modellként a Fabricben.

# Specify the model name and the path where you want to save it in the registry
model_name = "housing_model"  # Replace with your desired model name
model_path = f"runs:/{flaml_run_id}/model"

# Register the model to the MLflow registry
registered_model = mlflow.register_model(model_uri=model_path, name=model_name)

# Print the registered model's name and version
print(f"Model '{registered_model.name}' version {registered_model.version} registered successfully.")