ハンズオンを通してAmazon SageMaker Autopilotでモデルを作成してみる
お疲れさまです。とーちです。
前回に引き続き、Amazon SageMaker Immersion Dayのハンズオンをやっています。今回は、Amazon SageMaker Autopilot(以後、Autopilot)を使った機械学習モデルの自動生成について学んだことを共有したいと思います。
料金について
今回の範囲では、以下の料金が発生する可能性があります:
- Amazon SageMaker Studio JupyterLab
- Amazon SageMaker トレーニング
- Amazon SageMaker バッチ変換
特にトレーニングは合計で1時間以上かかりましたので、料金はそれなりにかかってくると思いますのでご注意ください。
Note
料金の詳細は公式ページをご確認ください。
Amazon SageMaker Autopilotとは
Autopilotは表形式のデータを扱う自動機械学習(AutoML)ツールです。特徴量エンジニアリングからモデルチューニングまで、機械学習の一連のプロセスを自動化してくれる便利なサービスです。
主な特徴:
- データの前処理を自動化
- 最適なモデルの選択を自動化
- ハイパーパラメータのチューニングを自動化
- コードの記載はほぼ必要なし
実際にはSageMakerAIの自動パラメータチューニングなど、複数の機能が組み合わせてラッピングされているような印象を受けました。
なお、Autopilotは最大5GBまでのデータセットを処理できるとのことです。
やってみる
今回も前回までのハンズオンと同様に「銀行の定期預金の契約予測」をするための機械学習モデルを作っていきます。
データの準備
予測に使用するデータはAmazon SageMaker Immersion Dayを始める際にgit cloneで取得したファイルの中に含まれているのでこれを使って進めていきます。
import pandas as pd
local_data_path = './bank-additional/bank-additional-full.csv'
data = pd.read_csv(local_data_path)
通常の機械学習では、データの前処理(欠損値処理、カテゴリカルデータの数値化等)に多くの時間と労力が必要ですが、SageMaker Autopilotの優れている点は、これらの前処理を全て自動的に行ってくれることだそうです。
とはいえ、Autopilotを使う場合でもデータの前処理はしておいたほうがいいようで、テキストには「データセットに明らかなエラーがないか確認してください。オートパイロットの処理には時間がかかる場合があり、通常は作業を開始する前にデータセットを検査することが推奨されます」との記載がありました。
Autopilotによるデータ分割
機械学習では以下の3つのデータを用意するのが一般的です。
-
訓練データ
- モデルの学習に使用
- 実際のパターンを学習させるためのデータ
-
検証データ
- モデルの調整に使用
- パラメータの最適化に利用
-
テストデータ
- 最終的な性能評価に使用
Autopilotでは、データの自動分割機能もあり、データを与えると訓練データと検証データに自動で分割してくれます。そのため、ユーザーとしてはAutopilotに入力するデータ(訓練データと検証データを含むもの)とテストデータだけを用意すればよい形になります。
なおデータ分割する際のポイントは以下とのことです。
- ランダムな分割で偏りを防ぐ
- 7:3や8:2の比率が一般的
- 特徴分布の均一性を保つ
ハンズオンでは、元データを、「訓練・検証データ」と「テストデータ」に分割するために以下の処理を行ってます。pandasライブラリを使うと簡単にデータを分割できるんですね。
# 元のデータ(data)から80%をランダムに抽出して、train_dataという新しい変数に格納
train_data = data.sample(frac=0.8,random_state=200)
# 元のデータ(data)から、train_dataで使用した行(train_data.index)を削除し、その結果をtest_dataに格納(つまりtrain_dataに含まれない残り2割のデータをテストデータとして使用)
test_data = data.drop(train_data.index)
# テストデータから予測させたい列(y列)を削除したデータセットを作成
test_data_no_target = test_data.drop(columns=['y'])
分割したデータはautopilot-dm/train/
とautopilot-dm/test/
にアップロードします。
SageMaker Autopilotジョブを設定していく
上記はAutopilotを起動するための設定をしている部分です。
Autopilotジョブを実行するには3つの要素が必要とのこと。このうちIAMロールは後述のAutopilotジョブを実行(create_auto_ml_job_v2
)する際に指定しています。
- Amazon S3の場所指定(入力・出力データの保存場所)
- 予測対象列の名前(今回は'y'列)
- IAMロール(S3アクセス権限)
SageMaker Autopilotの問題タイプと実行時間の設定について
auto_ml_problem_type_config={
'TabularJobConfig': {
'CompletionCriteria': {
'MaxCandidates': 5
},
'ProblemType': 'BinaryClassification',
'TargetAttributeName': 'y',
},
}
上記の部分でAutopilotの問題タイプと実行時間の設定をしています。
Autopilotで解決できる問題のタイプには3種類あります。なお、問題タイプが不明な場合でも、Autopilotが自動的に適切なタイプを判断してくれるとのことです。
- 回帰(Regression):連続的な数値予測(例:売上予測)
- 二値分類(BinaryClassification):はい/いいえのような2つの選択肢から予測(例:顧客が定期預金に加入するかどうか)
- 多クラス分類(MulticlassClassification):3つ以上の選択肢から予測(例:商品のカテゴリー分類)
実行時間は以下の2つの方法で制限できます:
- パイプライン評価数の制限(例:MaxCandidates=5)
- パイプライン = データ前処理 + モデル学習 + パラメータ調整
- 'MaxCandidates': 5だとAutopilotは最大5個のパイプラインを試行する
- 全体実行時間の制限(デフォルト約4時間)
- ジョブ全体の最大実行時間を設定
ジョブの実行
sm.create_auto_ml_job_v2(
AutoMLJobName=auto_ml_job_name,
AutoMLJobInputDataConfig=auto_ml_job_input_data_config,
OutputDataConfig=output_data_config,
AutoMLJobObjective=auto_ml_job_objective,
AutoMLProblemTypeConfig=auto_ml_problem_type_config,
RoleArn=role
)
Autopilotジョブは3つのステップで実行されます
- データ分析(Analyzing Data)
- データセットの詳細な分析を実行
- この分析結果を基に、試すべきML(機械学習)パイプラインのリストを作成
- データを訓練セットと検証セットに自動的に分割
- 特徴量エンジニアリング(Feature Engineering)
- データの特徴を機械学習に適した形に変換
- 個別の特徴量レベルでの変換
- 例:カテゴリデータの数値化
- 例:日付データの分解
- モデルチューニング(Model Tuning)
- 最も性能の良いパイプラインを選択
- そのパイプラインの学習アルゴリズムに最適なハイパーパラメータを決定
実行状況の確認
describe_auto_ml_job_v2
を実行することでAutopilotのジョブの実行状況を確認可能です。
while job_run_status not in ('Failed', 'Completed', 'Stopped'):
describe_response = sm.describe_auto_ml_job_v2(AutoMLJobName=auto_ml_job_name)
job_run_status = describe_response['AutoMLJobStatus']
print (describe_response['AutoMLJobStatus'] + " - " + describe_response['AutoMLJobSecondaryStatus'])
sleep(30)
ジョブの実行が完了すると Completed - Completed
と表示されます。
このAutopilotジョブですが、めちゃくちゃ時間がかかったのでご注意ください。私が実施した際はハイパーパラメータの調整ジョブだけでも4,50分くらいはかかりました。全体の実行時間はもう少し長かったと思います。
ジョブが完了した後は、Autopilotジョブが選んだ最適な候補(BestCandidate)の情報も取得できます
best_candidate = sm.describe_auto_ml_job_v2(AutoMLJobName=auto_ml_job_name)['BestCandidate']
best_candidate_name = best_candidate['CandidateName']
print(best_candidate)
裏側ではハイパーパラメータの自動チューニングジョブが動いてました。
バッチ推論の実行
モデルが作成できたのでバッチ推論をしてみます。なお今回はバッチ推論をしてますが、リアルタイム推論用のエンドポイントとしてデプロイすることもできます。
モデルの作成
BestCandidateの情報を使用してcreate_model
でSageMaker上にモデルを作成できます。(デプロイではない)
model = sm.create_model(
Containers=best_candidate['InferenceContainers'],
ModelName=model_name,
ExecutionRoleArn=role
)
バッチ推論の設定は以下のコードで実行します。
transform_job_name = 'automl-banking-transform-' + timestamp_suffix
transform_input = {
'DataSource': {
'S3DataSource': {
'S3DataType': 'S3Prefix',
'S3Uri': test_data_s3_path
}
},
'ContentType': 'text/csv',
'CompressionType': 'None',
'SplitType': 'Line'
}
transform_output = {
'S3OutputPath': 's3://{}/{}/inference-results'.format(bucket,prefix),
}
transform_resources = {
'InstanceType': 'ml.m5.4xlarge',
'InstanceCount': 1
}
ざっくり内容を説明すると以下のような感じです。
- 入力データの設定(transform_input)
- 予測対象のデータ(テストデータ)の場所と形式を指定
- CSVファイル形式で、圧縮なし、1行ごとに処理することを指定
- 出力設定(transform_output):
- 予測結果の保存先を指定
- リソース設定(transform_resources):
- 使用するコンピューティングリソースを指定
- ml.m5.4xlargeインスタンスを1台使用
変換ジョブの実行
最後に、これらの設定を使ってcreate_transform_job
でバッチ変換ジョブを作成します。
sm.create_transform_job(
TransformJobName = transform_job_name,
ModelName = model_name,
TransformInput = transform_input,
TransformOutput = transform_output,
TransformResources = transform_resources
)
バッチ推論の実行状況はdescribe_transform_job
メソッドで確認可能です。
describe_response = sm.describe_transform_job(TransformJobName = transform_job_name)
バッチ推論の結果は上記で指定したtransform_outputに出力されます。結果は以下のような感じでした。
ノートブックが自動生成される
SageMaker AutoPilotは、候補定義ノートブックも自動生成できます。このノートブックは、SageMaker Autopilotが最適な候補を導き出すために実行するステップを確認できます
以下のコードでローカルに候補定義ノートブックをコピーできます
# cell 15
desc_notebook = sm.describe_auto_ml_job_v2(AutoMLJobName=auto_ml_job_name)['AutoMLJobArtifacts']['CandidateDefinitionNotebookLocation']
# S3 URLからバケット名とキーを抽出
from urllib.parse import urlparse
parsed_url = urlparse(desc_notebook)
bucket_name = parsed_url.netloc
key = parsed_url.path.lstrip('/')
# ダウンロード実行
session.download_data(
path='.',
bucket=bucket_name,
key_prefix=key
)
またAutoPilotはデータ探索ノートブック(Data Exploration notebook)というAutoPilotに対して入力したデータの内容を分析したノートブックも生成します。
このノートブックには以下のような情報が含まれてます
- データの品質(重複、異常値、欠損値)
- 目的変数の分析
- 特徴量の要約
- 列間の関係性
こちらも以下のコードでダウンロードしてみます
desc_job=sm.describe_auto_ml_job_v2(AutoMLJobName=auto_ml_job_name)['AutoMLJobArtifacts']['DataExplorationNotebookLocation']
# S3 URLからバケット名とキーを抽出
from urllib.parse import urlparse
parsed_url = urlparse(desc_job)
bucket_name = parsed_url.netloc
key = parsed_url.path.lstrip('/')
# ダウンロード実行
session.download_data(
path='.',
bucket=bucket_name,
key_prefix=key
)
こんな感じでした
まとめ
SageMaker Autopilotを使ってモデルの作成とバッチ推論をしてみました。Autopilotがハマるパターンであれば楽にモデルが作れそうですが、入力データの制限が5GBというのがなかなか厳しそうですね。
以上、とーちでした。