Amazon Web Services ブログ

Amazon SageMaker で、Scikit-Learn のサポートを追加

Amazon SageMaker は、Docker コンテナの Scikit-Learn Machine Learning ライブラリで事前に構成されています。Scikit-Learn は、一貫性のある Python インターフェイスと文書で十分に立証された API を使用して、データ分析や一般的な Machine Learning アルゴリズムを高品質で実装できる効率的なツールを提供するため、データサイエンティストや開発者にとって人気があります。Scikit-Learn はすばやく実行でき、ほとんどのデータセットや問題に対応できるため、Machine Learning 問題をすばやく繰り返さなくてはならない場合に最適です。TensorFlow や MxNet などの深層学習フレームワークとは異なり、Scikit-Learn は Machine Learning やデータ分析に使用されます。クラスタリング、回帰、分類、次元削減、機能の前処理、およびモデル選択に関して、指導付き学習アルゴリズムと指導無し学習アルゴリズムの範囲から選択できます。

新しく追加された Scikit-Learn ライブラリは、Amazon SageMaker Python SDK で利用可能です。Scikit-Learn スクリプトを作成し、自動モデルチューニングを含む Amazon SageMaker のトレーニング機能を使用することができます。モデルのトレーニングを終えたら、Scikit-Learn モデルを高い可用性のエンドポイントにデプロイして、Auto Scaling して、低レイテンシーでリアルタイムでの予測を行うことができます。また、大規模なバッチ変換ジョブで同じモデルを使用することもできます。

このブログ記事では、Amazon SageMaker で事前に構築された Scikit-Learn ライブラリを使用して、マルチクラス分類モデルを構築、トレーニング、およびデプロイする方法を説明します。

Scikit-Learn モデルのトレーニングとデプロイ

この例では、IRIS データセットの決定木分類子をトレーニングします。この例は Scikit-Learn 決定木分類子のに基づいています。完全な Amazon SageMaker ノートブックをお試しいただけます。ここでは最も重要な部分を強調します。このデータセットは、異なる 3 種のアイリス花から 50 個のサンプルをとったもので、Machine Learning 技術の実証において一般的に使用されます。さまざまな特性(花びらの長さ、花びらの幅など)に基づいて、3 種のうちから花の属性を予測することが目的です。この問題を解決するために決定木を使用していますが、Scikit-Learn では、他にも使用できる多くのアルゴリズム提供しています。

エントリーポイントのスクリプト

最初の手順は Scikit-Learn スクリプトを書くことです。メインガードから、パーサーを使用して、トレーニングジョブを作成するとき Amazon SageMaker 推定子に渡すハイパーパラメータを読み取ります。これらのハイパーパラメータは、トレーニングコンテナの入力スクリプトの引数として使用できます。この例では、葉ノードの最大数を求めます。入力データの位置やモデルを保存する位置など、トレーニング環境に関する情報を得るために、Amazon SageMaker 固有の環境変数をいくつか分析します。

if __name__ == '__main__':
    parser = argparse.ArgumentParser()

    # ハイパーパラメータについては、ここで説明します。この単純な例では、一つのハイパーパラメータのみを含んでいます。
    parser.add_argument('--max_leaf_nodes', type=int, default=-1)

    # SageMaker 固有の引数。環境変数にはデフォルト値が設定されています。
    parser.add_argument('--output-data-dir', type=str, default=os.environ['SM_OUTPUT_DATA_DIR'])
    parser.add_argument('--model-dir', type=str, default=os.environ['SM_MODEL_DIR'])
    parser.add_argument('--train', type=str, default=os.environ['SM_CHANNEL_TRAIN'])

    args = parser.parse_args()

ハイパーパラメータを定義したら、データセットを読み込みます。この例では、Pandas ライブラリを使用してすべての CSV ファイルを読み込みます。

    # 一連のファイルを 1 つの Pandas データフレームに読み込みます
    input_files = [ os.path.join(args.train, file) for file in os.listdir(args.train) ]
    if len(input_files) == 0:
        raise ValueError(('There are no files in {}.\n' +
                          'This usually indicates that the channel ({}) was incorrectly specified,\n' +
                          'the data specification in S3 was incorrectly specified or the role specified\n' +
                          'does not have permission to access the data.').format(args.train, "train"))
    raw_data = [ pd.read_csv(file, header=None, engine="python") for file in input_files ]
    train_data = pd.concat(raw_data)

この例では、ラベル(花の属性)が最初の列に保存されていると想定します。機能とラベルを別々のデータフレーム 2 つに分けています。

    # ラベルは最初の列にあります
    train_y = train_data.ix[:,0]
    train_X = train_data.ix[:,1:]

