チュートリアル 2: 特徴量を使用してモデルの実験とトレーニングを行う

このチュートリアル シリーズでは、プロトタイプ作成、トレーニング、運用という機械学習ライフサイクルのすべてのフェーズを、特徴量によってシームレスに統合する方法について説明します。

最初のチュートリアルでは、カスタム変換を使用して特徴量セット仕様を作成し、その特徴量セットを使用してトレーニング データを生成し、具体化を有効にし、バックフィルを実行する方法を示しました。 このチュートリアルでは、具体化を有効にし、バックフィルを実行する方法を示します。 また、モデルのパフォーマンスを向上させる方法として、特徴量を使用して実験する方法についても説明します。

このチュートリアルでは、次の作業を行う方法について説明します。

  • 既存の事前計算値を特徴量として使用して、新しい accounts 特徴量セット仕様のプロトタイプを作成します。 次に、ローカルの特徴量セット仕様を特徴量セットとして特徴量ストアに登録します。 このプロセスは、カスタム変換を含む特徴量セットを作成した 1 つめのチュートリアルとは異なります。
  • transactionsaccounts の特徴量セットからモデル用の特徴量を選択し、特徴量取得仕様として保存します。
  • その特徴量取得仕様を使用するトレーニング パイプラインを実行して、新しいモデルをトレーニングします。 このパイプラインは、組み込みの特徴量取得コンポーネントを使用して、トレーニング データを生成します。

前提条件

このチュートリアルに進む前に、シリーズの最初のチュートリアルを完了してください。

設定

  1. Azure Machine Learning Spark ノートブックを構成します。

    新しいノートブックを作成し、順を追ってこのチュートリアルの手順を実行できます。 "featurestore_sample/notebooks" ディレクトリの "2.Experiment-train-models-using-features.ipynb" という名前の既存のノートブックを開いて実行することもできます。 sdk_only または sdk_and_cli を選択できます。 このチュートリアルは開いたままにしておき、ドキュメントのリンクや追加の説明を参照してください。

    1. 上部のメニューの [Compute] (コンピューティング) ドロップダウン リストで、[Azure Machine Learning Serverless Spark] (Azure Machine Learning サーバーレス Spark) の下の [Serverless Spark Compute] (サーバーレス Spark コンピューティング) を選択します。

    2. セッションを構成するには、以下を行います。

      1. ツール バーに [Configure session] (セッションの構成) と表示されたら、それを選択します。
      2. [Python パッケージ] タブで、[Upload Conda file] (Conda ファイルのアップロード) を選択します。
      3. 1 つめのチュートリアルでアップロードした "conda.yml" ファイルをアップロードします。
      4. オプションで、前提条件が頻繁に再実行されないように、セッション タイムアウト (アイドル時間) を増やします。
  2. Spark セッションを開始します。

    # 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")
  3. サンプルのルート ディレクトリを設定します。

    import os
    
    # please update the dir to ./Users/<your_user_alias> (or any custom directory you uploaded the samples to).
    # You can find the name from the directory structure in the left nav
    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")
  4. CLI を設定します。

    該当なし。


  1. プロジェクト ワークスペース変数を初期化します。

    これは現在のワークスペースであり、チュートリアル ノートブックはこのリソースで実行されます。

    ### Initialize the MLClient of this project workspace
    import os
    from azure.ai.ml import MLClient
    from azure.ai.ml.identity import AzureMLOnBehalfOfCredential
    
    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"]
    
    # connect to the project workspace
    ws_client = MLClient(
        AzureMLOnBehalfOfCredential(), project_ws_sub_id, project_ws_rg, project_ws_name
    )
  2. 特徴量ストア変数を初期化します。

    1 つめのチュートリアルで作成した内容を反映するように、featurestore_namefeaturestore_location の値を必ず更新してください。

    from azure.ai.ml import MLClient
    from azure.ai.ml.identity import AzureMLOnBehalfOfCredential
    
    # feature store
    featurestore_name = (
        "<FEATURESTORE_NAME>"  # use the same name from part #1 of the tutorial
    )
    featurestore_subscription_id = os.environ["AZUREML_ARM_SUBSCRIPTION"]
    featurestore_resource_group_name = os.environ["AZUREML_ARM_RESOURCEGROUP"]
    
    # feature store ml client
    fs_client = MLClient(
        AzureMLOnBehalfOfCredential(),
        featurestore_subscription_id,
        featurestore_resource_group_name,
        featurestore_name,
    )
  3. 特徴量ストア使用クライアントを初期化します。

    # 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,
    )
  4. プロジェクト ワークスペースに、cpu-cluster という名前のコンピューティング クラスターを作成します。

    トレーニング/バッチ推論ジョブを実行するときに、このコンピューティング クラスターが必要です。

    from azure.ai.ml.entities import AmlCompute
    
    cluster_basic = AmlCompute(
        name="cpu-cluster-fs",
        type="amlcompute",
        size="STANDARD_F4S_V2",  # you can replace it with other supported VM SKUs
        location=ws_client.workspaces.get(ws_client.workspace_name).location,
        min_instances=0,
        max_instances=1,
        idle_time_before_scale_down=360,
    )
    ws_client.begin_create_or_update(cluster_basic).result()

