チュートリアル: 1 日でわかる Azure Machine Learning

適用対象: Python SDK azure-ai-ml v2 (現行)

データ サイエンティストがどのように Azure Machine Learning を使用してモデルをトレーニングし、そのモデルを予測に使用するかについて説明します。 このチュートリアルは、Azure Machine Learning の主要な概念とその最も一般的な使用方法を理解するのに役立ちます。

スクリプトの実行に必要な "ジョブ環境" を使用して構成された、指定の "コンピューティング リソース" で "トレーニング スクリプト" を実行する "コマンド ジョブ" を送信する方法について説明します。

"トレーニング スクリプト" では、データの準備を行った後、モデルをトレーニングして登録します。 モデルが完成したら "エンドポイント" としてデプロイし、そのエンドポイントを推論用に呼び出します。

これを実行する手順は次のとおりです。

  • Azure Machine Learning ワークスペースに接続する
  • コンピューティング リソースとジョブ環境を作成する
  • トレーニング スクリプトを作成する
  • 適切なジョブ環境を使用して構成されたコンピューティング リソースでトレーニング スクリプトを実行するコマンド ジョブを作成して実行する
  • トレーニング スクリプトの出力を表示する
  • 新しくトレーニングされたモデルをエンドポイントとしてデプロイする
  • 推論のために Azure Machine Learning エンドポイントを呼び出す

前提条件

ノートブックを実行する

  1. 上部のバーで、クイック スタート: Azure Machine Learning の使用開始に関する記事で作成したコンピューティング インスタンスを選択して、ノートブックの実行に使用します。

  2. 右上にあるカーネルが Python 3.10 - SDK v2 であることを確認します。 そうでない場合は、ドロップダウンを使用してこのカーネルを選択します。

スクリーンショット: カーネルを設定します。

重要

このチュートリアルの残りの部分には、チュートリアル ノートブックのセルが含まれています。 それらを新しいノートブックにコピー/貼り付けするか、複製した場合はここでそのノートブックに切り替えます。

ノートブックで単一のコード セルを実行するには、そのコード セルをクリックして Shift + Enter キーを押します。 または、上部のツール バーから [すべて実行] を選択して、ノートブック全体を実行します。

ワークスペースに接続する

コードを詳しく見る前に、Azure Machine Learning ワークスペースに接続する必要があります。 ワークスペースは、Azure Machine Learning の最上位のリソースで、Azure Machine Learning を使用するときに作成するすべての成果物を操作するための一元的な場所を提供します。

ここでは、DefaultAzureCredential を使ってワークスペースへのアクセスを取得しています。 DefaultAzureCredential を使用すると、ほとんどの Azure SDK 認証シナリオを処理できます。

# Handle to the workspace
from azure.ai.ml import MLClient

# Authentication package
from azure.identity import DefaultAzureCredential

credential = DefaultAzureCredential()

次のセルに、サブスクリプション ID、リソース グループ名、ワークスペース名を入力します。 これらの値を見つけるには:

  1. 右上隅の Azure Machine Learning スタジオ ツール バーで、ワークスペース名を選びます。
  2. ワークスペース、リソース グループ、サブスクリプション ID の値をコードにコピーします。
  3. 1 つの値をコピーし、領域を閉じて貼り付けてから、戻って次のものを処理する必要があります。

スクリーンショット: ツール バーの右上にあるコードの資格情報を見つけます。

# Get a handle to the workspace
ml_client = MLClient(
    credential=credential,
    subscription_id="<SUBSCRIPTION_ID>",
    resource_group_name="<RESOURCE_GROUP>",
    workspace_name="<AML_WORKSPACE_NAME>",
)

その結果、他のリソースとジョブを管理するために使うワークスペースに対するハンドラーになります。

重要

MLClient を作成しても、ワークスペースには接続されません。 クライアントの初期化は遅延型なので、初めて呼び出す必要が生じるときまで待機します (以下のノートブックでは、コンピューティングの作成時に行われます)。

ジョブを実行するコンピューティング リソースを作成する

ジョブを実行するにはコンピューティング リソースが必要です。 Linux または Windows OS の単一または複数ノードのマシン、または Spark などの特定のコンピューティング ファブリックを使用できます。