これで、モデルをトレーニングする準備ができました。これは、適切な分類子を作成して呼び出すことと同じくらい簡単です。Scikit-Learn の主な利点は、各アルゴリズムが公開するインターフェイスの簡素化と一貫性です。モデル機能の前処理や検証スコアの計算が必要な場合は、この手順でも作業を行うことができます。

    # 上記のハイパーパラメータを使用して葉ノードの数を決定します。
    max_leaf_nodes = args.max_leaf_nodes

    # Scikit-Learn の決定機分類子を使用してモデルをトレーニングします。
    clf = tree.DecisionTreeClassifier(max_leaf_nodes=max_leaf_nodes)
    clf = clf.fit(train_X, train_y)

最後に、モデルを保存します。

    # 決定木モデルを保存します。
    joblib.dump(clf, os.path.join(args.model_dir, "model.joblib"))

Amazon SageMaker ノートブック – セットアップ

Scikit-Learn スクリプトを作成したので、Amazon SageMaker で事前に構築された Scikit-Learn コンテナを使用して、Amazon SageMaker で実行することができます。ホストされた Jupiter ノートブックを使用してトレーニングプロセスを調整します。ノートブックを実行すると、インタラクティブについて行くことができます。

まず、データとモデルの保存用 Amazon S3 バケットと、データと Amazon SageMaker 権限に向けての AWS Identity and Access Management (IAM) ロールを設定します。

import sagemaker

# S3 プレフィックス
prefix = 'scikit-iris'

# このノートブックインスタンスで使用される SageMaker 互換ロールを取得します。
role = sagemaker.get_execution_role()

次に、必要な Python ライブラリをインポートし、Amazon SageMaker セッションを作成します。

from sagemaker.sklearn.estimator import SKLearn

sagemaker_session = sagemaker.Session()

次に、データセットをダウンロードして Amazon S3 にアップロードします。この例では、IRIS データセットをダウンロードする便利な機能を提供しているため、ノートブックでローカル Scikit-Learn を使用しています。

import numpy as np
import os
from sklearn import datasets

# アイリスのデータセットを読み込み、ラベルと機能を一緒に結合します
iris = datasets.load_iris()
joined_iris = np.insert(iris.data, 0, iris.target, axis=1)


# 一時ディレクトリを作成し、CSV 形式でデータセットを書き込みます
os.makedirs('./data', exist_ok=True)
np.savetxt('./data/iris.csv', joined_iris, delimiter=',', fmt='%1.1f, %1.3f, %1.3f, %1.3f, %1.3f')

# S3 にデータセットをアップロードします。
train_input = sagemaker_session.upload_data('data', key_prefix="{}/{}".format(prefix, 'data'))

Amazon SageMaker ノートブック – トレーニング

トレーニングデータと Scikit-Learn スクリプト (scikit_learn_iris.py という名前) を準備したため、SageMaker Python SDK の SKLearn クラスは、Amazon SageMaker 管理トレーニングインフラストラクチャのトレーニングジョブとしてスクリプトを実行することができます。また、IAMロール、使用するインスタンスのタイプ、スクリプトに渡すハイパーパラメータのディクショナリを推定子に渡します。Scikit-Learn は単一の CPU のみのマシンで動作するため、推定子は 1 つのトレーニングでのみインスタンス数をサポートし、GPU インスタンスはサポートされていません。

sklearn = SKLearn(
    entry_point='scikit_learn_iris.py',
    train_instance_type="ml.c4.xlarge",
    role=role,
    sagemaker_session=sagemaker_session,
    hyperparameters={'max_leaf_nodes': 30})

SKLearn 推定子を構築した後、Amazon S3 にアップロードしたデータを渡して適合させることができます。Amazon SageMaker は、データがトレーニングクラスターのローカルファイルシステムで利用できることを確認するので、Scikit-Learn スクリプトは単純にディスクからデータを読み取ることができます。

sklearn.fit({'train': train_input})

Amazon SageMaker ノートブック – デプロイメント

トレーニング後、SKLearn 推定子を使用して Amazon SageMaker エンドポイントを作成することができます。推論の実行に使用できるホスト型予測サービスおよび管理型予測サービスです。

これを行うために、scikit_learn_iris.py スクリプトには、保存されたモデルを読み込んで予測を行う model_fn() 関数が必要です。

def model_fn(model_dir):
    clf = joblib.load(os.path.join(model_dir, "model.joblib"))
    return clf