ローカル環境でアカウントの特徴量セットを作成する

1 つめのチュートリアルでは、カスタム変換を含む transactions 特徴量セットを作成しました。 ここでは、事前に計算された値を使用する accounts 特徴量セットを作成します。

事前計算済み特徴量をオンボードするために、変換コードを記述せずに特徴量セット仕様を作成できます。 特徴量セット仕様は、特徴量セットを完全にローカルな開発環境で開発およびテストするために使用します。

特徴量ストアに接続する必要はありません。 この手順では、特徴量セット仕様をローカルに作成し、次にそこから値をサンプリングします。 マネージド Feature Store の機能については、特徴量資産定義を使用して、特徴量セット仕様を特徴量ストアに登録する必要があります。 このチュートリアルの後の手順では、詳細について説明します。

  1. アカウントのソース データを調べます。

    Note

    このノートブックでは、パブリックにアクセスできる BLOB コンテナーでホストされているサンプル データを使用します。 Spark でこれを読み取ることができるのは wasbs ドライバーだけです。 独自のソース データを使用して特徴量セットを作成するときは、Azure Data Lake Storage Gen2 アカウントでそれらの特徴量セットをホストし、データ パスで abfss ドライバーを使用してください。

    accounts_data_path = "wasbs://data@azuremlexampledata.blob.core.windows.net/feature-store-prp/datasources/accounts-precalculated/*.parquet"
    accounts_df = spark.read.parquet(accounts_data_path)
    
    display(accounts_df.head(5))
  2. これらの事前計算された特徴量から accounts 特徴量セット仕様をローカルで作成します。

    事前計算済みの特徴量を参照するため、ここでは変換コードは必要ありません。

    from azureml.featurestore import create_feature_set_spec, FeatureSetSpec
    from azureml.featurestore.contracts import (
        DateTimeOffset,
        Column,
        ColumnType,
        SourceType,
        TimestampColumn,
    )
    from azureml.featurestore.feature_source import ParquetFeatureSource
    
    
    accounts_featureset_spec = create_feature_set_spec(
        source=ParquetFeatureSource(
            path="wasbs://data@azuremlexampledata.blob.core.windows.net/feature-store-prp/datasources/accounts-precalculated/*.parquet",
            timestamp_column=TimestampColumn(name="timestamp"),
        ),
        index_columns=[Column(name="accountID", type=ColumnType.string)],
        # account profiles in the source are updated once a year. set temporal_join_lookback to 365 days
        temporal_join_lookback=DateTimeOffset(days=365, hours=0, minutes=0),
        infer_schema=True,
    )
  3. 特徴量セット仕様としてエクスポートします。

    特徴量セット仕様を特徴量ストアに登録するには、特徴量セット仕様を特定の形式で保存する必要があります。

    次のセルを実行した後、生成された accounts 特徴量セット仕様を検査します。 仕様を確認するには、ファイル ツリーから "featurestore/featuresets/accounts/spec/FeatureSetSpec.yaml" ファイルを開きます。

    この仕様には次の重要な要素が含まれています。

    • source: ストレージ リソースへの参照。 この場合は、BLOB ストレージ リソース内の Parquet ファイルです。

    • features: 特徴量とそのデータ型の一覧。 用意されている変換コードを使用する場合は、そのコードから、特徴量とデータ型に対応する DataFrame を返す必要があります。 変換コードを指定しない場合、システムは、特徴量とデータ型をソースにマップするクエリを構築します。 この場合、特徴量は事前計算されるため、生成される accounts 特徴量セット仕様に変換コードは含まれません。

    • index_columns: 特徴量セットから値にアクセスするために必要な結合キー。

    詳細については、「マネージド Feature Store の最上位エンティティについて」と「CLI (v2) 特徴量セット仕様 YAML スキーマ」を参照してください。

    追加の利点として、永続化はソース管理をサポートします。

    事前計算済みの特徴量を参照するため、ここでは変換コードは必要ありません。

    import os
    
    # create a new folder to dump the feature set spec
    accounts_featureset_spec_folder = root_dir + "/featurestore/featuresets/accounts/spec"
    
    # check if the folder exists, create one if not
    if not os.path.exists(accounts_featureset_spec_folder):
        os.makedirs(accounts_featureset_spec_folder)
    
    accounts_featureset_spec.dump(accounts_featureset_spec_folder, overwrite=True)

