共用方式為


開始使用:在 Azure Databricks 上建置您的第一個機器學習模型

本文說明如何使用 Azure Databricks 上的 scikit-learn 程式庫來建置機器學習分類模型。

目標是建立分類模型來預測葡萄酒是否被視為「高品質」。 資料集包含不同葡萄酒的 11 個特徵 (例如酒精含量、酸度和殘留糖分),介於 1 到 10 之間的品質排名。

此範例也說明如何使用 MLflow 來追蹤模型開發流程,以及 Hyperopt 將超參數微調自動化。

資料集來自 UCI 機器學習存放庫,在透過物理化學特性的資料挖掘,建立葡萄酒喜好的模型 [Cortez 等人,2009] 中提出。

開始之前

  • 您的工作區必須啟用 Unity Catalog。
  • 您必須擁有建立叢集或存取叢集的權限。
  • 您必須擁有目錄的USE_CATALOG許可權。
  • 在該目錄中,您必須在架構上具有下列許可權:USE_SCHEMA、CREATE_TABLE和CREATE_MODEL。

提示

本文中的所有程式碼都可在筆記本中取得,您可以直接匯入工作區。 請參閱範例筆記本:建置分類模型

步驟 1:建立 Databricks 筆記本

若要在工作區中建立筆記本,請按一下提要欄位的 新增圖示新增 ,然後按一下 筆記本。 空白筆記本會在工作區中開啟。

若要深入瞭解如何建立並管理筆記本,請參閱 管理筆記本

步驟 2:連線到計算資源

若要進行探索性資料分析和資料工程,您必須能夠存取計算。

如需連線到現有計算資源的指示,請參閱計算。 如需設定新計算資源的指示,請參閱計算組態參考

本文中的步驟需要適用於機器學習的 Databricks Runtime。 如需選取 Databricks Runtime ML 版本的詳細資訊和指示,請參閱適用於機器學習的 Databricks Runtime

步驟 3:設定模型登錄、目錄和架構

開始之前,需要兩個重要步驟。 首先,您必須將 MLflow 用戶端設定為使用 Unity 目錄作為模型登錄。 在筆記本的新儲存格中輸入下列程式碼。

import mlflow
mlflow.set_registry_uri("databricks-uc")

您也必須設定註冊模型所需的目錄和結構描述。 您必須具有目錄的 USE CATALOG 許可權,以及架構上USE_SCHEMA、CREATE_TABLE和CREATE_MODEL許可權。

如需如何使用 Unity 目錄的詳細資訊,請參閱 什麼是 Unity 目錄?

在筆記本的新儲存格中輸入下列程式碼。

# If necessary, replace "main" and "default" with a catalog and schema for which you have the required permissions.
CATALOG_NAME = "main"
SCHEMA_NAME = "default"

步驟 4:載入資料並建立 Unity 目錄數據表

此範例使用 Azure Databricks 中內建的兩個 CSV 檔案。 若要了解如何內嵌您自己的資料,請參閱將資料內嵌至 Databricks Lakehouse

在筆記本的新儲存格中輸入下列程式碼。

white_wine = spark.read.csv("dbfs:/databricks-datasets/wine-quality/winequality-white.csv", sep=';', header=True)
red_wine = spark.read.csv("dbfs:/databricks-datasets/wine-quality/winequality-red.csv", sep=';', header=True)

# Remove the spaces from the column names
for c in white_wine.columns:
    white_wine = white_wine.withColumnRenamed(c, c.replace(" ", "_"))
for c in red_wine.columns:
    red_wine = red_wine.withColumnRenamed(c, c.replace(" ", "_"))

# Define table names
red_wine_table = f"{CATALOG_NAME}.{SCHEMA_NAME}.red_wine"
white_wine_table = f"{CATALOG_NAME}.{SCHEMA_NAME}.white_wine"

