本教學課程示範如何使用 scikit-learn 程式庫在 Azure Databricks 上建置機器學習分類模型。
目標是建立分類模型來預測葡萄酒是否被視為「高品質」。 資料集包含不同葡萄酒的 11 個特徵 (例如酒精含量、酸度和殘留糖分),介於 1 到 10 之間的品質排名。
此範例也說明如何使用 MLflow 來追蹤模型開發程式,以及 使用 Hyperopt 來自動化超參數微調。
數據集來自 UCI 機器學習資料庫,在 [Cortez et al., 2009] 的研究中通過物理化學屬性的數據挖掘來建模葡萄酒的偏好。
開始之前
- 您的工作區必須啟用 Unity Catalog。 請參閱 開始使用 Unity 目錄。
- 您必須具有建立計算資源的許可權,或存取使用 Databricks Runtime for Machine Learning 的計算資源。
- 您必須擁有 USE CATALOG 目錄的權限。
- 在該目錄中,您必須在架構上具有下列許可權: USE SCHEMA、 CREATE TABLE和 CREATE MODEL。
提示
本文中的所有程式碼都可在筆記本中取得,您可以直接匯入工作區。 請參閱 範例筆記本:建置分類模型。
步驟 1:建立 Databricks 筆記本
若要在工作區中建立筆記本,請按兩下提要字段中的 [
] ,然後按兩下 [ 筆記本]。 空白筆記本會在工作區中開啟。
若要深入瞭解如何建立和管理筆記本,請參閱 管理筆記本。
步驟 2:連線到計算資源
若要進行探勘數據分析和數據工程,您必須能夠存取 計算。 本文中的步驟需要適用於機器學習的 Databricks Runtime。 如需選取 Databricks Runtime ML 版本的詳細資訊和指示,請參閱 Machine Learning 的 Databricks Runtime。
在您的筆記本中,按下右上方的 連線 下拉選單。 如果您有使用 Databricks Runtime for Machine Learning 的現有資源存取權,請從功能表中選取該資源。 否則,請按兩下 [ 建立新的資源... ] 來 設定新的計算資源。
步驟 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 目錄數據表
此範例使用 中 databricks-datasets提供的兩個 CSV 檔案。 若要瞭解如何內嵌您自己的數據,請參閱 Lakeflow Connect 中的標準連接器。
在筆記本的新儲存格中輸入下列程式碼。 此程式代碼會執行下列動作:
- 將數據從
winequality-white.csv和winequality-red.csv讀入 Spark DataFrames。 - 使用底線取代數據行名稱中的空格,以清除數據。
- 將 DataFrames 寫入 Unity Catalog 中的
white_wine和red_wine資料表。 將資料儲存至 Unity 目錄會保存數據,並可讓您控制如何與其他人共用數據。
white_wine = spark.read.csv("/databricks-datasets/wine-quality/winequality-white.csv", sep=';', header=True)
red_wine = spark.read.csv("/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,並預先處理數據。 此區段中的代碼會執行下列動作:
- 以 Pandas DataFrames 載入資料。
- 將布爾值數據行新增至每個 DataFrame 以區分紅白葡萄酒,然後將 DataFrame 合併成新的 DataFrame,
data_df。 - 數據集包含一個
quality數據行,將葡萄酒評為 1 到 10,其中 10 表示品質最高。 此程式代碼會將此數據行轉換成兩個分類值:“True”,以表示高品質的葡萄酒(quality>= 7)和“False”,以表示不高品質的葡萄酒(quality< 7)。 - 將 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 曲線的繪圖:
步驟 7。 在 MLflow 中檢視實驗執行
MLflow 實驗追蹤可在您反覆式開發模型時記錄程式碼和結果,協助您追蹤模型開發。
若要從您剛執行的訓練執行中檢視記錄的結果,請按下儲存格輸出中的連結,如下圖所示。
實驗頁面可讓您比較執行,並檢視特定執行的詳細資料。 點擊執行名稱以查看該執行的參數和度量值等詳細資訊。 請參閱 MLflow 實驗追蹤。
您也可以點選筆記本右上角的實驗圖示
,來查看筆記本的實驗執行狀況。 這會開啟實驗側邊欄,其中顯示與筆記本實驗相關聯的每個執行摘要,包括執行參數和度量。 如有必要,請按兩下重新整理圖示來擷取並監視最新的執行。
實驗執行側邊欄在筆記本中顯示最新的 MLflow 執行。
步驟 8。 使用 Hyperopt 進行超參數微調
開發 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")
步驟 10. 將模型部署至生產環境
當您準備好提供和部署模型時,您可以使用 Azure Databricks 工作區中的 [服務 UI] 來執行此動作。
- 請參閱 建立自訂模型服務端點。
- 請參閱 查詢自訂模型的服務端點。
範例筆記本:建置分類模型
使用下列筆記本來執行本文章中的步驟。 如需將筆記本匯入 Azure Databricks 工作區的指示,請參閱 匯入筆記本。
使用 atabricks 建置您的第一個機器學習模型
深入了解
Databricks 提供單一平臺,提供 ML 開發和部署的每個步驟,從原始數據到推斷數據表,以儲存服務模型的每個要求和回應。 數據科學家、數據工程師、ML 工程師和DevOps可以使用同一組工具和單一事實來源來執行其工作。
若要深入了解,請參閱下列內容: