다음을 통해 공유


패브릭에서 하이퍼 매개 변수 튜닝 수행(미리 보기)

하이퍼 매개 변수 튜닝은 성능에 영향을 주는 기계 학습 모델의 매개 변수에 대한 최적 값을 찾는 프로세스입니다. 특히 복잡한 모델 및 큰 데이터 세트를 처리할 때는 도전적이고 시간이 많이 걸릴 수 있습니다. 이 문서에서는 Fabric에서 하이퍼 매개 변수 튜닝을 수행하는 방법을 보여 줍니다.

이 자습서에서는 캘리포니아의 다양한 인구 조사 블록에 대한 중앙값 및 기타 기능에 대한 정보가 포함된 캘리포니아 주택 데이터 세트를 사용합니다. 데이터가 미리 준비되면 SynapseML LightGBM 모델을 학습하여 기능에 따라 집 값을 예측합니다. 다음으로, 빠르고 간단한 AutoML 라이브러리인 FLAML을 사용하여 LightGBM 모델에 가장 적합한 하이퍼 매개 변수를 찾습니다. 마지막으로 튜닝된 모델의 결과를 기본 매개 변수를 사용하는 기준 모델과 비교합니다.

Important

이 기능은 미리 보기로 제공됩니다.

필수 조건

  • 패브릭 환경을 만들거나 Fabric 런타임 1.2(Spark 3.4 이상) 및 델타 2.4에서 실행 중인지 확인합니다.
  • 새 Notebook을 만듭니다.
  • 레이크하우스에 Notebook을 첨부합니다. Notebook 왼쪽에서 추가를 선택하여 기존 레이크하우스를 추가하거나 새 레이크하우스를 만듭니다.

학습 및 테스트용 데이터 세트 준비

이 구역에서는 LightGBM 모델에 대한 학습 및 테스트 데이터 세트를 준비합니다. 우리는 Sklearn의 캘리포니아 주택 데이터 세트를 사용합니다. 데이터에서 Spark 데이터 프레임을 만들고 VectorAssembler를 사용하여 기능을 단일 벡터 열로 결합합니다.

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)

그런 다음 데이터를 각각 85%, 12.75%, 2.25%의 학습, 유효성 검사 및 테스트의 세 하위 집합으로 임의로 분할합니다. 하이퍼 매개 변수 튜닝에 대한 학습 및 유효성 검사 집합과 모델 평가를 위한 테스트 집합을 사용합니다.

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)

ML 실험 설정

MLflow 구성

하이퍼 매개 변수 튜닝을 수행하기 전에 하이퍼 매개 변수의 다른 값을 사용하고 학습 데이터에 대해 LightGBM 모델을 학습할 수 있는 학습 함수를 정의해야 합니다. 또한 모델이 데이터에 얼마나 잘 맞는지 측정하는 R2 점수를 사용하여 유효성 검사 데이터에 대한 모델 성능을 평가해야 합니다.

이렇게 하려면 먼저 필요한 모듈을 가져오고 MLflow 실험을 설정합니다. MLflow는 엔드투엔드 기계 학습 수명 주기를 관리하기 위한 오픈 소스 플랫폼입니다. 다양한 모델 및 하이퍼 매개 변수의 결과를 추적하고 비교하는 데 도움이 됩니다.

# 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)

로깅 수준 설정

여기서는 Synapse.ml 라이브러리에서 불필요한 출력을 표시하지 않도록 로깅 수준을 구성하여 로그를 더 깔끔하게 유지합니다.

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

기준 모델 학습

다음으로, 네 개의 하이퍼 매개 변수를 입력으로 사용하는 학습 함수(alpha, learningRate, numLeaves 및 numIterations)를 정의합니다. FLAML을 사용하여 나중에 튜닝하려는 하이퍼 매개 변수입니다.

또한 train 함수는 두 개의 데이터 프레임을 입력으로 사용합니다. train_data 및 val_data 각각 학습 및 유효성 검사 데이터 세트입니다. 학습 함수는 학습된 모델과 유효성 검사 데이터의 R2 점수라는 두 개의 출력을 반환합니다.

# 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

마지막으로 학습 함수를 사용하여 하이퍼 매개 변수의 기본값을 사용하여 기준 모델을 학습시킵니다. 또한 테스트 데이터에 대한 기준 모델을 평가하고 R2 점수를 출력합니다.

# 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)

FLAML로 하이퍼 매개 변수 튜닝 수행

FLAML은 지정된 모델 및 데이터 세트에 가장 적합한 하이퍼 매개 변수를 자동으로 찾을 수 있는 빠르고 간단한 AutoML 라이브러리입니다. 평가 메트릭의 피드백에 맞게 조정되는 저비용 검색 전략을 사용합니다. 이 구역에서는 FLAML을 사용하여 이전 구역에서 정의한 LightGBM 모델의 하이퍼 매개 변수를 튜닝합니다.

튜닝 함수의 정의

FLAML을 사용하려면 구성 사전을 입력으로 사용하고 평가 메트릭이 있는 사전을 키로, 메트릭 값을 값으로 반환하는 튜닝 함수를 정의해야 합니다.

구성 사전에는 튜닝하려는 하이퍼 매개 변수와 해당 값이 포함됩니다. Tune 함수는 앞에서 정의한 학습 함수를 사용하여 지정된 구성을 사용하여 모델을 학습시키고 평가합니다.

# 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}

검색 공간 정의

다음으로, 튜닝하려는 하이퍼 매개 변수의 검색 공간을 정의해야 합니다. 검색 공간은 하이퍼 매개 변수 이름을 탐색하려는 값 범위에 매핑하는 사전입니다. FLAML은 균일, loguniform 및 randint와 같은 다양한 유형의 범위를 정의하는 몇 가지 편리한 함수를 제공합니다.

이 경우 알파, learningRate, numLeaves 및 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),
}

하이퍼 매개 변수 평가판 정의

마지막으로 FLAML을 사용하여 하이퍼 매개 변수를 최적화하는 하이퍼 매개 변수 평가판을 정의해야 합니다. Tune 함수, 검색 공간, 시간 예산, 샘플 수, 메트릭 이름, 모드 및 세부 정보 수준을 flaml.tune.run 함수에 전달해야 합니다. 또한 중첩된 MLflow 실행을 시작하여 평가판의 결과를 추적해야 합니다.

flaml.tune.run function(은)는 최상의 구성과 최상의 메트릭 값을 포함하는 분석 개체를 반환합니다.

# 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,
        )

평가판이 완료되면 분석 개체에서 최상의 구성과 최상의 메트릭 값을 볼 수 있습니다.

# 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"])

결과 비교

FLAML을 사용하여 최상의 하이퍼 매개 변수를 찾은 후에는 모델 성능이 얼마나 향상되는지 평가해야 합니다. 이를 위해 학습 함수를 사용하여 전체 학습 데이터 세트에서 최상의 하이퍼 매개 변수를 사용하여 새 모델을 만듭니다. 그런 다음 테스트 데이터 세트를 사용하여 새 모델과 기준 모델 모두에 대한 R2 점수를 계산합니다.

# 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)

최종 모델 저장

하이퍼 매개 변수 평가판을 완료하면 이제 최종 조정된 모델을 Fabric에서 ML 모델로 저장할 수 있습니다.

# 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.")