# Write to tables in Unity Catalog
spark.sql(f"DROP TABLE IF EXISTS {red_wine_table}")
spark.sql(f"DROP TABLE IF EXISTS {white_wine_table}")
white_wine.write.saveAsTable(f"{CATALOG_NAME}.{SCHEMA_NAME}.white_wine")
red_wine.write.saveAsTable(f"{CATALOG_NAME}.{SCHEMA_NAME}.red_wine")

步驟 5: 前置處理和分割資料

在此步驟中,您會將數據從您在步驟 4 中建立的 Unity 目錄數據表載入 Pandas DataFrame,並預先處理數據。 此區段中的代碼會執行下列動作:

  1. 以 Pandas DataFrames 載入資料。
  2. 將布爾值數據行新增至每個 DataFrame 以區分紅白葡萄酒,然後將 DataFrame 合併成新的 DataFrame,data_df
  3. 數據集包含一個 quality 數據行,將葡萄酒評為 1 到 10,其中 10 表示品質最高。 此程式代碼會將此數據行轉換成兩個分類值:“True”,以表示高品質的葡萄酒(quality>= 7)和“False”,以表示不高品質的葡萄酒(quality< 7)。
  4. 將 DataFrame 分割為訓練與測試資料集。

首先,匯入必要的程式庫:

import numpy as np
import pandas as pd
import sklearn.datasets
import sklearn.metrics
import sklearn.model_selection
import sklearn.ensemble

import matplotlib.pyplot as plt

from hyperopt import fmin, tpe, hp, SparkTrials, Trials, STATUS_OK
from hyperopt.pyll import scope

現在載入及前置處理資料:

# Load data from Unity Catalog as Pandas dataframes
white_wine = spark.read.table(f"{CATALOG_NAME}.{SCHEMA_NAME}.white_wine").toPandas()
red_wine = spark.read.table(f"{CATALOG_NAME}.{SCHEMA_NAME}.red_wine").toPandas()

# Add Boolean fields for red and white wine
white_wine['is_red'] = 0.0
red_wine['is_red'] = 1.0
data_df = pd.concat([white_wine, red_wine], axis=0)

# Define classification labels based on the wine quality
data_labels = data_df['quality'].astype('int') >= 7
data_df = data_df.drop(['quality'], axis=1)

# Split 80/20 train-test
X_train, X_test, y_train, y_test = sklearn.model_selection.train_test_split(
  data_df,
  data_labels,
  test_size=0.2,
  random_state=1
)

步驟 6。 訓練對分類模型

此步驟會使用預設演算法設定來訓練梯度提升分類器。 然後,它會將產生的模型套用至測試資料集,然後計算、記錄,並顯示接收者作業曲線下的區域,以評估模型的效能。

首先,啟用 MLflow 自動記錄:

mlflow.autolog()

現在啟動模型訓練執行:

with mlflow.start_run(run_name='gradient_boost') as run:
    model = sklearn.ensemble.GradientBoostingClassifier(random_state=0)

    # Models, parameters, and training metrics are tracked automatically
    model.fit(X_train, y_train)

    predicted_probs = model.predict_proba(X_test)
    roc_auc = sklearn.metrics.roc_auc_score(y_test, predicted_probs[:,1])
    roc_curve = sklearn.metrics.RocCurveDisplay.from_estimator(model, X_test, y_test)

    # Save the ROC curve plot to a file
    roc_curve.figure_.savefig("roc_curve.png")

    # The AUC score on test data is not automatically logged, so log it manually
    mlflow.log_metric("test_auc", roc_auc)

    # Log the ROC curve image file as an artifact
    mlflow.log_artifact("roc_curve.png")

    print("Test AUC of: {}".format(roc_auc))

儲存格結果會顯示曲線下計算的區域和 ROC 曲線的繪圖:

分類模型的 ROC 曲線。

步驟 7。 在 MLflow 中檢視實驗執行

MLflow 實驗追蹤可在您反覆式開發模型時記錄程式碼和結果,協助您追蹤模型開發。

若要從您剛執行的訓練執行中檢視記錄的結果,請按下儲存格輸出中的連結,如下圖所示。