未登録の特徴量を使ってローカルで実験し、準備ができたら特徴量ストアに登録する

特徴量を開発するときには、特徴量ストアへの特徴量の登録や、クラウドでのトレーニング パイプラインの実行より前に、特徴量をローカルでテストして検証することが必要な場合があります。 ローカルの未登録の特徴量セット (accounts) と、特徴量ストアに登録されている特徴量セット (transactions) の組み合わせにより、機械学習モデルのトレーニング データが生成されます。

  1. モデル用の特徴量を選択します。

    # get the registered transactions feature set, version 1
    transactions_featureset = featurestore.feature_sets.get("transactions", "1")
    # Notice that account feature set spec is in your local dev environment (this notebook): not registered with feature store yet
    features = [
        accounts_featureset_spec.get_feature("accountAge"),
        accounts_featureset_spec.get_feature("numPaymentRejects1dPerUser"),
        transactions_featureset.get_feature("transaction_amount_7d_sum"),
        transactions_featureset.get_feature("transaction_amount_3d_sum"),
        transactions_featureset.get_feature("transaction_amount_7d_avg"),
    ]
  2. ローカルでトレーニング データを生成します。

    この手順では、説明のためにトレーニング データを生成します。 オプションとして、ここではモデルをローカルでトレーニングできます。 このチュートリアルの後の手順では、クラウドでモデルをトレーニングする方法について説明します。

    from azureml.featurestore import get_offline_features
    
    # Load the observation data. To understand observatio ndata, refer to part 1 of this tutorial
    observation_data_path = "wasbs://data@azuremlexampledata.blob.core.windows.net/feature-store-prp/observation_data/train/*.parquet"
    observation_data_df = spark.read.parquet(observation_data_path)
    obs_data_timestamp_column = "timestamp"
    # 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: display(training_df.head(5)) displays the timestamp column in a different format. You can can call training_df.show() to see correctly formatted value
  3. 特徴量ストアに accounts 特徴量セットを登録します。

    特徴量定義をローカルで試し、それらが妥当と思われたら、特徴量ストアに特徴量セット資産定義を登録できます。

    from azure.ai.ml.entities import FeatureSet, FeatureSetSpecification
    
    accounts_fset_config = FeatureSet(
        name="accounts",
        version="1",
        description="accounts featureset",
        entities=[f"azureml:account:1"],
        stage="Development",
        specification=FeatureSetSpecification(path=accounts_featureset_spec_folder),
        tags={"data_type": "nonPII"},
    )
    
    poller = fs_client.feature_sets.begin_create_or_update(accounts_fset_config)
    print(poller.result())
  4. 登録済みの特徴量セットを取得して、テストします。

    # look up the featureset by providing name and version
    accounts_featureset = featurestore.feature_sets.get("accounts", "1")