Linux コンピューティング クラスターをプロビジョニングします。 VM のサイズと価格の完全な一覧を参照してください。

この例では、基本的なクラスターのみが必要なので、2 つの vCPU コア、7 GB RAM の Standard_DS3_v2 モデルを使用し、Azure Machine Learning コンピューティングを作成します。

from azure.ai.ml.entities import AmlCompute

# Name assigned to the compute cluster
cpu_compute_target = "cpu-cluster"

try:
    # let's see if the compute target already exists
    cpu_cluster = ml_client.compute.get(cpu_compute_target)
    print(
        f"You already have a cluster named {cpu_compute_target}, we'll reuse it as is."
    )

except Exception:
    print("Creating a new cpu compute target...")

    # Let's create the Azure ML compute object with the intended parameters
    cpu_cluster = AmlCompute(
        name=cpu_compute_target,
        # Azure ML Compute is the on-demand VM service
        type="amlcompute",
        # VM Family
        size="STANDARD_DS3_V2",
        # Minimum running nodes when there is no job running
        min_instances=0,
        # Nodes in cluster
        max_instances=4,
        # How many seconds will the node running after the job termination
        idle_time_before_scale_down=180,
        # Dedicated or LowPriority. The latter is cheaper but there is a chance of job termination
        tier="Dedicated",
    )
    print(
        f"AMLCompute with name {cpu_cluster.name} will be created, with compute size {cpu_cluster.size}"
    )
    # Now, we pass the object to MLClient's create_or_update method
    cpu_cluster = ml_client.compute.begin_create_or_update(cpu_cluster)

ジョブ環境を作成する

コンピューティング リソースで Azure Machine Learning ジョブを実行するには、環境が必要です。 環境には、トレーニングするコンピューティングにインストールするソフトウェア ランタイムとライブラリが一覧表示されます。 これは、ローカル コンピューター上の Python 環境に似ています。

Azure Machine Learning には、キュレーションまたは既製の環境が多数用意されていて、一般的なトレーニングと推論のシナリオに役立ちます。 また、Docker イメージまたは conda 構成を使用して独自のカスタム環境を作成することもできます。

この例では、conda yaml ファイルを使って、ジョブ用のカスタム conda 環境を作成します。

まず、ファイルを格納するディレクトリを作成します。

import os

dependencies_dir = "./dependencies"
os.makedirs(dependencies_dir, exist_ok=True)

次に、依存関係ディレクトリにファイルを作成します。 次のセルでは、IPython マジックを使用して、先ほど作成したディレクトリにファイルを書き込みます。

%%writefile {dependencies_dir}/conda.yml
name: model-env
channels:
  - conda-forge
dependencies:
  - python=3.8
  - numpy=1.21.2
  - pip=21.2.4
  - scikit-learn=0.24.2
  - scipy=1.7.1
  - pandas>=1.1,<1.2
  - pip:
    - inference-schema[numpy-support]==1.3.0
    - xlrd==2.0.1
    - mlflow== 1.26.1
    - azureml-mlflow==1.42.0
    - psutil>=5.8,<5.9
    - tqdm>=4.59,<4.60
    - ipykernel~=6.0
    - matplotlib

この仕様には、ジョブで使ういくつかの通常のパッケージ (numpy や pip など) が含まれています。

この yaml ファイルを参照してこのカスタム環境を作成し、ワークスペースに登録します。

from azure.ai.ml.entities import Environment

custom_env_name = "aml-scikit-learn"

pipeline_job_env = Environment(
    name=custom_env_name,
    description="Custom environment for Credit Card Defaults pipeline",
    tags={"scikit-learn": "0.24.2"},
    conda_file=os.path.join(dependencies_dir, "conda.yml"),
    image="mcr.microsoft.com/azureml/openmpi3.1.2-ubuntu18.04:latest",
)
pipeline_job_env = ml_client.environments.create_or_update(pipeline_job_env)

print(
    f"Environment with name {pipeline_job_env.name} is registered to workspace, the environment version is {pipeline_job_env.version}"
)

コマンド ジョブとは

