教學課程 6:使用功能存放區的網路隔離
Azure Machine Learning 受管理的功能存放區可讓您探索、建立及運作功能。 從原型設計階段開始,功能就充當著機器學習生命週期中的結締組織,您可於此階段中測試各種功能。 該生命週期會延續至運算化階段,您可於此階段中部署模型,並可透過推斷步驟查閱功能資料。 如需功能存放區的詳細資訊,請閱讀功能存放區概念文件。
本教學課程說明如何透過私人端點設定安全輸入,以及透過受控虛擬網路安全輸出。
本教學課程系列的第 1 部分示範如何使用自訂轉換來建立功能集規格,並使用該功能集來產生定型資料。 本系列的第 2 部分示範如何啟用具體化,並執行回填。 此外,第 2 部分示範如何實驗功能,以此來提升模型效能。 第 3 部分示範功能存放區如何提高實驗和定型流程的靈活性。 第 3 部分也說明如何執行批次推斷。 教學課程 4 說明如何使用功能存放區進行線上/即時推斷使用案例。 教學課程 5 示範如何使用自訂資料來源開發功能集。 教學課程 6 說明如何
- 設定受管理的功能存放區網路隔離所需資源。
- 建立新的功能存放區資源。
- 設定您的功能存放區以支援網路隔離案例。
- 更新您的專案工作區 (目前工作區) 以支援網路隔離案例。
必要條件
注意
本教學課程使用 Azure Machine Learning 筆記本搭配無伺服器 Spark 計算。
Azure Machine Learning 工作區,已針對無伺服器 Spark 作業啟用受控虛擬網路
若要設定專案工作區:
建立名為
network.yml
的 YAML 檔案:managed_network: isolation_mode: allow_internet_outbound
執行下列命令來更新工作區,並為無伺服器 Spark 作業佈建受控虛擬網路:
az ml workspace update --file network.yml --resource-group my_resource_group --name my_workspace_name az ml workspace provision-network --resource-group my_resource_group --name my_workspace_name --include-spark
如需詳細資訊,請瀏覽設定無伺服器 Spark 作業。
您的使用者帳戶必須具有指派給資源群組 (您在其中建立功能存放區) 的
Owner
或Contributor
角色。 您的使用者帳戶也需要User Access Administrator
角色。
重要
針對您的 Azure Machine Learning 工作區,請將 isolation_mode
設定為 allow_internet_outbound
。 這是唯一支援的網路隔離模式。 本教學課程會示範如何透過私人端點安全地連線至來源、具體化存放區和觀察資料。
設定
本教學課程使用 Python 功能存放區核心 SDK (azureml-featurestore
)。 Python SDK 僅用於功能集開發和測試。 CLI 可用於功能存放區、功能集和功能存放區實體的建立、讀取、更新和刪除 (CRUD) 作業。 這適用於持續整合與持續傳遞 (CI/CD) 或 GitOps 案例,因為這些案例偏好使用 CLI/YAML。
您無須針對本教學課程明確安裝這些資源,因為在此處顯示的設定指示中,conda.yaml
檔案涵蓋了所有相關資源。
若要準備筆記本環境進行開發:
使用下列命令,將 azureml-examples 存放庫複製到本機 GitHub 資源:
git clone --depth 1 https://github.com/Azure/azureml-examples
您也可以從 azureml-examples 存放庫下載 ZIP 檔案。 在此頁面上,先選取 [
code
] 下拉式清單,然後選取 [Download ZIP
]。 然後,將內容解壓縮到本機裝置上的資料夾。將功能存放區範例目錄上傳至專案工作區
- 在 Azure Machine Learning 工作區中,開啟 Azure Machine Learning 工作室 UI
- 在左側瀏覽窗格中,選取 [Notebooks]
- 在目錄清單中選取您的使用者名稱
- 選取省略號 (...),然後選取 [上傳資料夾]
- 從複製的目錄路徑中選取功能存放區範例資料夾:
azureml-examples/sdk/python/featurestore-sample
執行教學課程
選項 1:建立新的筆記本,並逐步執行本文件中的指示
選項 2:開啟現有的筆記本
featurestore_sample/notebooks/sdk_and_cli/network_isolation/Network-isolation-feature-store.ipynb
。 您可以將本文件保持開啟狀態,並從中取得更多說明和文件連結- 在頂端導覽 [計算] 下拉式清單中選取 [無伺服器 Spark 計算]。 這項作業可能需要一到兩分鐘的時間。 等候頂端的狀態列顯示 [設定工作階段]
- 選取頂端狀態列中的 [設定工作階段]
- 選取 [Python 套件]
- 選取 [上傳 Conda 檔案]
- 選取位於本機裝置上的檔案
azureml-examples/sdk/python/featurestore-sample/project/env/conda.yml
- (選擇性) 增加工作階段逾時 (以分鐘為單位的閒置時間),以減少無伺服器 Spark 叢集的啟動時間
此程式碼資料格會啟動 Spark 工作階段。 安裝所有相依性並啟動 Spark 工作階段大約需要 10 分鐘。
# Run this cell to start the spark session (any code block will start the session ). This can take around 10 mins. print("start spark session")
設定範例的根目錄
import os # Please update your alias below (or any custom directory you have uploaded the samples to). # You can find the name from the directory structure in the left navigation. root_dir = "./Users/<your_user_alias>/featurestore_sample" if os.path.isdir(root_dir): print("The folder exists.") else: print("The folder does not exist. Please create or fix the path")
設定 Azure Machine Learning CLI:
安裝 Azure Machine Learning CLI 擴充功能
# install azure ml cli extension !az extension add --name ml
驗證
# authenticate !az login
設定預設訂用帳戶
# Set default subscription import os subscription_id = os.environ["AZUREML_ARM_SUBSCRIPTION"] !az account set -s $subscription_id
注意
功能存放區工作區支援跨專案重複使用功能。 專案工作區 (目前使用的工作區) 利用特定功能存放區的功能來定型和推斷模型。 許多專案工作區可以共用並重複使用相同的功能存放區工作區。
佈建必要的資源
您可以建立新的 Azure Data Lake Storage (ADLS) Gen2 儲存體帳戶和容器,或針對功能存放區重複使用現有的儲存體帳戶和容器資源。 在實際情況中,不同的儲存體帳戶可以裝載 ADLS Gen2 容器。 這兩種選項都適用,具體取決於您的特定需求。
在本教學課程中,您會在相同的 ADLS Gen2 儲存體帳戶中建立三個不同的儲存體容器:
- 來源資料
- 離線存放區
- 觀察資料
針對來源資料、離線存放區和觀察資料,建立 ADLS Gen2 儲存體帳戶。
在下列程式碼範例中提供 Azure Data Lake Storage Gen2 儲存體帳戶的名稱。 您可以透過提供的預設設定,執行下列程式碼資料格。 您也可以選擇覆寫預設設定。
## Default Setting # We use the subscription, resource group, region of this active project workspace, # We hard-coded default resource names for creating new resources ## Overwrite # You can replace them if you want to create the resources in a different subsciprtion/resourceGroup, or use existing resources # At the minimum, provide an ADLS Gen2 storage account name for `storage_account_name` storage_subscription_id = os.environ["AZUREML_ARM_SUBSCRIPTION"] storage_resource_group_name = os.environ["AZUREML_ARM_RESOURCEGROUP"] storage_account_name = "<STORAGE_ACCOUNT_NAME>" storage_location = "eastus" storage_file_system_name_offline_store = "offline-store" storage_file_system_name_source_data = "source-data" storage_file_system_name_observation_data = "observation-data"
此程式碼資料格會建立上述程式碼資料格中定義的 ADLS Gen2 儲存體帳戶。
# Create new storage account !az storage account create --name $storage_account_name --enable-hierarchical-namespace true --resource-group $storage_resource_group_name --location $storage_location --subscription $storage_subscription_id
此程式碼資料格會為離線存放區建立新的儲存體容器。
# Create a new storage container for offline store !az storage fs create --name $storage_file_system_name_offline_store --account-name $storage_account_name --subscription $storage_subscription_id
此程式碼資料格會為來源資料建立新的儲存體容器。
# Create a new storage container for source data !az storage fs create --name $storage_file_system_name_source_data --account-name $storage_account_name --subscription $storage_subscription_id
此程式碼資料格會為觀察資料建立新的儲存體容器。
# Create a new storage container for observation data !az storage fs create --name $storage_file_system_name_observation_data --account-name $storage_account_name --subscription $storage_subscription_id
將本教學課程系列所需的範例資料複製到新建立的儲存體容器中。
若要將資料寫入儲存體容器,請確保遵循下列步驟,將參與者和儲存體 Blob 資料參與者角色指派給在 Azure 入口網站中所建立 ADLS Gen2 儲存體帳戶上的使用者身分識別。
重要
當您確保將參與者和儲存體 Blob 資料參與者角色指派給使用者身分識別後,請在角色指派後等候幾分鐘以便權限傳播,再繼續進行後續步驟。 若要深入了解存取控制,請瀏覽 Azure 儲存體帳戶的角色型存取控制 (RBAC)
下一個程式碼儲存格會將本教學課程中使用的交易功能集範例來源資料,從公用儲存體帳戶複製到新建立的儲存體帳戶。
# Copy sample source data for transactions feature set used in this tutorial series from the public storage account to the newly created storage account transactions_source_data_path = "wasbs://data@azuremlexampledata.blob.core.windows.net/feature-store-prp/datasources/transactions-source/*.parquet" transactions_src_df = spark.read.parquet(transactions_source_data_path) transactions_src_df.write.parquet( f"abfss://{storage_file_system_name_source_data}@{storage_account_name}.dfs.core.windows.net/transactions-source/" )
針對本教學課程中使用的帳戶功能集,將帳戶功能的範例來源資料複製到新建立的儲存體帳戶。
# Copy sample source data for account feature set used in this tutorial series from the public storage account to the newly created storage account accounts_data_path = "wasbs://data@azuremlexampledata.blob.core.windows.net/feature-store-prp/datasources/accounts-precalculated/*.parquet" accounts_data_df = spark.read.parquet(accounts_data_path) accounts_data_df.write.parquet( f"abfss://{storage_file_system_name_source_data}@{storage_account_name}.dfs.core.windows.net/accounts-precalculated/" )
將用於訓練的範例觀察資料,從公用儲存體帳戶複製到新建立的儲存體帳戶。
# Copy sample observation data used for training from the public storage account to the newly created storage account observation_data_train_path = "wasbs://data@azuremlexampledata.blob.core.windows.net/feature-store-prp/observation_data/train/*.parquet" observation_data_train_df = spark.read.parquet(observation_data_train_path) observation_data_train_df.write.parquet( f"abfss://{storage_file_system_name_observation_data}@{storage_account_name}.dfs.core.windows.net/train/" )
將用於批次推斷的範例觀察資料,從公用儲存體帳戶複製到新建立的儲存體帳戶。
# Copy sample observation data used for batch inference from a public storage account to the newly created storage account observation_data_inference_path = "wasbs://data@azuremlexampledata.blob.core.windows.net/feature-store-prp/observation_data/batch_inference/*.parquet" observation_data_inference_df = spark.read.parquet(observation_data_inference_path) observation_data_inference_df.write.parquet( f"abfss://{storage_file_system_name_observation_data}@{storage_account_name}.dfs.core.windows.net/batch_inference/" )
在新建立的儲存體帳戶上停用公用網路存取。
此程式碼資料格會停用稍早建立 ADLS Gen2 儲存體帳戶的公用網路存取。
# Disable the public network access for the above created ADLS Gen2 storage account !az storage account update --name $storage_account_name --resource-group $storage_resource_group_name --subscription $storage_subscription_id --public-network-access disabled
針對離線存放區、來源資料和觀察資料容器設定 ARM 識別碼。
# set the container arm id offline_store_gen2_container_arm_id = "/subscriptions/{sub_id}/resourceGroups/{rg}/providers/Microsoft.Storage/storageAccounts/{account}/blobServices/default/containers/{container}".format( sub_id=storage_subscription_id, rg=storage_resource_group_name, account=storage_account_name, container=storage_file_system_name_offline_store, ) print(offline_store_gen2_container_arm_id) source_data_gen2_container_arm_id = "/subscriptions/{sub_id}/resourceGroups/{rg}/providers/Microsoft.Storage/storageAccounts/{account}/blobServices/default/containers/{container}".format( sub_id=storage_subscription_id, rg=storage_resource_group_name, account=storage_account_name, container=storage_file_system_name_source_data, ) print(source_data_gen2_container_arm_id) observation_data_gen2_container_arm_id = "/subscriptions/{sub_id}/resourceGroups/{rg}/providers/Microsoft.Storage/storageAccounts/{account}/blobServices/default/containers/{container}".format( sub_id=storage_subscription_id, rg=storage_resource_group_name, account=storage_account_name, container=storage_file_system_name_observation_data, ) print(observation_data_gen2_container_arm_id)
建立已啟用具體化的功能存放區
設定功能存放區參數
設定功能存放區名稱、位置、訂用帳戶識別碼、群組名稱和 ARM 識別碼,如下列程式碼資料格範例所示:
# We use the subscription, resource group, region of this active project workspace.
# Optionally, you can replace them to create the resources in a different subsciprtion/resourceGroup, or use existing resources
import os
# At the minimum, define a name for the feature store
featurestore_name = "<FEATURESTORE_NAME>"
# It is recommended to create featurestore in the same location as the storage
featurestore_location = storage_location
featurestore_subscription_id = os.environ["AZUREML_ARM_SUBSCRIPTION"]
featurestore_resource_group_name = os.environ["AZUREML_ARM_RESOURCEGROUP"]
feature_store_arm_id = "/subscriptions/{sub_id}/resourceGroups/{rg}/providers/Microsoft.MachineLearningServices/workspaces/{ws_name}".format(
sub_id=featurestore_subscription_id,
rg=featurestore_resource_group_name,
ws_name=featurestore_name,
)
此程式碼儲存格會針對已啟用具體化的功能存放區產生 YAML 規格檔案。
# The below code creates a feature store with enabled materialization
import yaml
config = {
"$schema": "http://azureml/sdk-2-0/FeatureStore.json",
"name": featurestore_name,
"location": featurestore_location,
"compute_runtime": {"spark_runtime_version": "3.3"},
"offline_store": {
"type": "azure_data_lake_gen2",
"target": offline_store_gen2_container_arm_id,
},
}
feature_store_yaml = root_dir + "/featurestore/featurestore_with_offline_setting.yaml"
with open(feature_store_yaml, "w") as outfile:
yaml.dump(config, outfile, default_flow_style=False)
建立功能存放區
此程式碼資料格會使用上一個步驟中產生的 YAML 規格檔案,建立已啟用具體化的功能存放區。
!az ml feature-store create --file $feature_store_yaml --subscription $featurestore_subscription_id --resource-group $featurestore_resource_group_name
初始化 Azure Machine Learning 功能存放區核心 SDK 用戶端
在此資料格中初始化的 SDK 用戶端有助於開發及取用功能:
# feature store client
from azureml.featurestore import FeatureStoreClient
from azure.ai.ml.identity import AzureMLOnBehalfOfCredential
featurestore = FeatureStoreClient(
credential=AzureMLOnBehalfOfCredential(),
subscription_id=featurestore_subscription_id,
resource_group_name=featurestore_resource_group_name,
name=featurestore_name,
)
將角色指派給功能存放區上的使用者身分識別
請遵循下列指示,取得使用者身分識別的 Microsoft Entra 物件識別碼。 然後,在下一個命令中使用 Microsoft Entra 物件識別碼,將 AzureML 資料科學家角色指派給所建立功能存放區上的使用者身分識別。
your_aad_objectid = "<YOUR_AAD_OBJECT_ID>"
!az role assignment create --role "AzureML Data Scientist" --assignee-object-id $your_aad_objectid --assignee-principal-type User --scope $feature_store_arm_id
取得功能存放區的預設儲存體帳戶和金鑰保存庫,並停用對應資源的公用網路存取
下一個程式碼儲存格會傳回後續步驟的功能存放區物件。
fs = featurestore.feature_stores.get()
此程式碼儲存格會傳回功能存放區的預設儲存體帳戶和金鑰保存庫名稱。
# Copy the properties storage_account and key_vault from the response returned in feature store show command respectively
default_fs_storage_account_name = fs.storage_account.rsplit("/", 1)[-1]
default_key_vault_name = fs.key_vault.rsplit("/", 1)[-1]
此程式碼資料格會停用功能存放區儲存體帳戶的公用網路存取。
# Disable the public network access for the above created default ADLS Gen2 storage account for the feature store
!az storage account update --name $default_fs_storage_account_name --resource-group $featurestore_resource_group_name --subscription $featurestore_subscription_id --public-network-access disabled
下一個儲存格會列印功能存放區的預設金鑰保存庫名稱。
print(default_key_vault_name)
針對稍早建立的預設功能存放區金鑰保存庫停用公用網路存取
- 在 Azure 入口網站中,開啟您在上一個儲存格建立的預設金鑰保存庫。
- 選取 [網路] 索引標籤。
- 選取 [停用公用存取],然後選取頁面左下方的 [套用]。
啟用功能存放區工作區的受控虛擬網路
使用必要的輸出規則更新功能存放區
下一個程式碼儲存格會針對為功能存放區定義的輸出規則建立 YAML 規格檔案。
# The below code creates a configuration for managed virtual network for the feature store
import yaml
config = {
"public_network_access": "disabled",
"managed_network": {
"isolation_mode": "allow_internet_outbound",
"outbound_rules": [
# You need to add multiple rules here if you have separate storage account for source, observation data and offline store.
{
"name": "sourcerulefs",
"destination": {
"spark_enabled": "true",
"subresource_target": "dfs",
"service_resource_id": f"/subscriptions/{storage_subscription_id}/resourcegroups/{storage_resource_group_name}/providers/Microsoft.Storage/storageAccounts/{storage_account_name}",
},
"type": "private_endpoint",
},
# This rule is added currently because serverless Spark doesn't automatically create a private endpoint to default key vault.
{
"name": "defaultkeyvault",
"destination": {
"spark_enabled": "true",
"subresource_target": "vault",
"service_resource_id": f"/subscriptions/{featurestore_subscription_id}/resourcegroups/{featurestore_resource_group_name}/providers/Microsoft.Keyvault/vaults/{default_key_vault_name}",
},
"type": "private_endpoint",
},
],
},
}
feature_store_managed_vnet_yaml = (
root_dir + "/featurestore/feature_store_managed_vnet_config.yaml"
)
with open(feature_store_managed_vnet_yaml, "w") as outfile:
yaml.dump(config, outfile, default_flow_style=False)
此程式碼儲存格會使用產生的 YAML 規格檔案來更新功能存放區。
!az ml feature-store update --file $feature_store_managed_vnet_yaml --name $featurestore_name --resource-group $featurestore_resource_group_name
針對定義的輸出規則建立私人端點
provision-network
命令會針對功能存放區,建立從受控虛擬網路 (其中會執行具體化作業) 到來源、離線存放區、觀察資料、預設儲存體帳戶以及預設金鑰保存庫的私人端點。 此命令可能需要約 20 分鐘才能完成。
#### Provision network to create necessary private endpoints (it may take approximately 20 minutes)
!az ml feature-store provision-network --name $featurestore_name --resource-group $featurestore_resource_group_name --include-spark
此程式碼儲存格確認已建立輸出規則所定義的私人端點。
### Check that managed virtual network is correctly enabled
### After provisioning the network, all the outbound rules should become active
### For this tutorial, you will see 6 outbound rules
!az ml feature-store show --name $featurestore_name --resource-group $featurestore_resource_group_name
更新專案工作區的受控虛擬網路
接下來,更新專案工作區的受控虛擬網路。 首先,取得專案工作區的訂用帳戶識別碼、資源群組和工作區名稱。
# lookup the subscription id, resource group and workspace name of the current workspace
project_ws_sub_id = os.environ["AZUREML_ARM_SUBSCRIPTION"]
project_ws_rg = os.environ["AZUREML_ARM_RESOURCEGROUP"]
project_ws_name = os.environ["AZUREML_ARM_WORKSPACE_NAME"]
使用必要的輸出規則更新專案工作區
專案工作區需要下列資源的存取權限:
- 來源資料
- 離線存放區
- 觀察資料
- 功能存放區
- 功能存放區的預設儲存體帳戶
此程式碼資料格會使用產生的 YAML 規格檔案與必要的輸出規則來更新專案工作區。
# The below code creates a configuration for managed virtual network for the project workspace
import yaml
config = {
"managed_network": {
"isolation_mode": "allow_internet_outbound",
"outbound_rules": [
# Incase you have separate storage accounts for source, observation data and offline store, you need to add multiple rules here. No action needed otherwise.
{
"name": "projectsourcerule",
"destination": {
"spark_enabled": "true",
"subresource_target": "dfs",
"service_resource_id": f"/subscriptions/{storage_subscription_id}/resourcegroups/{storage_resource_group_name}/providers/Microsoft.Storage/storageAccounts/{storage_account_name}",
},
"type": "private_endpoint",
},
# Rule to create private endpoint to default storage of feature store
{
"name": "defaultfsstoragerule",
"destination": {
"spark_enabled": "true",
"subresource_target": "blob",
"service_resource_id": f"/subscriptions/{featurestore_subscription_id}/resourcegroups/{featurestore_resource_group_name}/providers/Microsoft.Storage/storageAccounts/{default_fs_storage_account_name}",
},
"type": "private_endpoint",
},
# Rule to create private endpoint to default key vault of feature store
{
"name": "defaultfskeyvaultrule",
"destination": {
"spark_enabled": "true",
"subresource_target": "vault",
"service_resource_id": f"/subscriptions/{featurestore_subscription_id}/resourcegroups/{featurestore_resource_group_name}/providers/Microsoft.Keyvault/vaults/{default_key_vault_name}",
},
"type": "private_endpoint",
},
# Rule to create private endpoint to feature store
{
"name": "featurestorerule",
"destination": {
"spark_enabled": "true",
"subresource_target": "amlworkspace",
"service_resource_id": f"/subscriptions/{featurestore_subscription_id}/resourcegroups/{featurestore_resource_group_name}/providers/Microsoft.MachineLearningServices/workspaces/{featurestore_name}",
},
"type": "private_endpoint",
},
],
}
}
project_ws_managed_vnet_yaml = (
root_dir + "/featurestore/project_ws_managed_vnet_config.yaml"
)
with open(project_ws_managed_vnet_yaml, "w") as outfile:
yaml.dump(config, outfile, default_flow_style=False)
此程式碼資料格會使用產生的 YAML 規格檔案與輸出規則來更新專案工作區。
#### Update project workspace to create private endpoints for the defined outbound rules (it may take approximately 15 minutes)
!az ml workspace update --file $project_ws_managed_vnet_yaml --name $project_ws_name --resource-group $project_ws_rg
此程式碼儲存格確認已建立輸出規則所定義的私人端點。
!az ml workspace show --name $project_ws_name --resource-group $project_ws_rg
您也可以從 Azure 入口網站驗證輸出規則。 從專案工作區的左側導覽面板瀏覽至 [網路],然後開啟 [工作區受控輸出存取] 索引標籤。
交易滾動彙總功能集的原型設計與開發
探索交易來源資料
注意
可公開存取的 Blob 容器會裝載本教學課程中使用的範例資料。 其只能透過 wasbs
驅動程式在 Spark 中讀取。 當您使用自己的來源資料建立功能集時,請將功能集裝載在 ADLS Gen2 帳戶中,並在資料路徑中使用 abfss
驅動程式。
# remove the "." in the root directory path as we need to generate absolute path to read from Spark
transactions_source_data_path = f"abfss://{storage_file_system_name_source_data}@{storage_account_name}.dfs.core.windows.net/transactions-source/*.parquet"
transactions_src_df = spark.read.parquet(transactions_source_data_path)
display(transactions_src_df.head(5))
# Note: display(training_df.head(5)) displays the timestamp column in a different format. You can can call transactions_src_df.show() to see correctly formatted value
在本機開發交易功能集
功能集規格是可在本機開發和測試的獨立功能集定義。
建立下列滾動時段彙總功能:
- 交易三天計數
- 交易金額三天總和
- 交易金額三天平均
- 交易七天計數
- 交易金額七天總和
- 交易金額七天平均
檢查功能轉換程式碼檔案 featurestore/featuresets/transactions/spec/transformation_code/transaction_transform.py
。 此 Spark 轉換器會執行針對功能定義的滾動彙總。
如需功能集和轉換的詳細資訊,請瀏覽功能存放區概念。
from azureml.featurestore import create_feature_set_spec, FeatureSetSpec
from azureml.featurestore.contracts import (
DateTimeOffset,
FeatureSource,
TransformationCode,
Column,
ColumnType,
SourceType,
TimestampColumn,
)
transactions_featureset_code_path = (
root_dir + "/featurestore/featuresets/transactions/transformation_code"
)
transactions_featureset_spec = create_feature_set_spec(
source=FeatureSource(
type=SourceType.parquet,
path=f"abfss://{storage_file_system_name_source_data}@{storage_account_name}.dfs.core.windows.net/transactions-source/*.parquet",
timestamp_column=TimestampColumn(name="timestamp"),
source_delay=DateTimeOffset(days=0, hours=0, minutes=20),
),
transformation_code=TransformationCode(
path=transactions_featureset_code_path,
transformer_class="transaction_transform.TransactionFeatureTransformer",
),
index_columns=[Column(name="accountID", type=ColumnType.string)],
source_lookback=DateTimeOffset(days=7, hours=0, minutes=0),
temporal_join_lookback=DateTimeOffset(days=1, hours=0, minutes=0),
infer_schema=True,
)
# Generate a spark dataframe from the feature set specification
transactions_fset_df = transactions_featureset_spec.to_spark_dataframe()
# display few records
display(transactions_fset_df.head(5))
匯出功能集規格
若要向功能存放區註冊功能集規格,該規格必須以特定格式儲存。
若要檢查產生的交易功能集規格,請從檔案樹狀結構開啟此檔案,以檢視規格:
featurestore/featuresets/accounts/spec/FeaturesetSpec.yaml
規格包含下列元素:
source
:儲存體資源的參考,在本案例中是 Blob 儲存體資源中的 parquet 檔案features
:功能及其資料類型的清單。 若您提供轉換程序碼index_columns
:要從功能集存取值所需的聯結索引鍵
將功能集規格儲存為 YAML 檔案的另一個優點是,可以對規格執行版本控制。 若要深入了解功能集規格,請參閱最上層功能存放區實體文件和功能集規格 YAML 參考。
import os
# create a new folder to dump the feature set specification
transactions_featureset_spec_folder = (
root_dir + "/featurestore/featuresets/transactions/spec"
)
# check if the folder exists, create one if not
if not os.path.exists(transactions_featureset_spec_folder):
os.makedirs(transactions_featureset_spec_folder)
transactions_featureset_spec.dump(transactions_featureset_spec_folder, overwrite=True)
註冊功能存放區實體
實體有助於在使用相同邏輯實體的功能集中,強制使用相同的聯結索引鍵定義。 實體範例包括帳戶實體、客戶實體等。一般會建立一次實體,然後跨功能集重複使用。 如需詳細資訊,請瀏覽最上層功能存放區實體文件。
此程式碼資料格會建立功能存放區的帳戶實體。
account_entity_path = root_dir + "/featurestore/entities/account.yaml"
!az ml feature-store-entity create --file $account_entity_path --resource-group $featurestore_resource_group_name --workspace-name $featurestore_name
向功能存放區註冊交易功能集,並提交具體化作業
若要共用和重複使用功能集資產,您必須先向功能存放區註冊該資產。 功能集資產註冊可提供受控功能,包括版本設定和具體化。 本教學課程系列涵蓋這些主題。
功能集資產會參考您稍早建立的功能集規格,以及其他屬性 - 例如版本和具體化設定。
建立功能集
下一個程式碼儲存格會使用預先定義的 YAML 規格檔案來建立功能集。
transactions_featureset_path = (
root_dir
+ "/featurestore/featuresets/transactions/featureset_asset_offline_enabled.yaml"
)
!az ml feature-set create --file $transactions_featureset_path --resource-group $featurestore_resource_group_name --workspace-name $featurestore_name
此程式碼資料格會預覽新建立的功能集。
# Preview the newly created feature set
!az ml feature-set show --resource-group $featurestore_resource_group_name --workspace-name $featurestore_name -n transactions -v 1
提交回填具體化作業
下一個程式碼儲存格會定義功能具體化視窗的開始和結束時間值,並提交回填具體化作業。
feature_window_start_time = "2023-02-01T00:00.000Z"
feature_window_end_time = "2023-03-01T00:00.000Z"
!az ml feature-set backfill --name transactions --version 1 --by-data-status "['None']" --workspace-name $featurestore_name --resource-group $featurestore_resource_group_name --feature-window-start-time $feature_window_start_time --feature-window-end-time $feature_window_end_time
此程式碼儲存格提供 <JOB_ID_FROM_PREVIOUS_COMMAND>
來檢查回填具體化作業的狀態。
### Check the job status
!az ml job show --name <JOB_ID_FROM_PREVIOUS_COMMAND> -g $featurestore_resource_group_name -w $featurestore_name
此程式碼儲存格會列出目前功能集的所有具體化作業。
### List all the materialization jobs for the current feature set
!az ml feature-set list-materialization-operation --name transactions --version 1 -g $featurestore_resource_group_name -w $featurestore_name
將 Azure Cache for Redis 附加為線上存放區
建立 Azure Cache for Redis
在下一個程式碼儲存格中,定義要建立或重複使用的 Azure Cache for Redis 名稱。 您也可以選擇覆寫其他預設設定。
redis_subscription_id = os.environ["AZUREML_ARM_SUBSCRIPTION"]
redis_resource_group_name = os.environ["AZUREML_ARM_RESOURCEGROUP"]
redis_name = "my-redis"
redis_location = storage_location
您可以選取 Redis 快取層 (基本、標準或進階)。 您應該選擇可供所選快取層使用的 SKU 系列。 有關選擇不同層如何影響快取效能的詳細資訊,請瀏覽本文件資源。 如需不同 SKU 層和 Azure Cache for Redis 系列價格的詳細資訊,請瀏覽此文件資源。
執行下列此程式碼儲存格,以建立具有進階層、SKU 系列 P
和快取容量 2 的 Azure Cache for Redis。 佈建 Redis 執行個體可能需要大約 5-10 分鐘的時間。
# Create new redis cache
from azure.mgmt.redis import RedisManagementClient
from azure.mgmt.redis.models import RedisCreateParameters, Sku, SkuFamily, SkuName
management_client = RedisManagementClient(
AzureMLOnBehalfOfCredential(), redis_subscription_id
)
# It usually takes about 5 - 10 min to finish the provision of the Redis instance.
# If the following begin_create() call still hangs for longer than that,
# please check the status of the Redis instance on the Azure portal and cancel the cell if the provision has completed.
# This sample uses a PREMIUM tier Redis SKU from family P, which may cost more than a STANDARD tier SKU from family C.
# Please choose the SKU tier and family according to your performance and pricing requirements.
redis_arm_id = (
management_client.redis.begin_create(
resource_group_name=redis_resource_group_name,
name=redis_name,
parameters=RedisCreateParameters(
location=redis_location,
sku=Sku(name=SkuName.PREMIUM, family=SkuFamily.P, capacity=2),
public_network_access="Disabled", # can only disable PNA to redis cache during creation
),
)
.result()
.id
)
print(redis_arm_id)
使用線上存放區更新功能存放區
將 Azure Cache for Redis 附加至功能存放區,以作為線上具體化存放區使用。 下一個程式碼儲存格會針對為功能存放區定義的線上存放區輸出規則建立 YAML 規格檔案。
# The following code cell creates a YAML specification file for outbound rules that are defined for the feature store.
## rule 1: PE to online store (redis cache): this is optional if online store is not used
import yaml
config = {
"public_network_access": "disabled",
"managed_network": {
"isolation_mode": "allow_internet_outbound",
"outbound_rules": [
{
"name": "sourceruleredis",
"destination": {
"spark_enabled": "true",
"subresource_target": "redisCache",
"service_resource_id": f"/subscriptions/{storage_subscription_id}/resourcegroups/{storage_resource_group_name}/providers/Microsoft.Cache/Redis/{redis_name}",
},
"type": "private_endpoint",
},
],
},
"online_store": {"target": f"{redis_arm_id}", "type": "redis"},
}
feature_store_managed_vnet_yaml = (
root_dir + "/featurestore/feature_store_managed_vnet_config.yaml"
)
with open(feature_store_managed_vnet_yaml, "w") as outfile:
yaml.dump(config, outfile, default_flow_style=False)
下一個程式碼儲存格會使用產生的 YAML 規格檔案與為線上存放區的輸出規則來更新功能存放區。
!az ml feature-store update --file $feature_store_managed_vnet_yaml --name $featurestore_name --resource-group $featurestore_resource_group_name
更新專案工作區輸出規則
專案工作區需要線上存放區的存取權限。 下列程式碼儲存格會針對專案工作區的必要輸出規則建立 YAML 規格檔案。
import yaml
config = {
"managed_network": {
"isolation_mode": "allow_internet_outbound",
"outbound_rules": [
{
"name": "onlineruleredis",
"destination": {
"spark_enabled": "true",
"subresource_target": "redisCache",
"service_resource_id": f"/subscriptions/{storage_subscription_id}/resourcegroups/{storage_resource_group_name}/providers/Microsoft.Cache/Redis/{redis_name}",
},
"type": "private_endpoint",
},
],
}
}
project_ws_managed_vnet_yaml = (
root_dir + "/featurestore/project_ws_managed_vnet_config.yaml"
)
with open(project_ws_managed_vnet_yaml, "w") as outfile:
yaml.dump(config, outfile, default_flow_style=False)
執行下一個程式碼儲存格會使用產生的 YAML 規格檔案與為線上存放區的輸出規則來更新專案工作區。
#### Update project workspace to create private endpoints for the defined outbound rules (it may take approximately 15 minutes)
!az ml workspace update --file $project_ws_managed_vnet_yaml --name $project_ws_name --resource-group $project_ws_rg
將交易功能集具體化為線上存放區
下一個程式碼儲存格會啟用 transactions
功能集線上具體化。
# Update featureset to enable online materialization
transactions_featureset_path = (
root_dir
+ "/featurestore/featuresets/transactions/featureset_asset_online_enabled.yaml"
)
!az ml feature-set update --file $transactions_featureset_path --resource-group $featurestore_resource_group_name --workspace-name $featurestore_name
下一個程式碼儲存格會定義功能具體化視窗的開始和結束時間值,並提交回填具體化作業。
feature_window_start_time = "2024-01-24T00:00.000Z"
feature_window_end_time = "2024-01-25T00:00.000Z"
!az ml feature-set backfill --name transactions --version 1 --by-data-status "['None']" --feature-window-start-time $feature_window_start_time --feature-window-end-time $feature_window_end_time --feature-store-name $featurestore_name --resource-group $featurestore_resource_group_name
使用已註冊的功能來產生定型資料
載入觀察資料
首先,探索觀察資料。 用於定型和推斷的核心資料通常涉及觀察資料。 該資料接著會與功能資料聯結,藉此建立完整的訓練資料資源。 觀察資料是在事件發生期間擷取的資料。 在此案例中,其具有核心交易資料,包括交易識別碼、帳戶識別碼和交易金額值。 在此處,由於觀察資料用於定型,因此也會附加目標變數 (is_fraud
)。
observation_data_path = f"abfss://{storage_file_system_name_observation_data}@{storage_account_name}.dfs.core.windows.net/train/*.parquet"
observation_data_df = spark.read.parquet(observation_data_path)
obs_data_timestamp_column = "timestamp"
display(observation_data_df)
# Note: the timestamp column is displayed in a different format. Optionally, you can can call training_df.show() to see correctly formatted value
取得已註冊的功能集,並列出其功能
接下來,透過提供其名稱和版本來取得功能集,然後列出此功能集中的功能。 此外,也列印一些範例功能值。
# look up the featureset by providing name and version
transactions_featureset = featurestore.feature_sets.get("transactions", "1")
# list its features
transactions_featureset.features
# print sample values
display(transactions_featureset.to_spark_dataframe().head(5))
選取功能並產生定型資料
選取定型資料的功能,並使用功能存放區 SDK 來產生定型資料。
from azureml.featurestore import get_offline_features
# you can select features in pythonic way
features = [
transactions_featureset.get_feature("transaction_amount_7d_sum"),
transactions_featureset.get_feature("transaction_amount_7d_avg"),
]
# you can also specify features in string form: featurestore:featureset:version:feature
more_features = [
"transactions:1:transaction_3d_count",
"transactions:1:transaction_amount_3d_avg",
]
more_features = featurestore.resolve_feature_uri(more_features)
features.extend(more_features)
# generate training dataframe by using feature data and observation data
training_df = get_offline_features(
features=features,
observation_data=observation_data_df,
timestamp_column=obs_data_timestamp_column,
)
# Ignore the message that says feature set is not materialized (materialization is optional). We will enable materialization in the next part of the tutorial.
display(training_df)
# Note: the timestamp column is displayed in a different format. Optionally, you can can call training_df.show() to see correctly formatted value
時間點聯結會將功能附加至訓練資料。
選擇性的後續步驟
既然您已成功建立安全功能存放區並提交成功的具體化執行,您可以透過教學課程系列掌握功能存放區的相關知識。
本教學課程結合了本系列教學課程 1 和 2 中的步驟。 請記得將其他教學課程筆記本中使用的必要公用儲存體容器替換為本教學課程筆記本中所建立的公用儲存體容器,才能實現網路隔離。
這個教學課程結束。 您的定型資料使用功能存放區的功能。 您可以將其儲存至儲存體以供日後使用,或直接對其執行模型定型。