トレーニング実験を実行する

次の手順では、特徴量の一覧を選択し、トレーニング パイプラインを実行し、モデルを登録します。 モデルのパフォーマンスが希望どおりになるまで、この手順を繰り返すことができます。

  1. オプションで、特徴量ストア UI から特徴量を見つけます。

    1 つめのチュートリアルで、transactions 機能セットを登録したときにこの手順を説明しています。 accounts 特徴量セットもあるため、次のように使用可能な特徴量を参照できます。

    1. Azure Machine Learning のグローバル ランディング ページに移動します。
    2. 左側のウィンドウで、[Feature stores] (特徴量ストア) を選択します。
    3. 特徴量ストアの一覧で、前に作成した特徴量ストアを選択します。

    UI に、作成した特徴量セットとエンティティが表示されます。 特徴量セットを選択して、特徴量定義を参照します。 また、グローバル検索ボックスを使うと、複数の特徴量ストアにまたがって特徴量セットを検索できます。

  2. オプションで、SDK から特徴量を見つけます。

    # List available feature sets
    all_featuresets = featurestore.feature_sets.list()
    for fs in all_featuresets:
        print(fs)
    
    # List of versions for transactions feature set
    all_transactions_featureset_versions = featurestore.feature_sets.list(
        name="transactions"
    )
    for fs in all_transactions_featureset_versions:
        print(fs)
    
    # See properties of the transactions featureset including list of features
    featurestore.feature_sets.get(name="transactions", version="1").features
  3. モデル用の特徴量を選択し、特徴量取得仕様としてモデルをエクスポートします。

    前の手順では、ローカルでの実験とテストのために、登録済みと未登録の特徴量セットの組み合わせから特徴量を選びました。 これでクラウドで実験できるようになりました。 選択した特徴量を特徴量取得仕様として保存し、機械学習の運用 (MLOps) または継続的インテグレーションと継続的デリバリー (CI/CD) のフローでその仕様をトレーニングと推論に使用すると、モデル出荷の機敏性が向上します。

    1. モデル用の特徴量を選択します。

      # you can select features in pythonic way
      features = [
          accounts_featureset.get_feature("accountAge"),
          transactions_featureset.get_feature("transaction_amount_7d_sum"),
          transactions_featureset.get_feature("transaction_amount_3d_sum"),
      ]
      
      # you can also specify features in string form: featurestore:featureset:version:feature
      more_features = [
          f"accounts:1:numPaymentRejects1dPerUser",
          f"transactions:1:transaction_amount_7d_avg",
      ]
      
      more_features = featurestore.resolve_feature_uri(more_features)
      
      features.extend(more_features)
    2. 選択した特徴量を特徴量取得仕様としてエクスポートします。

      特徴量取得仕様は、モデルに関連付けられた特徴量一覧の移植可能な定義です。 これは、機械学習モデルの開発と運用化を合理化するのに役立ちます。 これは、トレーニング データを生成するトレーニング パイプラインへの入力となります。 その後、モデルと一緒にパッケージ化されます。

      推論フェーズはこの特徴量取得を使用して特徴量を検索します。 これにより、機械学習ライフサイクルのすべてのフェーズが統合されます。 実験やデプロイを行う際のトレーニング/推論パイプラインに加える変更を最小限に抑えることができます。

      特徴量取得仕様と組み込みの特徴量取得コンポーネントの使用は任意です。 前に説明したように、get_offline_features() API を直接使用できます。 モデルとともにパッケージ化するときの仕様の名前は "feature_retrieval_spec.yaml" にする必要があります。 そうすることで、システムはそれを認識できます。

      # Create feature retrieval spec
      feature_retrieval_spec_folder = root_dir + "/project/fraud_model/feature_retrieval_spec"
      
      # check if the folder exists, create one if not
      if not os.path.exists(feature_retrieval_spec_folder):
          os.makedirs(feature_retrieval_spec_folder)
      
      featurestore.generate_feature_retrieval_spec(feature_retrieval_spec_folder, features)

