皆さん、こんにちは。
クルトンです!
今回は、Amazon SageMaker Autopilot(以下、Autopilot)をチュートリアルを見て動かしてみました。Autopilotでは、複数のモデルを学習させ、一番より良い予測精度をもったモデルを使った予測も行なえます。
前提
公式チュートリアルを動かしています。
実行環境は、SageMaker StudioのPython 3 (Data Science)カーネルです。
準備
まずは各メソッドを呼び出すのに必要なboto3など、必要なモジュールをimportします。 変数prefixについては、チュートリアルそのままとしていますが、別名を設定しても良いです。ここを変更する事で、S3へデータをアップロードする時のパスが変わります。
import sagemaker
import boto3
from sagemaker import get_execution_role
region = boto3.Session().region_name
session = sagemaker.Session()
bucket = session.default_bucket()
prefix = "sagemaker/autopilot-dm"
role = get_execution_role()
sm = boto3.Session().client(service_name="sagemaker", region_name=region)
分析対象のファイル準備
Autopilotで学習させるデータを用意します。wgetコマンドを使って公式が用意しているデータをダウンロードします。 公式ドキュメントによると、CSVファイルかParquetファイルをサポートしているとの事なので、ダウンロードしたzipファイルを解凍して、CSVファイルを取り出す必要があります。
!apt-get install unzip
# 同じ階層に保存(ファイル名: bank-additonal.zip)
!wget -N https://sagemaker-sample-data-us-west-2.s3-us-west-2.amazonaws.com/autopilot/direct_marketing/bank-additional.zip
!unzip -o bank-additional.zip
local_data_path = "./bank-additional/bank-additional-full.csv"
Amazon S3へファイルアップロード
ダウンロードしてきたデータを、学習用とテスト用の2つに分け、Autopilotで扱えるようにS3へデータをアップロードします。
データ読み込み
CSVファイルを読み込むため、pandasモジュールのread_csvメソッドを使います。
import pandas as pd
data = pd.read_csv(local_data_path)
pd.set_option("display.max_columns", 500) # 全カラムを見えるよう設定
pd.set_option("display.max_rows", 10) # 1ページで収まるように行数を設定
data # データを出力して確認
データ分割
次に、データを学習用とテスト用の2つに分割します。
train_data = data.sample(frac=0.8, random_state=200)
test_data = data.drop(train_data.index)
test_data_no_target = test_data.drop(columns=["y"])
S3へアップロード
最後に、分割したデータをS3へアップロードします。学習用のデータとテスト用のデータについて、headerの有無の設定が異なるので、他のデータを使う場合に注意が必要そうです。
train_file = "train_data.csv"
train_data.to_csv(train_file, index=False, header=True)
train_data_s3_path = session.upload_data(path=train_file, key_prefix=prefix + "/train")
print("Train data uploaded to: " + train_data_s3_path)
test_file = "test_data.csv"
test_data_no_target.to_csv(test_file, index=False, header=False)
test_data_s3_path = session.upload_data(path=test_file, key_prefix=prefix + "/test")
print("Test data uploaded to: " + test_data_s3_path)
AutopilotのJob設定
ここでは、AutopilotでのJobに関連する設定を行ないます。次の公式ドキュメントが参考になります。
変数auto_ml_job_configで設定しているCompletionCriteria
では、他にも1つのJobが完了するまでの時間を制限する事も可能です。
auto_ml_job_config = {"CompletionCriteria": {"MaxCandidates": 10}}
input_data_config = [
{
"DataSource": {
"S3DataSource": {
"S3DataType": "S3Prefix",
"S3Uri": f"s3://{bucket}/{prefix}/train",
}
},
"TargetAttributeName": "y",
}
]
output_data_config = {"S3OutputPath": f"s3://{bucket}/{prefix}/output"}
注意点
データの前処理とハイパーパラメータのTrainingJobの2種類が動き、CompletionCriteria
で設定したMaxCandidatesの数に2を掛けた20個のTrainingJob数が動きました。また、関連して、ProcessingJobが複数動きます。
「とにかくコストを小さくして動かしたい」といった場合は、3など小さな数字を設定する事が可能です。ただし、予測の精度が落ちる可能性ありますので、ご留意ください。
AutopilotのJobを開始
実際にAutopilotを使って、機械学習モデルの学習とハイパーパラメータのチューニングを行ないます。どのような予測をさせるのかが分かっている場合は、create_auto_ml_jobメソッドのProblemTypeで指定できます。指定できるタイプは、BinaryClassification(2値分類)とMulticlassClassification(多クラス分類)とRegression(回帰)の3つです。
from time import gmtime, strftime, sleep
timestamp_suffix = strftime("%d-%H-%M-%S", gmtime())
auto_ml_job_name = "automl-banking-" + timestamp_suffix
print("AutoMLJobName: " + auto_ml_job_name)
sm.create_auto_ml_job(
AutoMLJobName=auto_ml_job_name,
InputDataConfig=input_data_config,
OutputDataConfig=output_data_config,
AutoMLJobConfig=auto_ml_job_config,
RoleArn=role,
)
Jobの詳細を出力
create_auto_ml_jobメソッドを動かしたのち、各Jobの状態を次のコードを使うと確認できます。 マネージメントコンソールからも、学習中などのJobのステータスが確認可能です。
print("JobStatus - Secondary Status")
print("------------------------------")
describe_response = sm.describe_auto_ml_job(AutoMLJobName=auto_ml_job_name)
print(describe_response["AutoMLJobStatus"] + " - " + describe_response["AutoMLJobSecondaryStatus"])
job_run_status = describe_response["AutoMLJobStatus"]
while job_run_status not in ("Failed", "Completed", "Stopped"):
describe_response = sm.describe_auto_ml_job(AutoMLJobName=auto_ml_job_name)
job_run_status = describe_response["AutoMLJobStatus"]
print(
describe_response["AutoMLJobStatus"] + " - " + describe_response["AutoMLJobSecondaryStatus"]
)
sleep(30)
Jobのステータスは次のようになりました。出力例としてご確認ください。
JobStatus - Secondary Status
------------------------------
InProgress - AnalyzingData
InProgress - AnalyzingData
InProgress - AnalyzingData
InProgress - AnalyzingData
InProgress - AnalyzingData
……
InProgress - AnalyzingData
InProgress - FeatureEngineering
InProgress - FeatureEngineering
InProgress - FeatureEngineering
……
InProgress - FeatureEngineering
InProgress - ModelTuning
InProgress - ModelTuning
InProgress - ModelTuning
……
InProgress - ModelTuning
InProgress - MergingAutoMLTaskReports
InProgress - MergingAutoMLTaskReports
InProgress - MergingAutoMLTaskReports
……
InProgress - MergingAutoMLTaskReports
Completed - Completed
学習結果確認
複数のモデルを学習した結果から、一番予測精度が高いモデルを確認します。
best_candidate = sm.describe_auto_ml_job(AutoMLJobName=auto_ml_job_name)["BestCandidate"]
best_candidate_name = best_candidate["CandidateName"]
print(best_candidate)
print("\n")
print("CandidateName: " + best_candidate_name)
print(
"FinalAutoMLJobObjectiveMetricName: "
+ best_candidate["FinalAutoMLJobObjectiveMetric"]["MetricName"]
)
print(
"FinalAutoMLJobObjectiveMetricValue: "
+ str(best_candidate["FinalAutoMLJobObjectiveMetric"]["Value"])
)
次以降のコードでは、ここで確認したモデルを使って推論を実行します。
バッチ推論を実施
まずは推論をさせるためのモデルを、create_modelメソッドでデプロイします。
model_name = "automl-banking-model-" + timestamp_suffix
model = sm.create_model(
Containers=best_candidate["InferenceContainers"], ModelName=model_name, ExecutionRoleArn=role
)
print(f"Model ARN corresponding to the best candidate is : {model['ModelArn']}")
バッチ推論を実施するためtransform_jobを設定後実行
次に、バッチ推論を行なうにあたって、Transformジョブを実行するので、推論を実行するファイルや推論結果を保存するS3 URIを設定します。
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": f"s3://{bucket}/{prefix}/inference-results",
}
transform_resources = {"InstanceType": "ml.m5.4xlarge", "InstanceCount": 1}
sm.create_transform_job(
TransformJobName=transform_job_name,
ModelName=model_name,
TransformInput=transform_input,
TransformOutput=transform_output,
TransformResources=transform_resources,
)
次のコードで、推論の途中経過を確認できます。
print("JobStatus")
print("----------")
describe_response = sm.describe_transform_job(TransformJobName=transform_job_name)
job_run_status = describe_response["TransformJobStatus"]
print(job_run_status)
while job_run_status not in ("Failed", "Completed", "Stopped"):
describe_response = sm.describe_transform_job(TransformJobName=transform_job_name)
job_run_status = describe_response["TransformJobStatus"]
print(job_run_status)
sleep(30)
推論の途中経過の出力例は、次のようになります。
JobStatus
----------
InProgress
InProgress
InProgress
InProgress
InProgress
InProgress
InProgress
InProgress
InProgress
InProgress
InProgress
InProgress
Completed
推論結果を確認
バッチ推論が完了すると、出力先に設定したパスへファイルがアップロードされています。 ここでは、S3から推論結果のファイルをダウンロードし、pandasモジュールのread_csvメソッドで読み込み後、データの確認をしています。
<br />s3_output_key = f"{prefix}/inference-results/test_data.csv.out"
local_inference_results_path = "inference_results.csv"
s3 = boto3.resource("s3")
inference_results_bucket = s3.Bucket(session.default_bucket())
inference_results_bucket.download_file(s3_output_key, local_inference_results_path)
data = pd.read_csv(local_inference_results_path, sep=";")
pd.set_option("display.max_rows", 10) # 1ページで収まるように行数を設定
data
リソース削除
Autopilotでは、さまざまなファイルを作成されるので、それらファイルが必要なければ、次のコードで削除できます。
s3 = boto3.resource('s3')
bucket = s3.Bucket(bucket)
job_outputs_prefix = '{}/output/{}'.format(prefix,auto_ml_job_name)
bucket.objects.filter(Prefix=job_outputs_prefix).delete()
その他
全モデルの学習結果を確認する方法や、Autopilotで実行したジョブが終わると2つのノートブックが作成されます。
全モデルの学習結果を確認
次のコードで、一番良かった学習結果のモデル以外では、どのような学習結果だったかを確認できます。
candidates = sm.list_candidates_for_auto_ml_job(
AutoMLJobName=auto_ml_job_name, SortBy="FinalObjectiveMetricValue"
)["Candidates"]
index = 1
for candidate in candidates:
print(
str(index)
+ " "
+ candidate["CandidateName"]
+ " "
+ str(candidate["FinalAutoMLJobObjectiveMetric"]["Value"])
)
index += 1
ノートブック生成場所を確認
生成されるノートブックは次の2つです。
- SageMakerAutopilotCandidateDefinitionNotebook.ipynb
- 前処理に使った設定(カテゴリカルデータのエンコーディング方法)や、ハイパーパラメータの調整時の設定を確認できます。
- SageMakerAutopilotDataExplorationNotebook.ipynb
- 学習に使用されたデータセットの情報が記されています。中央値や平均値といった基本的な統計的情報や、データセットのそれぞれのカラムにおける型を確認できます。
SageMakerAutopilotCandidateDefinitionNotebook.ipynbのパス確認
sm.describe_auto_ml_job(AutoMLJobName=auto_ml_job_name)["AutoMLJobArtifacts"][
"CandidateDefinitionNotebookLocation"
]
SageMakerAutopilotDataExplorationNotebook.ipynbのパス確認
sm.describe_auto_ml_job(AutoMLJobName=auto_ml_job_name)["AutoMLJobArtifacts"][
"DataExplorationNotebookLocation"
]
終わりに
今回は、AutopilotをSageMaker Studioから実行してみました!
簡単に実行できるのでありがたいですね。また、ハイパーパラメータの調整もしてくれるので、予測精度を上げるための処理がなされているのもナイスですね。
今回はここまで。
それでは、また!
参考にしたサイト
【イベント開催のお知らせ】
2023/07/19(水)「DevelopersIO大阪」4年ぶりのオフライン開催決定!
AWSはもちろん、ChatGPTやデータ分析など幅広い分野の技術を取り扱った12のライブセッションをお送りします。
また、クラスメソッドのエンジニアと直接技術の話ができる相談ブースも開設いたします。
大阪オフィス所属のAWS Japan Top Engineersや元Ambassadorも大集合!
さらになんと、数量限定でクラスメソッド社員謹製の本格スパイスカレーを提供いたします!
入場無料、途中の入退室は自由です。ぜひご参加ください!
タイムスケジュール・お申込みはこちらから! https://classmethod.connpass.com/event/286155/