Azure Machine Learning "コマンド ジョブ" は、クレジットの既定の予測に関するモデルをトレーニングするために作成します。 コマンド ジョブを使用して、指定されたコンピューティング リソースに対して指定の環境で "トレーニング スクリプト" を実行します。 環境とコンピューティング リソースは既に作成しています。 次に、トレーニング スクリプトを作成します。

この "トレーニング スクリプト"を使って、データの準備、トレーニング、トレーニングされたモデルの登録を処理します。 このチュートリアルでは、Python トレーニング スクリプトを作成します。

コマンド ジョブは、CLI、Python SDK、またはスタジオ インターフェイスから実行できます。 このチュートリアルでは、Azure Machine Learning Python SDK v2 を使用し、コマンド ジョブを作成して実行します。

トレーニング ジョブを実行したら、モデルをデプロイし、それを使用して予測を生成します。

トレーニング スクリプトを作成する

まず、トレーニング スクリプト main.py Python ファイルを作成します。

最初にスクリプトのソース フォルダーを作成します。

import os

train_src_dir = "./src"
os.makedirs(train_src_dir, exist_ok=True)

このスクリプトを使用して、データの前処理を行い、それをテストとトレーニングのデータに分割します。 次に、このデータを使用してツリー ベースのモデルをトレーニングし、出力モデルを返します。

MLFlow は、パイプラインの実行中にパラメーターとメトリックをログに記録するために使われます。

次のセルでは、IPython マジックを使用して、作成したディレクトリにトレーニング スクリプトを書き込みます。

%%writefile {train_src_dir}/main.py
import os
import argparse
import pandas as pd
import mlflow
import mlflow.sklearn
from sklearn.ensemble import GradientBoostingClassifier
from sklearn.metrics import classification_report
from sklearn.model_selection import train_test_split

def main():
    """Main function of the script."""

    # input and output arguments
    parser = argparse.ArgumentParser()
    parser.add_argument("--data", type=str, help="path to input data")
    parser.add_argument("--test_train_ratio", type=float, required=False, default=0.25)
    parser.add_argument("--n_estimators", required=False, default=100, type=int)
    parser.add_argument("--learning_rate", required=False, default=0.1, type=float)
    parser.add_argument("--registered_model_name", type=str, help="model name")
    args = parser.parse_args()
   
    # Start Logging
    mlflow.start_run()

    # enable autologging
    mlflow.sklearn.autolog()

    ###################
    #<prepare the data>
    ###################
    print(" ".join(f"{k}={v}" for k, v in vars(args).items()))

    print("input data:", args.data)
    
    credit_df = pd.read_excel(args.data, header=1, index_col=0)

    mlflow.log_metric("num_samples", credit_df.shape[0])
    mlflow.log_metric("num_features", credit_df.shape[1] - 1)

    train_df, test_df = train_test_split(
        credit_df,
        test_size=args.test_train_ratio,
    )
    ####################
    #</prepare the data>
    ####################

    ##################
    #<train the model>
    ##################
    # Extracting the label column
    y_train = train_df.pop("default payment next month")

    # convert the dataframe values to array
    X_train = train_df.values

    # Extracting the label column
    y_test = test_df.pop("default payment next month")

    # convert the dataframe values to array
    X_test = test_df.values

    print(f"Training with data of shape {X_train.shape}")

    clf = GradientBoostingClassifier(
        n_estimators=args.n_estimators, learning_rate=args.learning_rate
    )
    clf.fit(X_train, y_train)

    y_pred = clf.predict(X_test)

    print(classification_report(y_test, y_pred))
    ###################
    #</train the model>
    ###################

    ##########################
    #<save and register model>
    ##########################
    # Registering the model to the workspace
    print("Registering the model via MLFlow")
    mlflow.sklearn.log_model(
        sk_model=clf,
        registered_model_name=args.registered_model_name,
        artifact_path=args.registered_model_name,
    )

    # Saving the model to a file
    mlflow.sklearn.save_model(
        sk_model=clf,
        path=os.path.join(args.registered_model_name, "trained_model"),
    )
    ###########################
    #</save and register model>
    ###########################
    
    # Stop Logging
    mlflow.end_run()

if __name__ == "__main__":
    main()

このスクリプトでわかるように、モデルのトレーニングが完了すると、モデル ファイルが保存され、ワークスペースに登録されます。 これで、登録したモデルを推論エンドポイントで使用できるようになりました。