オプションで、入力要求の逆シリアル化 (input_fn()) 、予測のシリアル化 (output_fn()) 、および予測方法 (predict_fn()) をカスタマイズするその他の関数を指定することもできます。デフォルトは、現在のユースケースで機能するため、定義する必要はありません。

動作をカスタマイズするデフォルト実装については、SageMaker Scikit-Learn コンテナ GitHub リポジトリを参照してください。

これでノートブックの SKLearn 推定子を使用してモデルをデプロイすることができます。deploy() 関数を使用すると、予測エンドポイントに使用されるインスタンスの数とタイプを設定できます。これらは、トレーニングジョブに使用したものと同じ値である必要はありません。ここでは、モデルを単一の ml.m4.xlarge インスタンスにデプロイしますが、モデルを複数のインスタンスにデプロイして、エンドポイントの Auto Scaling を設定することもできます。

predictor = sklearn.deploy(initial_instance_count=1, instance_type="ml.m4.xlarge")

Amazon SageMaker ノートブック – 予測と評価

この予測子を使って IRIS データセットから花を分類できます。評価データセットはトレーニングデータセットとは異なるのが理想的ですが、この例では、トレーニングデータセットの一部を再利用してエンドポイントを呼び出すだけで十分です。

まず、テストデータセットを作成します。

import itertools
import pandas as pd

shape = pd.read_csv("data/iris.csv", header=None)

a = [50*i for i in range(3)]
b = [40+i for i in range(10)]
indices = [i+j for i,j in itertools.product(a,b)]

test_data = shape.iloc[indices[:-1]]
test_X = test_data.iloc[:,1:]
test_y = test_data.iloc[:,0]

エンドポイントを使用して、この機能で predict 関数を呼び出すと、予測を行うことができます。

predictor.predict(test_X.values)

Amazon SageMaker ノートブック – クリーンアップ

この例を終了したら、予測エンドポイントを削除して、関連するインスタンスをリリースしてください。

sklearn.delete_endpoint()

Amazon SageMaker ノートブック – バッチ変換

Amazon SageMaker は、大規模なデータセットでトレーニングされたモデルに対して推論を実行するために使用できる、大規模な管理サービスであるバッチ変換も提供します。大規模なデータを扱う場合、1 秒未満のレイテンシーを必要としない場合、またはトレーニングデータを前処理して変換する必要がある場合に理想的です。

まず、変換器を作成し、ジョブに使用するインスタンスの数とタイプを指定します。この場合、2 つのインスタンスを指定し、データセットのサイズでスケーリングして、かかる時間を短縮することができます。

# トレーニングされた SKLearn 推定子から SKLearn 変換器を定義する
transformer = sklearn.transformer(instance_count=2, instance_type='ml.m4.xlarge')

Amazon S3 でデータの位置を提供することで、変換ジョブを開始します。ノートブックの例には、データセットのアップロード手順が記載されています。

# 変換ジョブを開始し、完了するのを待ちます
transformer.transform(batch_input_s3, content_type='text/csv')
print('Waiting for transform job: ' + transformer.latest_transform_job.job_name)
transformer.wait()

変換ジョブが完了したら、Amazon S3 から出力データをダウンロードできます。入力ファイルごとに、対応する出力ファイルがあります。

# S3 の出力データをローカルファイルシステムにダウンロードします
batch_output = transformer.output_path
!mkdir -p batch_output
!aws s3 cp --recursive $batch_output/ batch_data/

結論

このブログ記事では、Amazon SageMaker の組み込み Scikit-Learn コンテナを使用して、IRIS データセットのモデルをトレーニングする方法をご紹介しました。しかし、これはほんの始まりに過ぎません。Scikit-Learn には、Machine Learning のユースケースに使用できるアルゴリズムと変換器が多く用意されています。Amazon SageMaker を使用すると、Scikit-Learn スクリプトを使用でき、SageMaker のトレーニング、自動モデルチューニング、およびデプロイメント機能をシームレスに連携できます。

引用

Dua, D. and Karra Taniskidou, E.(2017).UCI Machine Learning Repository

[http://archive.ics.uci.edu/ml]。Irvine, CA: University of California, School of Information and Computer Science.

 


今回のブログ投稿者について

Laurence Rouesnel は、Amazon AI ラボのアルゴリズムとプラットフォーム部門のグループマネージャーです。 深層学習と Machine Learning の研究や製品に取り組む、エンジニアとサイエンティストのチームを率いています。彼は熱心な旅行者で、空き時間には、ハイキング、スキー、ウインドサーフィンなど、野外活動を楽しんでいます。