在儲存格結果中連結實驗。

實驗頁面可讓您比較執行,並檢視特定執行的詳細資料。 請參閱 MLflow 實驗追蹤

步驟 8。 超參數微調

開發 ML 模型的重要步驟是微調控制演算法的參數,稱為超參數,以優化模型的精確度。

Databricks Runtime ML 包含 Hyperopt,也就是用於超參數微調的 Python 程式庫。 您可以使用 Hyperopt 以平行方式執行超參數掃掠和定型多個模型,以減少優化模型效能所需的時間。 MLflow 追蹤會與 Hyperopt 整合,以自動記錄模型和參數。 如需在 Databricks 中使用 Hyperopt 的詳細資訊,請參閱超參數微調

下列程式碼提供了使用 Hyperopt 的範例。

# Define the search space to explore
search_space = {
  'n_estimators': scope.int(hp.quniform('n_estimators', 20, 1000, 1)),
  'learning_rate': hp.loguniform('learning_rate', -3, 0),
  'max_depth': scope.int(hp.quniform('max_depth', 2, 5, 1)),
}

def train_model(params):
  # Enable autologging on each worker
  mlflow.autolog()
  with mlflow.start_run(nested=True):
    model_hp = sklearn.ensemble.GradientBoostingClassifier(
      random_state=0,
      **params
    )
    model_hp.fit(X_train, y_train)
    predicted_probs = model_hp.predict_proba(X_test)
    # Tune based on the test AUC
    # In production, you could use a separate validation set instead
    roc_auc = sklearn.metrics.roc_auc_score(y_test, predicted_probs[:,1])
    mlflow.log_metric('test_auc', roc_auc)

    # Set the loss to -1*auc_score so fmin maximizes the auc_score
    return {'status': STATUS_OK, 'loss': -1*roc_auc}

# SparkTrials distributes the tuning using Spark workers
# Greater parallelism speeds processing, but each hyperparameter trial has less information from other trials
# On smaller clusters try setting parallelism=2
spark_trials = SparkTrials(
  parallelism=1
)

with mlflow.start_run(run_name='gb_hyperopt') as run:
  # Use hyperopt to find the parameters yielding the highest AUC
  best_params = fmin(
    fn=train_model,
    space=search_space,
    algo=tpe.suggest,
    max_evals=32,
    trials=spark_trials)

步驟 9. 尋找最佳模型,並將其註冊至 Unity 目錄

下列程式碼會識別產生最佳結果的執行,如 ROC 曲線下的區域所測量:

# Sort runs by their test auc. In case of ties, use the most recent run.
best_run = mlflow.search_runs(
  order_by=['metrics.test_auc DESC', 'start_time DESC'],
  max_results=10,
).iloc[0]
print('Best Run')
print('AUC: {}'.format(best_run["metrics.test_auc"]))
print('Num Estimators: {}'.format(best_run["params.n_estimators"]))
print('Max Depth: {}'.format(best_run["params.max_depth"]))
print('Learning Rate: {}'.format(best_run["params.learning_rate"]))

使用您為最佳模型識別的 run_id,下列程式代碼會將該模型註冊到 Unity 目錄。

model_uri = 'runs:/{run_id}/model'.format(
    run_id=best_run.run_id
  )

mlflow.register_model(model_uri, f"{CATALOG_NAME}.{SCHEMA_NAME}.wine_quality_model")

範例筆記本:建置分類模型

使用下列筆記本來執行本文章中的步驟。 如需將筆記本匯入 Azure Databricks 工作區的指示,請參閱匯入筆記本

使用 atabricks 建置您的第一個機器學習模型

取得筆記本

深入了解

Databricks 提供單一平臺,提供 ML 開發和部署的每個步驟,從原始數據到推斷數據表,以儲存服務模型的每個要求和回應。 數據科學家、數據工程師、ML 工程師和DevOps可以使用同一組工具和單一事實來源來執行其工作。

若要深入了解,請參閱下列內容: