Amazon SageMakerの学習処理をAlteryxから実行する

こんにちは、小澤です。

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

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

SageMakerを外部から使うには

SageMakerを利用する際、ノートブックインスタンスで処理を記述することが多いかと思いますが、 SageMaker Python SDKはpipを使ってインストール可能なため、以下の記事にあるように外部から実行することも可能です。

また、AWSCLIやBoto3といったAWSが提供するAPIを使った操作にももちろん対応しているため、 外部で前処理などを行ったデータをS3に置けば、学習や推論エンドポイント作成, バッチ変換といった処理を行うのにノートブックインスタンスは必須ではありません。

さて、このような仕組みということは外部の別システムから連携させることも可能であるわけです。 そして、AlteryxにはPythonツールやRツール, Python SDKといった仕組みが用意されているため、 これらの仕組みを利用することでAlteryxからSageMakerを利用することも可能というわけです。

やってみよう

というわけで、あとはやってみるだけです。 とはいえ、Alteryxを使ってコードを記述するというのはなんか違う気がします。 そこで、マクロ化して使う人はコードの実装部分を意識しなくていい状態にしてみたいと思います。

SageMakerでの学習処理は

  • sagemaker.estimator.Estimatorクラスのインスタンスを作成
  • set_hyperparametersでハイパーパラメータを設定
  • fit関数で学習処理を実行

という流れとなります。 この処理は利用する手法に限らず共通したものとなりますがBuilt-inアルゴリズムを利用する場合でも、 入力データのフォーマットや設定するハイパーパラメータは異なります。 Alteryxでマクロ化してツールとして使う際にそれらの違いを吸収した内容にすることは可能ではありますが、煩雑になるため今回はBuilt-inアルゴリズムの1つであるxgboostに絞った実装をしていきます。

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

一見シンプルそうで、インターフェースが多いというなかなか怖いワークフローですね。 安心してください、すべてはPythonツールに詰まってます。

このワークフローでは、Macro Inputが1つとText Inputが2つあります。 Macro Inputは通常のマクロと同様、学習対象となるデータを入力として受け取るものとなります。

2つのText Inputツールはそれぞれ以下のようなデータを入力しています。

上がSageMakerを利用するために必要な設定値、下がハイパーパラメータの値となっています。 これらは上部のインターフェースツールと接続されており、ツールとして利用する際にはその値で置き換えるものになっています。

後続のPythonツールで直接取得するのではなく、このような方法を取っている理由は Alteryx.getWorkflowConstant ではEngineやUserで定義された値は取得できるがQuestionが取得できないしようとなっているためです。 この方法は以下で解説されたものとなります。

これら3つのデータをPythonツールに入力として与えます。

あとはPythonツールでSageMakerで学習するコードを記述するのみです。 処理内容は先ほど紹介したAmazon SageMakerでLinear Learner(線形学習者)をNotebookインスタンス使わずにやってみた | Developers.IOでやっているものとほぼ同等となります。

まず最初にAlteryxからBoto3とSageMaker Python SDKを利用するためにパッケージのインストールを行います。

from ayx import Package
Package.installPackages(['boto3', 'sagemaker'])

この処理はAlteryx側で提供されているものを利用しています。 すでにパッケージがインストール済みであってもエラーが出ることはありません。

ただし、パッケージをインストールするに際して、Alteryxをどのようにインストールしているかに注意する必要があります。 AlteryxにはAdmin版とNon-Admin版があります。 Admin版はインストールに際して管理者権限が必要なもので通常は C:\Program Files にインストールされます。 一方Non-Admin版は管理者権限を持たないユーザでもインストールを可能にするためのもので C:\Users\<ユーザ名>\AppData にインストールされます。

さて、AlteryxのPythonツールではこのツール用のvenv環境が作成されています。 そのvenv環境はインストール先の配下に作成されます。 そのため、Admin版のAlteryxを利用している場合は初回の実行時には管理者としてAlteryx Designerを起動したうえで実行しないと権限不足でパッケージのインストールに失敗します。

続いて、利用するものをインポートしたのち、データと設定値を受け取ります。

from ayx import Alteryx
import os
import numpy as np
import pandas as pd
from sklearn.datasets import dump_svmlight_file
import boto3
import sagemaker

df = Alteryx.read('#1')
settings = Alteryx.read('#2').set_index('key')
hyper_params = Alteryx.read('#3').set_index('param')

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

以降は、SageMaker Python SDKを使った通常の処理フローと同等になります。

# boto3.Sessionを使ってsagemaker.Sessionを作成
# boto3のSessionを作成する際はprofileの指定でも問題ないが、
# ワークフローを他の環境に持っていきやすいようにAccess keyを利用している
session = boto3.Session(
    aws_access_key_id=access_key,
    aws_secret_access_key=secret_key
)
sess = sagemaker.Session(boto_session=session)

# 目的変数となる列を設定値から取得
label = settings.loc['label'].value

# xgboostを使うのでScikt learnの関数を使ってlibsvm形式でファイルを保存する
# 保存先はAlteryx側で提供される一時ディレクトリ
file_path = os.path.join(Alteryx.getWorkflowConstant('Engine.TempFilePath'), 'data')
dump_svmlight_file(
    X=df.drop(label, axis=1).values,
    y=df.loc[:, label].values,
    f=file_path
)
# S3に保存したファイルをアップロード
s3_train_data = sess.upload_data(file_path, bucket, key_prefix='{}/train'.format(prefix))

# sagemaker.estimator.Estimatorを使った学習処理の実行
container = sagemaker.amazon.amazon_estimator.get_image_uri(boto3.Session().region_name, 'xgboost', '0.90-1')
output_location = 's3://{}/{}/output'.format(bucket, prefix)

xgboost = sagemaker.estimator.Estimator(
    container,
    sagemaker_role,
    train_instance_count=1,
    train_instance_type='ml.c4.xlarge',
    output_path=output_location,
    sagemaker_session=sess)

# ハイパーパラメータは設定値と同様ツールの入力から受け取ったものを利用する
# SageMakerのxgboostで利用可能なハイパーパラメータは他にもあるが今回は簡略化してる
xgboost.set_hyperparameters(
    max_depth=int(hyper_params.loc['max_depth'].value),
    eta=float(hyper_params.loc['eta'].value),
    gamma=float(hyper_params.loc['gamma'].value),
    min_child_weight=float(hyper_params.loc['min_child_weight']),
    objective=hyper_params.loc['objective'].value,
    num_class=len(df.loc[:, label].unique()),
    num_round=int(hyper_params.loc['num_round'].value)
)
xgboost.fit({'train': s3_train_data})

最後にS3に出力されたモデルのパスをこのツールの出力として返します。

xgboost_model = xgboost.create_model()
Alteryx.write(pd.DataFrame({'model_data' : [xgboost_model.model_data]}), 1)

この結果をMacro Outputツールに渡すことでツールの完成となります。

使ってみる

さて、このツールを実際に使う側を見ていきましょう。 とはいえ、ツール化されてるので通常のワークフローでの利用と全く同じ感じになります。

使っているのは絵が描かれていない茶色いアイコンのツールが今回作成したものです。 最初にあるFormulaツールとSelectツールは、データ中で文字列として与えられている正解ラベルを数値化してもとの列を削除するのに使っています。 また、学習データとテストデータを分けるためにCreate Sampleツールを利用しています。

SageMakerを使って学習するツールは、以下のように設定値とハイパーパラメータをタブで分けるインターフェースにしておきました。

ワークフローの実行中に、AWSマネジメントコンソールから学習ジョブが走っている様子なども確認可能です。

おわりに

今回は、SageMakerのxgboostを使った学習処理をAlteryxから実行するためのツールの作り方を紹介しました。

SageMakerは入力ファイルのフォーマットやハイパーパラメータが手法によって異なる以外は使い方はほぼ同じとなりますので、同様の方法で実現可能です。

また、 今回はハイパーパラメータを個別で指定していますが、 sagemaker.tuner.HyperparameterTuner を利用することも可能ですし、複数の手法で同時に学習を行って精度比較する要は仕組みも同様に実現可能です。