パイプラインを使用してクラウドでのトレーニングを行い、モデルを登録する

この手順では、トレーニング パイプラインを手動でトリガーします。 運用シナリオでは、ソース リポジトリの特徴量取得仕様に対する変更に基づいて、CI/CD パイプラインがこれをトリガーできます。 モデルが満足のいくものであれば、それを登録できます。

  1. トレーニング パイプラインを実行します。

    トレーニング パイプラインには以下の手順があります。

    1. 特徴量取得: この組み込みコンポーネントは、入力として特徴量取得仕様、観測データ、タイムスタンプ列名を受け取ります。 次に、出力としてトレーニング データを生成します。 これらの手順を、マネージド Spark ジョブとして実行します。

    2. トレーニング: この手順は、トレーニング データに基づいてモデルをトレーニングし、次にモデルを生成します (まだ登録しません)。

    3. 評価: この手順は、モデルのパフォーマンスと品質がしきい値内であるかどうかを検証します。 (このチュートリアルでは、これは説明のためのプレースホルダー ステップです。)

    4. モデルの登録: この手順はモデルを登録します。

      Note

      2 つめのチュートリアルでは、バックフィル ジョブを実行して transactions 特徴量セットのデータを具体化しました。 特徴量取得手順では、この特徴量セットのオフライン ストアから特徴量の値を読み取ります。 get_offline_features() API を使用した場合でも動作は同じです。

      from azure.ai.ml import load_job  # will be used later
      
      training_pipeline_path = (
          root_dir + "/project/fraud_model/pipelines/training_pipeline.yaml"
      )
      training_pipeline_definition = load_job(source=training_pipeline_path)
      training_pipeline_job = ws_client.jobs.create_or_update(training_pipeline_definition)
      ws_client.jobs.stream(training_pipeline_job.name)
      # Note: First time it runs, each step in pipeline can take ~ 15 mins. However subsequent runs can be faster (assuming spark pool is warm - default timeout is 30 mins)
    5. トレーニング パイプラインとモデルを調べます。

      • パイプラインの手順を表示するには、Web ビュー パイプラインのハイパーリンクを選択し、新しいウィンドウで開きます。
  2. モデル アーティファクトの特徴量取得仕様を次のように使用します。

    1. 現在のワークスペースの左側のウィンドウで、マウスの右ボタンを押して [モデル] を選択します。
    2. [Open in a new tab or window] (新しいタブまたはウィンドウで開く) を選択します。
    3. [fraud_model] を選択します。
    4. [アーティファクト] を選択します。

    特徴量取得仕様は、モデルとともにパッケージ化されます。 トレーニング パイプラインのモデル登録ステップで、この手順が処理されました。 実験中に特徴量取得仕様を作成しました。 これで、モデル定義の一部になりました。 次のチュートリアルでは、推論がどのようにそれを使用するかについて確認します。

特徴量セットとモデルの依存関係を表示する

  1. モデルに関連付けられている特徴量セットの一覧を表示します。

    同じ [モデル] ページで [Feature sets] (特徴量セット) タブを選択します。このタブには、このモデルが依存している transactionsaccounts の両方の特徴量セットが表示されます。

  2. この特徴量セットを使用しているモデルの一覧を次のように表示します。

    1. 特徴量ストア UI (このチュートリアルの前の方で説明済み) を開きます。
    2. 左側のウィンドウで、[Feature sets] (特徴量セット) を選択します。
    3. 特徴量セットを選択します。
    4. [モデル] タブを選択します。

    モデルが登録されたときに、特徴量取得仕様がこの一覧を決定しました。

クリーンアップ

このシリーズの 5 番目のチュートリアルでは、リソースを削除する方法について説明します。

次のステップ