0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

【AWS SageMaker】Notebookインスタンスにて組み込みアルゴリズムのXGBoostでハイパーパラメータ調整ジョブを行ってみた

Posted at

背景

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バケットに用意します。

キャプチャ6.png

3. Notebookインスタンスにデータをアップロード

Nishikaのサイトから取得した、trainフォルダ(train.zipファイルの解凍後)とtest.csvファイルを、Notebookインスタンスにアップロードします。

スクショ2.png

4. Notebookインスタンスにて.ipynbファイルを作成

カーネルはconda_python3を選択しました。

スクショ3.png

5. .ipynbファイルでコードを記載

5.1. 必要なライブラリーをインポート
hogehoge.ipynb
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. 初期変数を設定
hogehoge.ipynb
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データに纏めます。

hogehoge.ipynb
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 アルゴリズムは数値データしか受け入れないため、
>入力データが文字列またはカテゴリ形式の場合は、
>使用する前に数値形式に変換する必要があります。

数値データのみしか扱えなさそうですので、今回は簡便に済ませたいため、数値データっぽいものを説明変数にしようと思います。

hogehoge.ipynb
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列目が目的変数、それ以降の列が説明変数、の並びである事がお作法のようですので、その並びにもします。

>列指向入力によるトレーニングでは、
>アルゴリズムはターゲット変数 (ラベル) が最初の列であることを前提としています。
>推論の場合、アルゴリズムは入力にラベル列がないと見なします。

hogehoge.ipynb
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%の形で分けました。

hogehoge.ipynb
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 データの場合、入力にヘッダーレコードを含めることはできません。

hogehoge.ipynb
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)

スクショ7.png

続いて、S3のフォルダにアップロードします。

hogehoge.ipynb
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")

スクショ8.png

スクショ9.png

5.5. 組み込みアルゴリズムのXGBoostモデルのオブジェクトを作成

まずは、AWS側で用意している、組み込みアルゴリズムのXGBoostモデルのDockerコンテナのURIを取得します。

hogehoge.ipynb
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モデルのオブジェクトを作成します。

hogehoge.ipynb
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にします。

hogehoge.ipynb
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で設定します。

hogehoge.ipynb
hyperparameter_tuning_range = {"eta": sagemaker.tuner.ContinuousParameter(0.25, 0.75),
                               "max_depth": sagemaker.tuner.IntegerParameter(5, 10)}

続いて、ハイパーパラメータを調整していく中で、「何をもってこのハイパーパラメータでの結果はイイか」を定量的に判断するための、ハイパーパラメータ調整ジョブでの評価関数を選択します。
ハイパーパラメータ調整ジョブでの評価関数の一覧はこちらになります。

今回は、ハイパーパラメータ調整ジョブでの評価関数もRMSEにします。

hogehoge.ipynb
hyperparameter_tuning_job_objective_metric = "validation:rmse"

では、ハイパーパラメータ調整ジョブのオブジェクトを作成します。
オブジェクトの作成は、sagemaker.tuner.HyperparameterTunerクラスを用います。
設定出来る引数の一覧はこちらになります。

hogehoge.ipynb
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に設定出来る値の一覧はこちらになると思います。

hogehoge.ipynb
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メソッドを行って、ハイパーパラメータ調整ジョブを実行します。

hogehoge.ipynb
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
..................................................!

何やらメッセージは出てしまっていますが、キチンとハイパーパラメータ調整ジョブは行われました。
実行結果を確認してみます。

hogehoge.ipynb
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の「トレーニング > ハイパーパラメータの調整ジョブ」でも実行結果を確認出来ます。

キャプチャ7.png

また、ハイパーパラメータ調整ジョブは、XGBoostモデルの学習も兼ねているようでして、XGBoostモデルを作成する時のEstimatorクラスの引数output_pathで指定したパスには、ハイパーパラメータ調整ジョブ毎にフォルダが作られ、そのフォルダの中には学習後XGBoostモデルのmodel.tar.gzファイルが保存されていました。

キャプチャ8.png

キャプチャ9.png

5.8. 学習後XGBoostモデルをデプロイ

ハイパーパラメータ調整ジョブが行われた事で、ハイパーパラメータ調整ジョブのオブジェクトは、最も優れていたハイパーパラメータが設定されて学習も済んでいるXGBoostモデルのような形になっているようなので、このハイパーパラメータ調整ジョブのオブジェクトでdeployメソッドを行って、デプロイ(エンドポイントを作成)します。

hogehoge.ipynb
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

無事にデプロイ出来ました。
マネジメントコンソールの「推論 > エンドポイント」でも、デプロイが完了してエンドポイントが作成されている事を確認出来ます。

キャプチャ1.png

5.10. アパート価格を学習後XGBoostモデルのエンドポイントで予測(推論)

Nishikaのコンペサイトから取得して、Notebookインスタンスのローカルにアップロードしていたtest.csvファイルを、テスト(test)データとしてpandasでDataFrameデータにします。

hogehoge.ipynb
test_df = pd.read_csv(filepath_or_buffer="data/Nishika_ApartmentPrice/test.csv",
                      converters={"面積(㎡)": str},
                      encoding="utf-8")

学習後XGBoostモデルのエンドポイントに投げられるように、テスト(test)データを前処理します。
具体的には、
 ・説明変数のカラムのみにする
 ・文字列っぽいものを数字に書き換える
 ・int型にする

hogehoge.ipynb
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に設定します。

hogehoge.ipynb
xgboost_model_inference.content_type = "text/csv"
result_predict = xgboost_model_inference.predict(test_feature_df.iloc[0:25, :].values)
5.11. 予測結果を確認

変数result_predictの中身を確認してみます。

hogehoge.ipynb
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モデルのエンドポイントを残したままだと課金され続けてしまうので、削除します。

hogehoge.ipynb
sagemaker.Session().delete_endpoint(xgboost_model_inference.endpoint_name)

また、課金の対象ではありませんが、「エンドポイント設定」と「モデル」も念のため、マネジメントコンソールから削除します。

キャプチャ4.png

キャプチャ5.png

以上になります。

まとめ

簡単ではありますが、SageMakerのハイパーパラメータ調整ジョブを一通り試してみて、大まかな流れを理解する事が出来ました。
また、お題として組み込みアルゴリズムのXGBoostも触ってみました。過去にローカル環境でLightGBMを少し触った事があるのですが、個人的にはLightGBMの方が触りやすかったかも(笑)

補足:model.tar.gzファイルから学習後モデルのオブジェクトをロードする場合

学習後(パラメータ調整ジョブを実施後)にS3へ出力されるmodel.tar.gzファイルを使って、学習後のXGBoostモデルのオブジェクトを作成(ロード)する事が出来ます。
用途としては、学習後にNotebookインスタンスを落として、別日に改めてNotebookインスタンスを立ち上げて、学習後XGBoostモデルのオブジェクトをロードしたい、等になります。

hogehoge.ipynb
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'>

設定している引数について、はこちらの記事に記載しました。

参考

0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?