背景
AWS SageMakerを勉強していると、SageMakerに「トレーニング > ハイパーパラメータの調整ジョブ」というものがあったので、SageMakerの理解を深めるために、組み込みアルゴリズムのXGBoostのハイパーパラメータを、ハイパーパラメータ調整ジョブで調整してみました。
環境
sagemaker 2.219.0
行った事(概要)
Nishikaのトレーニングコンペのマンション価格予測に対して、組み込みアルゴリズムのXGBoostを使って価格予測を行う際に、このXGBoostのハイパーパラメータを、ハイパーパラメータ調整ジョブを使って、調整してみます。
行った事(詳細)
1. Nishikaのサイトからデータを取得
上記のNishikaのコンペサイトから、train.zipファイルとtest.csvファイルをダウンロードします。
train.zipファイルは解凍して、trainフォルダを取得します。
2. S3バケットにフォルダを用意
訓練(train)データ、検証(valid)データを保存するフォルダをS3バケットに用意します。
3. Notebookインスタンスにデータをアップロード
Nishikaのサイトから取得した、trainフォルダ(train.zipファイルの解凍後)とtest.csvファイルを、Notebookインスタンスにアップロードします。
4. Notebookインスタンスにて.ipynbファイルを作成
カーネルはconda_python3を選択しました。
5. .ipynbファイルでコードを記載
5.1. 必要なライブラリーをインポート
from datetime import datetime
import glob
import os
import numpy as np
import pandas as pd
import boto3
import sagemaker
import sklearn.model_selection
5.2. 初期変数を設定
ROLE = sagemaker.get_execution_role()
SAGEMAKER_SESSION = sagemaker.Session()
S3_BUCKET = SAGEMAKER_SESSION.default_bucket()
S3_PREFIX = "data-for-machine-learning/tanaka/for_sagemaker_algorithm_XGBoost"
TRAIN_DATA_PATH = "train/input_train_data.csv"
VALID_DATA_PATH = "valid/input_valid_data.csv"
5.3. データを前処理
trainフォルダの中にあるcsvファイルを、pandasライブラリーを使って、1つのDataFrameデータに纏めます。
data_df_list = []
for csv_file in glob.glob("./data/Nishika_ApartmentPrice/train/*"):
df = pd.read_csv(filepath_or_buffer=csv_file,
converters={"面積(㎡)": str},
encoding="utf-8")
data_df_list.append(df)
data_df = pd.concat(objs=data_df_list,
axis=0,
ignore_index=True)
print(data_df.columns)
Index(['ID', '種類', '地域', '市区町村コード', '都道府県名', '市区町村名', '地区名', '最寄駅:名称',
'最寄駅:距離(分)', '間取り', '面積(㎡)', '土地の形状', '間口', '延床面積(㎡)', '建築年', '建物の構造',
'用途', '今後の利用目的', '前面道路:方位', '前面道路:種類', '前面道路:幅員(m)', '都市計画', '建ぺい率(%)',
'容積率(%)', '取引時点', '改装', '取引の事情等', '取引価格(総額)_log'],
dtype='object')
DataFrameデータには28個のカラムがありまして、予測の対象である目的変数は下記になります。
・取引価格(総額)_log
一方で、説明変数については、まずXGBoostはこちらの記載によると、
>たとえば、XGBoost アルゴリズムは数値データしか受け入れないため、
>入力データが文字列またはカテゴリ形式の場合は、
>使用する前に数値形式に変換する必要があります。
数値データのみしか扱えなさそうですので、今回は簡便に済ませたいため、数値データっぽいものを説明変数にしようと思います。
print(data_df.dtypes)
ID int64
種類 object
地域 float64
市区町村コード int64
都道府県名 object
市区町村名 object
地区名 object
最寄駅:名称 object
最寄駅:距離(分) object
間取り object
面積(㎡) object
土地の形状 float64
間口 float64
延床面積(㎡) float64
建築年 object
建物の構造 object
用途 object
今後の利用目的 object
前面道路:方位 float64
前面道路:種類 float64
前面道路:幅員(m) float64
都市計画 object
建ぺい率(%) float64
容積率(%) float64
取引時点 object
改装 object
取引の事情等 object
取引価格(総額)_log float64
dtype: object
上記を踏まえて、何となく数値データっぽいものとして、下記を説明変数にします。
・市区町村コード
・最寄駅:距離(分)
・面積(㎡)
・建ぺい率(%)
・容積率(%)
ただし、中身を見ると、欠損値があったり、文字列っぽいものがあったり、float型だったりするので、簡易ですが前処理を行います。
また、こちらを確認すると、データの1列目が目的変数、それ以降の列が説明変数、の並びである事がお作法のようですので、その並びにもします。
>列指向入力によるトレーニングでは、
>アルゴリズムはターゲット変数 (ラベル) が最初の列であることを前提としています。
>推論の場合、アルゴリズムは入力にラベル列がないと見なします。
data_df["面積(㎡)"] = data_df["面積(㎡)"].apply(lambda x: "2000" if x == "2000㎡以上" else x)
data_df["最寄駅:距離(分)"] = data_df["最寄駅:距離(分)"].apply(lambda x: "45" if x == "30分?60分" else "75" if x == "1H?1H30" else "105" if x == "1H30?2H" else "120" if x == "2H?" else x)
feature_data_df = data_df[["取引価格(総額)_log", "市区町村コード", "最寄駅:距離(分)", "面積(㎡)", "建ぺい率(%)", "容積率(%)"]].dropna(how="any").copy()
feature_data_df["最寄駅:距離(分)"] = feature_data_df["最寄駅:距離(分)"].astype("int")
feature_data_df["面積(㎡)"] = feature_data_df["面積(㎡)"].astype("int")
feature_data_df["建ぺい率(%)"] = feature_data_df["建ぺい率(%)"].astype("int")
feature_data_df["容積率(%)"] = feature_data_df["容積率(%)"].astype("int")
print(feature_data_df)
取引価格(総額)_log 市区町村コード 最寄駅:距離(分) 面積(㎡) 建ぺい率(%) 容積率(%)
0 6.875061 30201 45 45 80 300
1 7.397940 30201 8 75 80 400
2 6.880814 30201 6 75 80 400
3 6.869232 30201 29 60 80 300
4 7.255273 30201 9 65 80 400
... ... ... ... ... ... ...
637346 6.944483 41201 24 70 60 200
637347 7.000000 41201 6 65 80 400
637348 6.643453 41201 26 35 80 400
637349 6.431364 41201 28 15 80 400
637350 7.146128 41201 8 75 60 200
[600296 rows x 6 columns]
続いて、DataFrameデータを、訓練(train)データと検証(valid)データに分けます。
今回は、訓練(train)を80%、検証(valid)を20%の形で分けました。
train_df, valid_df = sklearn.model_selection.train_test_split(feature_data_df,
test_size=0.2,
random_state=42,
shuffle=True)
print(train_df)
print(valid_df)
取引価格(総額)_log 市区町村コード 最寄駅:距離(分) 面積(㎡) 建ぺい率(%) 容積率(%)
495218 7.255273 28111 15 85 60 200
618152 6.740363 43105 5 75 60 200
192482 7.041393 13114 5 15 80 400
280095 7.204120 13102 4 20 80 500
179815 7.322219 13104 6 20 80 500
... ... ... ... ... ... ...
114801 6.959041 11219 18 65 60 200
272349 7.322219 13119 8 20 80 500
386147 6.568202 23106 1 20 80 600
137545 7.255273 34101 45 65 80 300
127044 7.602060 4102 5 55 80 500
[480236 rows x 6 columns]
取引価格(総額)_log 市区町村コード 最寄駅:距離(分) 面積(㎡) 建ぺい率(%) 容積率(%)
496579 7.505150 28204 7 85 60 200
99805 7.146128 11243 6 75 60 200
268888 7.278754 13103 3 15 60 300
323553 7.414973 13114 5 35 80 500
253899 7.041393 13215 11 50 60 200
... ... ... ... ... ... ...
322959 7.544068 13122 8 60 60 400
59887 7.113943 27123 5 65 80 600
77106 7.322219 25201 1 85 80 600
461758 7.653213 14118 13 95 60 200
22763 7.477121 27109 4 85 80 600
[120060 rows x 6 columns]
5.4. 前処理したDataFrameデータをCSVファイルにしてS3へアップロード
まずは、訓練(train)データと検証(valid)データをCSVファイルとして、Notebookインスタンスのローカルに出力します。
これらのCSVファイルは、この後に、組み込みアルゴリズムのXGBoostモデルの学習の入力データになるのですが、カラム名(ヘッダー部分)は入力データに含めてはいけないお作法のようですので、CSVファイルにするこのタイミングで、カラム名を除きます。
>CSV データの場合、入力にヘッダーレコードを含めることはできません。
train_df.to_csv("./data/Nishika_ApartmentPrice/input_train_data.csv",
header=False,
index=False)
valid_df.to_csv("./data/Nishika_ApartmentPrice/input_valid_data.csv",
header=False,
index=False)
続いて、S3のフォルダにアップロードします。
train_data_file_path = os.path.join(S3_PREFIX, TRAIN_DATA_PATH)
valid_data_file_path = os.path.join(S3_PREFIX, VALID_DATA_PATH)
boto3.Session().resource("s3").Bucket(S3_BUCKET).Object(train_data_file_path).upload_file("./data/Nishika_ApartmentPrice/input_train_data.csv")
boto3.Session().resource("s3").Bucket(S3_BUCKET).Object(valid_data_file_path).upload_file("./data/Nishika_ApartmentPrice/input_valid_data.csv")
5.5. 組み込みアルゴリズムのXGBoostモデルのオブジェクトを作成
まずは、AWS側で用意している、組み込みアルゴリズムのXGBoostモデルのDockerコンテナのURIを取得します。
xgboost_container = sagemaker.image_uris.retrieve(framework="xgboost",
region="ap-northeast-1",
version="1.5-1")
print(xgboost_container)
354813040037.dkr.ecr.ap-northeast-1.amazonaws.com/sagemaker-xgboost:1.5-1
続いて、sagemakerライブラリーのEstimatorクラスを使って、組み込みアルゴリズムのXGBoostモデルのオブジェクトを作成します。
s3_train_output_path = "s3://" + os.path.join(S3_BUCKET, S3_PREFIX)
print(s3_train_output_path)
xgboost_model = sagemaker.estimator.Estimator(image_uri=xgboost_container,
role=ROLE,
instance_count=1,
instance_type="ml.m5.large",
output_path=s3_train_output_path,
sagemaker_session=SAGEMAKER_SESSION)
print(type(xgboost_model))
s3://sagemaker-ap-northeast-1-*****/data-for-machine-learning/for_sagemaker_algorithm_XGBoost
<class 'sagemaker.estimator.Estimator'>
それぞれの引数の意味は下記になります。
■image_uri
組み込みアルゴリズムのDockerイメージのURI
■role
割り当てるロール
■instance_count
組み込みアルゴリズムのモデルを動かすインスタンスの数
■instance_type
組み込みアルゴリズムのモデルを動かすインスタンスのタイプ
インスタンス毎の価格は
■output_path
学習完了後のモデルをファイル出力するS3のパス
■sagemaker_session
割り当てるセッション
次に、作成したXGBoostモデルのオブジェクトに、ハイパーパラメータを設定します。ここでは、ハイパーパラメータ調整ジョブで調整しないハイパーパラメータを設定します。
組み込みアルゴリズムのXGBoostモデルに設定出来るハイパーパラメータの一覧はこちらになります。
今回はアパート価格の予測なので、回帰タスクとして、評価関数はRMSEにします。
xgboost_model.set_hyperparameters(num_round=100,
early_stopping_rounds=20,
eval_metric="rmse",
objective="reg:squarederror")
5.6. ハイパーパラメータ調整ジョブのオブジェクトを作成
まずは、ハイパーパラメータ調整ジョブで調整したいハイパーパラメータと、そのハイパーパラメータの値の調整幅を、辞書型の変数に保存します。
ハイパーパラメータ調整ジョブで調整出来るハイパーパラメータの一覧はこちらになります。
値の調整幅を設定する際、そのハイパーパラメータが浮動小数点数を取り得る場合はsagemaker.tuner.ContinuousParameterで設定して、そのハイパーパラメータが整数のみを取り得る場合はsagemaker.tuner.IntegerParameterで設定します。
hyperparameter_tuning_range = {"eta": sagemaker.tuner.ContinuousParameter(0.25, 0.75),
"max_depth": sagemaker.tuner.IntegerParameter(5, 10)}
続いて、ハイパーパラメータを調整していく中で、「何をもってこのハイパーパラメータでの結果はイイか」を定量的に判断するための、ハイパーパラメータ調整ジョブでの評価関数を選択します。
ハイパーパラメータ調整ジョブでの評価関数の一覧はこちらになります。
今回は、ハイパーパラメータ調整ジョブでの評価関数もRMSEにします。
hyperparameter_tuning_job_objective_metric = "validation:rmse"
では、ハイパーパラメータ調整ジョブのオブジェクトを作成します。
オブジェクトの作成は、sagemaker.tuner.HyperparameterTunerクラスを用います。
設定出来る引数の一覧はこちらになります。
hyperparameter_tuner = sagemaker.tuner.HyperparameterTuner(estimator=xgboost_model,
objective_metric_name=hyperparameter_tuning_job_objective_metric,
objective_type="Minimize",
hyperparameter_ranges=hyperparameter_tuning_range,
strategy="Bayesian",
max_jobs=10,
max_parallel_jobs=2)
今回は下記の引数を設定しました。
■estimator
ハイパーパラメータを調整するモデル
■objective_metric_name
ハイパーパラメータ調整ジョブでの評価関数
■objective_type
ハイパーパラメータ調整ジョブでの評価関数のタイプ(MinimizeかMaxmizeを選択)
■hyperparameter_ranges
調整したいハイパーパラメータと、そのハイパーパラメータ値の調整幅
■strategy
調整したいハイパーパラメータの値をどのような方法で決めるか
(ベイズ最適化、ランダム、等を選べる)
■max_jobs
ハイパーパラメータ調整ジョブを行う回数
行った回数の中で、最も評価関数の値がイイ時のハイパーパラメータを用いる
■max_parallel_jobs
ハイパーパラメータ調整ジョブを何並列で行うか
(今回の設定ならば、10回のハイパーパラメータ調整ジョブを2並列で行う)
引数objective_typeには少し注意が必要でした。
今回、ハイパーパラメータ調整ジョブでの評価関数はRMSEにしました。RMSE値は「小さい程イイ結果」という事になりますので、ハイパーパラメータ調整ジョブは、「RMSE値の最小化を目指す」事になります。
どうやら、「最小化を目指す」という設定が引数objective_typeらしくて、この引数objective_typeのデフォルト値は上記のサイトを確認するとMaximizeになります。
よって、引数objective_typeにMinimizeを設定しないで、この後の処理を続けていくと、ハイパーパラメータ調整ジョブを起動する段階で、「RMSEは最大化を目指す評価関数ではない」ような旨のエラーメッセージが表示されて、ハイパーパラメータ調整ジョブが起動しませんでした。
そのため、引数objective_metric_nameに指定する評価関数によって、引数objective_typeにはMinimizeかMaxmizeの適切な方を指定する必要がありそうです。
5.7. ハイパーパラメータ調整ジョブの実行
まずは、S3バケットにアップロードした訓練(train)データと検証(valid)データを、sagemaker.inputs.TraingInputクラスを用いて、ハイパーパラメータ調整ジョブへ投げられる形にします。
sagemaker.inputs.TraingInputクラスでの引数の一覧はこちらになります。
今回はS3バケットにCSVファイル形式で保存しているので、引数content_typeにtext/csvを設定します。
他のファイル形式の場合、content_typeに設定出来る値の一覧はこちらになると思います。
s3_train_data_file_path = "s3://" + os.path.join(S3_BUCKET, S3_PREFIX, TRAIN_DATA_PATH)
print(s3_train_data_file_path)
s3_valid_data_file_path = "s3://" + os.path.join(S3_BUCKET, S3_PREFIX, VALID_DATA_PATH)
print(s3_valid_data_file_path)
s3_train_data = sagemaker.inputs.TrainingInput(s3_data=s3_train_data_file_path,
content_type="text/csv")
s3_valid_data = sagemaker.inputs.TrainingInput(s3_data=s3_valid_data_file_path,
content_type="text/csv")
s3://sagemaker-ap-northeast-1-*****/data-for-machine-learning/for_sagemaker_algorithm_XGBoost/train/input_train_data.csv
s3://sagemaker-ap-northeast-1-*****/data-for-machine-learning/for_sagemaker_algorithm_XGBoost/valid/input_valid_data.csv
<class 'sagemaker.inputs.TrainingInput'>
<class 'sagemaker.inputs.TrainingInput'>
では、作成したハイパーパラメータ調整ジョブのオブジェクトにて、fitメソッドを行って、ハイパーパラメータ調整ジョブを実行します。
now = datetime.now()
year = str(now.year)
month = str(now.month)
day = str(now.day)
hour = str(now.hour)
minute = str(now.minute)
second = str(now.second)
job_timestamp = year + month + day + hour + minute + second
tuning_job_name = "test-{a}".format(a=job_timestamp)
hyperparameter_tuner.fit({"train": s3_train_data, "validation": s3_valid_data},
job_name=tuning_job_name)
No finished training job found associated with this estimator. Please make sure this estimator is only used for building workflow config
..................................................!
何やらメッセージは出てしまっていますが、キチンとハイパーパラメータ調整ジョブは行われました。
実行結果を確認してみます。
print(hyperparameter_tuner.analytics().dataframe())
eta max_depth TrainingJobName TrainingJobStatus \
0 0.399198 10.0 test-20246274039-010-a994b43e Completed
1 0.462003 10.0 test-20246274039-009-906eefcf Completed
2 0.367259 10.0 test-20246274039-008-ab936e1f Completed
3 0.291412 10.0 test-20246274039-007-973e4641 Completed
4 0.459432 9.0 test-20246274039-006-786ca55a Completed
5 0.449122 10.0 test-20246274039-005-f7e07d6e Completed
6 0.631065 6.0 test-20246274039-004-30463e18 Completed
7 0.351344 7.0 test-20246274039-003-55cbfe9b Completed
8 0.556184 9.0 test-20246274039-002-8fbafbfa Completed
9 0.494499 5.0 test-20246274039-001-be622ff2 Completed
FinalObjectiveValue TrainingStartTime TrainingEndTime \
0 0.18460 2024-06-02 07:49:06+00:00 2024-06-02 07:50:25+00:00
1 0.18500 2024-06-02 07:48:51+00:00 2024-06-02 07:50:15+00:00
2 0.18448 2024-06-02 07:47:15+00:00 2024-06-02 07:48:40+00:00
3 0.18532 2024-06-02 07:47:13+00:00 2024-06-02 07:48:33+00:00
4 0.18602 2024-06-02 07:45:40+00:00 2024-06-02 07:46:54+00:00
5 0.18459 2024-06-02 07:45:37+00:00 2024-06-02 07:46:56+00:00
6 0.19240 2024-06-02 07:44:18+00:00 2024-06-02 07:45:22+00:00
7 0.19115 2024-06-02 07:44:09+00:00 2024-06-02 07:45:19+00:00
8 0.18643 2024-06-02 07:41:26+00:00 2024-06-02 07:44:06+00:00
9 0.19659 2024-06-02 07:41:22+00:00 2024-06-02 07:43:41+00:00
TrainingElapsedTimeSeconds
0 79.0
1 84.0
2 85.0
3 80.0
4 74.0
5 79.0
6 64.0
7 70.0
8 160.0
9 139.0
また、マネジメントコンソールのSageMakerの「トレーニング > ハイパーパラメータの調整ジョブ」でも実行結果を確認出来ます。
また、ハイパーパラメータ調整ジョブは、XGBoostモデルの学習も兼ねているようでして、XGBoostモデルを作成する時のEstimatorクラスの引数output_pathで指定したパスには、ハイパーパラメータ調整ジョブ毎にフォルダが作られ、そのフォルダの中には学習後XGBoostモデルのmodel.tar.gzファイルが保存されていました。
5.8. 学習後XGBoostモデルをデプロイ
ハイパーパラメータ調整ジョブが行われた事で、ハイパーパラメータ調整ジョブのオブジェクトは、最も優れていたハイパーパラメータが設定されて学習も済んでいるXGBoostモデルのような形になっているようなので、このハイパーパラメータ調整ジョブのオブジェクトでdeployメソッドを行って、デプロイ(エンドポイントを作成)します。
xgboost_model_inference = hyperparameter_tuner.deploy(initial_instance_count=1,
instance_type="ml.m5.large",
serializer=sagemaker.serializers.CSVSerializer(),
deserializer=sagemaker.deserializers.JSONDeserializer())
print("XGBoost model Endpoint name: {}".format(xgboost_model_inference.endpoint_name))
2024-06-02 07:49:04 Starting - Found matching resource for reuse
2024-06-02 07:49:04 Downloading - Downloading the training image
2024-06-02 07:49:04 Training - Training image download completed. Training in progress.
2024-06-02 07:49:04 Uploading - Uploading generated training model
2024-06-02 07:49:04 Completed - Resource reused by training job: test-20246274039-010-a994b43e
------!XGBoost model Endpoint name: test-20246274039-008-ab936e1f
無事にデプロイ出来ました。
マネジメントコンソールの「推論 > エンドポイント」でも、デプロイが完了してエンドポイントが作成されている事を確認出来ます。
5.10. アパート価格を学習後XGBoostモデルのエンドポイントで予測(推論)
Nishikaのコンペサイトから取得して、Notebookインスタンスのローカルにアップロードしていたtest.csvファイルを、テスト(test)データとしてpandasでDataFrameデータにします。
test_df = pd.read_csv(filepath_or_buffer="data/Nishika_ApartmentPrice/test.csv",
converters={"面積(㎡)": str},
encoding="utf-8")
学習後XGBoostモデルのエンドポイントに投げられるように、テスト(test)データを前処理します。
具体的には、
・説明変数のカラムのみにする
・文字列っぽいものを数字に書き換える
・int型にする
test_feature_df = test_df[["市区町村コード", "最寄駅:距離(分)", "面積(㎡)", "建ぺい率(%)", "容積率(%)"]].dropna(how="any").copy()
test_feature_df["面積(㎡)"] = test_feature_df["面積(㎡)"].apply(lambda x: "2000" if x == "2000㎡以上" else x)
test_feature_df["面積(㎡)"] = test_feature_df["面積(㎡)"].astype("int")
test_feature_df["最寄駅:距離(分)"] = test_feature_df["最寄駅:距離(分)"].apply(lambda x: "45" if x == "30分?60分" else "75" if x == "1H?1H30" else "105" if x == "1H30?2H" else "120" if x == "2H?" else x)
test_feature_df["最寄駅:距離(分)"] = test_feature_df["最寄駅:距離(分)"].astype("int")
test_feature_df["建ぺい率(%)"] = test_feature_df["建ぺい率(%)"].astype("int")
test_feature_df["容積率(%)"] = test_feature_df["容積率(%)"].astype("int")
print(test_feature_df)
市区町村コード 最寄駅:距離(分) 面積(㎡) 建ぺい率(%) 容積率(%)
0 1101 26 75 40 60
1 1101 1 55 80 600
2 1101 2 15 80 400
3 1101 2 45 80 400
4 1101 3 20 80 400
... ... ... ... ... ...
19453 47201 16 75 60 200
19454 47201 16 15 60 200
19456 47201 11 65 60 200
19457 47208 45 60 60 200
19458 47208 6 55 60 150
[19032 rows x 5 columns]
では、学習後XGBoostモデルのエンドポイントのオブジェクトのpredictメソッドへ、テスト(test)データを投げてみます。投げる際は、array型で投げる必要があるため、valuesを使ってarray型にします。今回は試しに最初の25件のデータを投げてみます。
また、投げる前に、学習後XGBoostモデルのエンドポイントのオブジェクトのcontent_typeをtext/csvに設定します。
xgboost_model_inference.content_type = "text/csv"
result_predict = xgboost_model_inference.predict(test_feature_df.iloc[0:25, :].values)
5.11. 予測結果を確認
変数result_predictの中身を確認してみます。
result_list = []
for result in result_predict["predictions"]:
result_list.append(result["score"])
print(result_list)
[7.107568740844727, 7.272197723388672, 6.398514747619629, 6.810839653015137, 6.300151348114014, 6.988745212554932, 6.398514747619629, 7.27155065536499, 7.122378349304199, 6.810839653015137, 6.338977336883545, 6.292942047119141, 6.418282508850098, 6.575599193572998, 7.38175106048584, 7.417739391326904, 7.083965301513672, 7.006527423858643, 7.3751139640808105, 6.239658355712891, 7.1481523513793945, 7.351635456085205, 7.48366117477417, 7.497321128845215, 7.153726100921631]
キチンと25個の推論結果を確認出来ました。
5.12. 後片付け
学習後XGBoostモデルのエンドポイントを残したままだと課金され続けてしまうので、削除します。
sagemaker.Session().delete_endpoint(xgboost_model_inference.endpoint_name)
また、課金の対象ではありませんが、「エンドポイント設定」と「モデル」も念のため、マネジメントコンソールから削除します。
以上になります。
まとめ
簡単ではありますが、SageMakerのハイパーパラメータ調整ジョブを一通り試してみて、大まかな流れを理解する事が出来ました。
また、お題として組み込みアルゴリズムのXGBoostも触ってみました。過去にローカル環境でLightGBMを少し触った事があるのですが、個人的にはLightGBMの方が触りやすかったかも(笑)
補足:model.tar.gzファイルから学習後モデルのオブジェクトをロードする場合
学習後(パラメータ調整ジョブを実施後)にS3へ出力されるmodel.tar.gzファイルを使って、学習後のXGBoostモデルのオブジェクトを作成(ロード)する事が出来ます。
用途としては、学習後にNotebookインスタンスを落として、別日に改めてNotebookインスタンスを立ち上げて、学習後XGBoostモデルのオブジェクトをロードしたい、等になります。
best_parameter_tuning_job_name = "test-202461124059-005-1a885639"
hyperparameter_tuner = sagemaker.model.Model(image_uri=xgboost_container,
model_data="{a}/{b}/output/model.tar.gz".format(a=s3_train_output_path,
b=best_parameter_tuning_job_name),
role=ROLE,
predictor_cls=sagemaker.predictor.RealTimePredictor)
print(type(hyperparameter_tuner))
<class 'sagemaker.model.Model'>
設定している引数について、はこちらの記事に記載しました。
参考