コマンドを構成する

目的のタスクを実行できるスクリプトが用意されたので、コマンド ライン アクションを実行できる汎用コマンドを使用します。 このコマンドライン アクションで、直接、またはスクリプトを実行して、システム コマンドを呼び出すことができます。

ここでは、入力データ、分割率、学習率、登録されたモデル名を指定する入力変数を作成します。 このコマンド スクリプトで以下を行います。

  • 前に作成したコンピューティングを使用して、このコマンドを実行します。
  • 前に作成した環境を使用します。@latest 表記を使用すると、コマンドの実行時におけるその環境の最新バージョンを示すことができます。
  • 表示名、実験名などのメタデータを構成します。"実験" は、特定のプロジェクトで行うすべてのイテレーションのコンテナーです。 同じ実験名で送信されたすべてのジョブは、Azure Machine Learning スタジオ上ではすべて隣り合わせに表示されます。
  • コマンド ライン アクション自体を構成します。この場合は python main.py です。 入出力には、コマンドで ${{ ... }} 表記を使ってアクセスできます。
from azure.ai.ml import command
from azure.ai.ml import Input

registered_model_name = "credit_defaults_model"

job = command(
    inputs=dict(
        data=Input(
            type="uri_file",
            path="https://archive.ics.uci.edu/ml/machine-learning-databases/00350/default%20of%20credit%20card%20clients.xls",
        ),
        test_train_ratio=0.2,
        learning_rate=0.25,
        registered_model_name=registered_model_name,
    ),
    code="./src/",  # location of source code
    command="python main.py --data ${{inputs.data}} --test_train_ratio ${{inputs.test_train_ratio}} --learning_rate ${{inputs.learning_rate}} --registered_model_name ${{inputs.registered_model_name}}",
    environment="aml-scikit-learn@latest",
    compute="cpu-cluster",
    experiment_name="train_model_credit_default_prediction",
    display_name="credit_default_prediction",
)

ジョブを送信する

次に、Azure Machine Learning で実行するジョブを送信します。 今回は ml_client.jobs に対して create_or_update を使います。

ml_client.create_or_update(job)

ジョブの出力を表示してジョブの完了を待機する

前のセルの出力内のリンクを選択して、Azure Machine Learning スタジオでジョブを表示します。

このジョブの出力は、Azure Machine Learning スタジオではこのようになります。 メトリック、出力などのさまざまな詳細のタブを調べます。完了すると、ジョブで、トレーニングの結果としてモデルがワークスペースに登録されます。

ジョブの概要を示すスクリーンショット

重要

ジョブの状態が完了になるまで待ってから、このノートブックに戻って続行します。 ジョブの実行には 2 から 3 分かかります。 コンピューティング クラスターが 0 ノードにスケールダウンされ、カスタム環境がまだ構築中である場合は、さらに長く (最大 10 分) かかることがあります。

モデルをオンライン エンドポイントとしてデプロイする

次に、機械学習モデルを Web サービス (online endpoint) として Azure クラウドにデプロイします。

通常、機械学習サービスをデプロイするには、以下のものが必要です。

  • デプロイするモデル資産 (ファイル、メタデータ)。 これらの資産は、トレーニング ジョブに既に登録されています。
  • サービスとして実行するコード。 このコードを使って、指定した入力要求に対してモデルを実行します。 このエントリ スクリプトは、デプロイされた Web サービスに送信されたデータを受け取り、それをモデルに渡し、モデルの応答をクライアントに返します。 このスクリプトはこのモデルに固有のものです。 エントリ スクリプトでは、モデルが受け入れ、返すデータを認識する必要があります。 MLFlow モデルの場合、このチュートリアルのように、このスクリプトは自動的に作成されます。 スコアリング スクリプトのサンプルについては、こちらを参照してください。

新しいオンライン エンドポイントを作成する

登録されたモデルと推論スクリプトを用意できたので、次はオンライン エンドポイントを作成します。 エンドポイント名は、Azure リージョン全体で一意である必要があります。 このチュートリアルでは、UUID を使って一意の名前を作成します。

import uuid

# Creating a unique name for the endpoint
online_endpoint_name = "credit-endpoint-" + str(uuid.uuid4())[:8]

