Amazon SageMakerの推論処理をAlteryxから実行する

こんにちは、小澤です。

当エントリは『機械学習 on AWS Advent Calendar 2019』の6日目です。

本日は、SageMakerのBuilt-inアルゴリズムの1つであるxgboostの推論処理をAlteryxから実行できるようなツールの作成に挑戦したいと思います。

推論だってAlteryxから

5日目のエントリーにて、SageMakerを使った学習処理をAlteryxから実行するツールの作成に挑戦しました。 学習ができるのであれば、その結果のモデルを使った推論もAlteryxから実現できると嬉しいですね。 というわけでやりましょう。

ワークフローの全体像は以下のようになります。

2つのMacro Inputツールではそれぞれ、推論対象となるデータとモデルが格納されているS3のパスを指定します。

その上のText Inputツールは設定値を取得するためのものとなっています。 学習用のツール作成時と同様接続したインターフェースツール値を書き換えることで、Pythonツールへの設定値の入力としています。

なお、推論時にはハイパーパラメータの指定はないため、インターフェースツールから渡しているものはこの設定のみとなります。

これらのデータをPythonツールに渡して推論の処理を行います。 まずは必要なデータを受け取ります。

from ayx import Alteryx
import boto3
import sagemaker
import os
import numpy as np

# S3のモデル保存先は単一のデータのみなので決め打ちで取得する
model_data = Alteryx.read('#1').iloc[0, 0]
settings = Alteryx.read('#2').set_index('key')
df = Alteryx.read('#3')

# 設定値の取得やSessionの生成
sagemaker_role = settings.loc['sagemaker_role'].value
access_key = settings.loc['access_key'].value
secret_key = settings.loc['secret_key'].value

bucket = settings.loc['bucket'].value
prefix = settings.loc['key'].value

session = boto3.Session(
    aws_access_key_id=access_key,
    aws_secret_access_key=secret_key
)

sess = sagemaker.Session(boto_session=session)

この情報を使って推論を行うわけですがSageMakerにアクセスするに際して、 学習時に利用した sagemaker.estimator.Estimator のオブジェクトは残念ながらここでは保持していないため、まずは別途 sagemaker.model.Model オブジェクトを作成します。

container = sagemaker.amazon.amazon_estimator.get_image_uri(boto3.Session().region_name, 'xgboost', '0.90-1')

# Modelオブジェクトを作成するに際して引数でS3上のモデルのファイルパスを指定する必要がある
# 入力として受け取ったものを指定する
model = sagemaker.model.Model(
    model_data,
    container,
    sagemaker_session=sess,
    role=sagemaker_role
)

あとは、推論を行うためのsagemaker. これで推論を行う準備が整いました。 推論を行う際には、リアルタイムでデータを受け取って結果を返却する sagemaker.Predictor.RealTimePredictor か、 S3にあるデータをまとめて推論して結果もS3に出力する sagemaker.transformer.Transformer を利用します。 今回はAlteryxで扱うデータに対してまとめて推論を行うことを想定しているためTransformerを使ったバッチ変換での推論を行います。

# バッチ変換を行うためにS3にデータをアップロード
file_path = os.path.join(Alteryx.getWorkflowConstant('Engine.TempFilePath'), 'test.csv')
np.savetxt(file_path, df, fmt='%.8f')
s3_path = sess.upload_data(file_path, bucket, key_prefix='{}/test'.format(prefix))

# modelからtransformerのインスタンスを生成して推論しょろを実行
transformer = model.transformer(
    instance_type='ml.m4.xlarge',
    instance_count=1,
    output_path='s3://{}/{}/transform'.format(bucket, prefix),
    assemble_with='Line'
)
transformer.transform(
    's3://cm-ozawa-sagemaker/alteryx_test/iris/test',
    wait=True, logs=True,
    content_type='text/csv', split_type='Line'
)


# 推論結果をS3から取得してDataFrameに変換する
s3 = session.client('s3')
keys = s3.list_objects(Bucket=bucket, Prefix='{}/transform'.format(prefix))
predicted_label_file = os.path.join(Alteryx.getWorkflowConstant('Engine.TempFilePath'), 'test.csv.out')
s3.download_file(
    Bucket=bucket,
    Key='{}/transform/test.csv.out'.format(prefix),
    Filename=predicted_label_file
)
result = pd.read_csv(predicted_label_file, names=['predicted_label'])

# 結果をAlteryx側に出力
Alteryx.write(result, 1)

これで推論結果のが出力されます。 今回は、分類問題を扱っているため、推論したラベルが出力となるわけです。

なお、SageMakerから出力される内容は利用する手法によって異なります。 利用しているxgboostでは、1行1件でラベルのみが出力されていまが、手法によっては各クラスの確率値なども取得できます。

また、この処理では推論結果のみを出力してます。 元のデータとあわせて結果を出力したいなどの場合には、 Alteryx.write 実行前に結合するか、出力した結果に対してAlteryx側で結合するかしてください。

使ってみる

推論処理を行うツールを使ってみましょう。 ワークフローの全体像は以下のようになります。

Create Samplesツールまでは学習時と同様、文字列の目的変数を数値化して学習データとテストデータに分けるものとなっています。 そのあとのSelectツールでは、テストデータから目的変数を取り除いています。

その結果を今回利用する茶色いツールに渡しています。 これが先ほど実装したSageMakerを使った推論を行うツールになっています。

ツールの設定項目は以下のように表示なるので、必要な値を入力します。

その下にあるText Inputツールは学習時に作成したモデルのS3上のパスとなっています。 これは s3://///.tar.gz のように単一の文字列でのパスを指定します。 また、前回作成したSageMakerを使った学習用ツールと同時に利用する場合には、そちらのツールの出力がそのまま推論ツールでの入力して利用できます。

ワークフローを実行すると、以下のように推論結果が出力されているのが確認できます。

おわりに

今回はSageMakerの推論処理をAlteryxから利用するツールの作成を行ってみました。

今回作成したツールではバッチ変換によって結果を得ていますが、 推論エンドポイントを作成することでAlteryxで作成したSageMakerのモデルをデプロイしてシステムで使うような使い方も可能です。