Note

エンドポイントの作成には約 6 から 8 分かかります。

from azure.ai.ml.entities import (
    ManagedOnlineEndpoint,
    ManagedOnlineDeployment,
    Model,
    Environment,
)

# create an online endpoint
endpoint = ManagedOnlineEndpoint(
    name=online_endpoint_name,
    description="this is an online endpoint",
    auth_mode="key",
    tags={
        "training_dataset": "credit_defaults",
        "model_type": "sklearn.GradientBoostingClassifier",
    },
)

endpoint = ml_client.online_endpoints.begin_create_or_update(endpoint).result()

print(f"Endpoint {endpoint.name} provisioning state: {endpoint.provisioning_state}")

エンドポイントを作成したら、次のように取得します。

endpoint = ml_client.online_endpoints.get(name=online_endpoint_name)

print(
    f'Endpoint "{endpoint.name}" with provisioning state "{endpoint.provisioning_state}" is retrieved'
)

モデルをエンドポイントにデプロイする

エンドポイントを作成したら、エントリ スクリプトを使ってモデルをデプロイします。 各エンドポイントに複数のデプロイを設定できます。 これらのデプロイへの直接トラフィックは、ルールを使用して指定できます。 ここでは、受信トラフィックの 100% を処理する 1 つのデプロイを作成します。 ここではデプロイの色名 (たとえば bluegreenred のデプロイ) を選択しましたが、これは任意です。

Azure Machine Learning スタジオの [モデル] ページで、登録したモデルの最新バージョンを確認できます。 また、次のコードで、使う最新のバージョン番号を取得することもできます。

# Let's pick the latest version of the model
latest_model_version = max(
    [int(m.version) for m in ml_client.models.list(name=registered_model_name)]
)

最新バージョンのモデルをデプロイします。

注意

このデプロイには約 6 分から 8 分かかります。

# picking the model to deploy. Here we use the latest version of our registered model
model = ml_client.models.get(name=registered_model_name, version=latest_model_version)


# create an online deployment.
blue_deployment = ManagedOnlineDeployment(
    name="blue",
    endpoint_name=online_endpoint_name,
    model=model,
    instance_type="Standard_DS3_v2",
    instance_count=1,
)

blue_deployment = ml_client.begin_create_or_update(blue_deployment).result()

サンプル クエリでのテスト

モデルがエンドポイントにデプロイされたので、これを使って推論を実行できます。

スコア スクリプトの run メソッドで想定される設計に従って、サンプル要求ファイルを作成します。

deploy_dir = "./deploy"
os.makedirs(deploy_dir, exist_ok=True)
%%writefile {deploy_dir}/sample-request.json
{
  "input_data": {
    "columns": [0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22],
    "index": [0, 1],
    "data": [
            [20000,2,2,1,24,2,2,-1,-1,-2,-2,3913,3102,689,0,0,0,0,689,0,0,0,0],
            [10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 10, 9, 8]
        ]
  }
}
# test the blue deployment with some sample data
ml_client.online_endpoints.invoke(
    endpoint_name=online_endpoint_name,
    request_file="./deploy/sample-request.json",
    deployment_name="blue",
)

リソースをクリーンアップする

エンドポイントを使う予定がない場合は、削除してリソースの使用を停止します。 他のデプロイがエンドポイントを使っていないことを確認してから削除してください。

注意

この手順には約 6 分から 8 分かかります。

ml_client.online_endpoints.begin_delete(name=online_endpoint_name)

すべてを削除する

Azure Machine Learning ワークスペースとすべてのコンピューティング リソースを削除するには、次の手順を使用します。

重要

作成したリソースは、Azure Machine Learning に関連したその他のチュートリアルおよびハウツー記事の前提条件として使用できます。

作成したどのリソースも今後使用する予定がない場合は、課金が発生しないように削除します。

  1. Azure Portal で、左端にある [リソース グループ] を選択します。

  2. 一覧から、作成したリソース グループを選択します。

  3. [リソース グループの削除] を選択します。

    Azure portal でリソース グループの削除を選択する画面のスクリーンショット。

  4. リソース グループ名を入力します。 次に、 [削除] を選択します。

次のステップ