0
0

【AWS SageMaker Canvas】AutoMLを試してみた

Posted at

背景

AWS SageMaker Canvasを用いる事で、機械学習モデルを自動作成して、そのままデプロイも行う事が出来るようですので、試してみました。

試した事(概要)

Nishikaのコンペの訓練(train)データとテスト(test)データを使って、SageMaker Canvasにて機械学習モデルを作成、デプロイして、デプロイしたモデルで推論を試してみました。

試した事(詳細)

1. 準備

1.1. データを用意

こちらのサイトから、train.zipとtest.csvをダウンロードします。

zipファイルを解凍すると、trainフォルダ内に多数のcsvファイルが入っていますので、それらcsvファイルを、pandasを使って1つのcsvファイルに纏めて、train.csvとします。

hogehoge.ipynb
train_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")
    train_df_list.append(df)
train_df = pd.concat(objs=train_df_list,
                     axis=0,
                     ignore_index=True)
print(train_df.columns)
train_df.to_csv(path_or_buf="data/Nishika_ApartmentPrice/train.csv",
                header=True,
                index=False,
                encoding="utf-8")
Index(['ID', '種類', '地域', '市区町村コード', '都道府県名', '市区町村名', '地区名', '最寄駅:名称', '最寄駅:距離(分)', '間取り', '面積(㎡)', '土地の形状', '間口', '延床面積(㎡)', '建築年', '建物の構造', '用途', '今後の利用目的', '前面道路:方位', '前面道路:種類', '前面道路:幅員(m)', '都市計画', '建ぺい率(%)', '容積率(%)', '取引時点', '改装', '取引の事情等', '取引価格(総額)_log'], dtype='object')
1.2. データを前処理

先程作成したtrain.csvと、先程ダウンロードしたtest.csvをDataFrameの形で取得します。

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

見やすくするために、カラムを少し減らそうと思います。
今回はこちらの記事の1.4.と同様の前処理を、train_dfとtest_dfに行います。

hogehoge.ipynb
simple_train_df = train_df[["市区町村コード", "最寄駅:距離(分)", "面積(㎡)", "建ぺい率(%)", "容積率(%)", "取引価格(総額)_log"]].dropna(how="any").copy()
simple_train_df["面積(㎡)"] = simple_train_df["面積(㎡)"].apply(lambda x: "2000" if x == "2000㎡以上" else x)
simple_train_df["面積(㎡)"] = simple_train_df["面積(㎡)"].astype("int")
simple_train_df["最寄駅:距離(分)"] = simple_train_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)
simple_train_df["最寄駅:距離(分)"] = simple_train_df["最寄駅:距離(分)"].astype("int")
simple_train_df["建ぺい率(%)"] = simple_train_df["建ぺい率(%)"].astype("int")
simple_train_df["容積率(%)"] = simple_train_df["容積率(%)"].astype("int")
print(simple_train_df)
        市区町村コード  最寄駅:距離(分)  面積(㎡)  建ぺい率(%)  容積率(%)  取引価格(総額)_log
0         30201         45     45       80     300      6.875061
1         30201          8     75       80     400      7.397940
2         30201          6     75       80     400      6.880814
3         30201         29     60       80     300      6.869232
4         30201          9     65       80     400      7.255273
...         ...        ...    ...      ...     ...           ...
637346    41201         24     70       60     200      6.944483
637347    41201          6     65       80     400      7.000000
637348    41201         26     35       80     400      6.643453
637349    41201         28     15       80     400      6.431364
637350    41201          8     75       60     200      7.146128

[600296 rows x 6 columns]
hogehoge.ipynb
simple_test_df = test_df[["市区町村コード", "最寄駅:距離(分)", "面積(㎡)", "建ぺい率(%)", "容積率(%)"]].dropna(how="any").copy()
simple_test_df["面積(㎡)"] = simple_test_df["面積(㎡)"].apply(lambda x: "2000" if x == "2000㎡以上" else x)
simple_test_df["面積(㎡)"] = simple_test_df["面積(㎡)"].astype("int")
simple_test_df["最寄駅:距離(分)"] = simple_test_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)
simple_test_df["最寄駅:距離(分)"] = simple_test_df["最寄駅:距離(分)"].astype("int")
simple_test_df["建ぺい率(%)"] = simple_test_df["建ぺい率(%)"].astype("int")
simple_test_df["容積率(%)"] = simple_test_df["容積率(%)"].astype("int")
print(simple_test_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]

作成したsimple_train_dfとsimple_test_dfを、simple_train.csvとsimple_test.csvのCSVファイルで保存して、ダウンロードします。

hogehoge.ipynb
simple_train_df.to_csv(path_or_buf="data/Nishika_ApartmentPrice/simple_train.csv",
                       header=True,
                       index=False,
                       encoding="utf-8")
simple_test_df.to_csv(path_or_buf="data/Nishika_ApartmentPrice/simple_test.csv",
                      header=True,
                      index=False,
                      encoding="utf-8")
1.3. S3にデータを保存

S3バケットにフォルダを作成して、そのフォルダに先程作成したsimple_train.csvとsimple_test.csvを保存します。

スクショ1.PNG

1.4. SageMakerのドメインのCanvas権限を変更

今回扱うSageMakerのドメインで、「アプリケーション設定」の「Canvas」部分の「Canvas モデルの直接デプロイを有効にする」が有効かどうかを確認します。

スクショ2.PNG

スクショ3.PNG

これが無効だった場合は、有効に変更します。
まずは編集ボタンをクリックします。

スクショ4.PNG

画面が変わった後、こちらのトグルを切り替えます。

スクショ5.PNG

スクショ6.PNG

画面下部の送信ボタンをクリックします。

スクショ7.PNG

有効に変わりました。

スクショ8.PNG


準備は以上になります。

2. 実装

SageMaker Canvasを開きます。

スクショ9.PNG

スクショ10.PNG

2.1. Datasetsを作成

まずは、S3に保存しているsimple_train.csvをインポートします。
Datasetsをクリックします。

スクショ11.PNG

画面右上のImport dataボタンをクリックして、Tabularをクリックします。

スクショ36.PNG

dataset名を入力します。今回はtrain_data_ForQiitaを入力して、Createボタンをクリックします。

スクショ13.PNG

Select a data sourceでAmazon S3を選択します。

スクショ14.PNG

対象バケットの対象フォルダからsimple_train.csvを選択して、Preview datasetボタンをクリックします。

スクショ15.PNG

simple_train.csvのプレビュー画面が表示されます。画面右上のCreate datasetボタンをクリックします。

スクショ16.PNG

Datasetsの画面に戻ります。train_data_ForQiitaが新規に作成されました。

スクショ17.PNG

同様の作業を、S3に保存しているsimple_test.csvに対しても行います。
(dataset名はtest_data_ForQiitaにしました。)

スクショ1.PNG

2.2. モデルを作成

訓練(train)データを使って、モデルを作成します。
Datasetsの画面で、train_data_ForQiitaを選択して、画面右上のCreate a modelボタンをクリックします。

スクショ2.PNG

モデル名はmodel_ForQiitaにします。今回はアパート価格の予測なので、回帰のPredictive analysisを選択した後、画面右下のCreateボタンをクリックします。

スクショ3.PNG

Target columnで取引価格_総額(log)を選択します。画面右のStandard buildの横の三角ボタンをクリックして、Quick buildを選択した後、Quick buildボタンをクリックします。

スクショ4.PNG

スクショ5.PNG

データ型の検証などが行われた後、モデルの作成が始まります。

スクショ6.PNG

スクショ7.PNG

少し待つと、モデルが作成されました。
画面右のModel leaderboardの横の矢印ボタンをクリックすると、モデルに関する情報を確認出来ます。

スクショ8.PNG

スクショ9.PNG

スクショ10.PNG

スクショ11.PNG

一通り内容を確認したら、画面右上のPredictボタンをクリックします。

スクショ12.PNG

Batch predictionを選択した後、Manualボタンをクリックします。

スクショ13.PNG

テスト(test)データのDatasetsであるtest_data_ForQiitaを選択して、画面右下のGenerate predictionsボタンをクリックします。

スクショ14.PNG

画面が戻ります。戻った画面の下で推論ジョブが行われた事を確認出来ます。

スクショ15.PNG

画面を右にスクロールして、status欄の縦三点ボタンをクリックすると、推論ジョブの結果の扱い方を選べますので、まずはPreviewを選んでみます。

スクショ16.PNG

スクショ17.PNG

予測されたアパート価格(取引価格_総額(log))を確認出来ました。

スクショ18.PNG

次はDownloadを選んでみます。

スクショ19.PNG

csvファイルの形で予測結果をダウンロード出来ました。

スクショ20.PNG

2.3. モデルをデプロイ

モデルを作成出来たので、このモデルをデプロイしてみます。

画面上のタブをAnalyzeに切り替えます。

スクショ21.PNG

画面右のDeployボタンをクリックします。
(もし、クリック出来ない場合は、1.4.の作業でキチンと権限が有効になっている事を確認します。)

スクショ22.PNG

デプロイの設定画面が出てきます。今回はデプロイ名をdeployForQiita、インスタンスタイプをml.t2.medium、インスタンス数を1に設定して、Deployボタンをクリックします。

スクショ24.PNG

モデルのデプロイが始まります。

スクショ25a.png

数分待つと、デプロイが完了しました。

スクショ26a.PNG

2.4. リアルタイム推論を実験

デプロイしたモデルのエンドポイント(URL)へ、説明変数のデータを投げると、目的変数のアパート価格の予測結果が返ってくる事を確認してみます。

画面上のDeployタブで、対象のデプロイの画面右の縦三点ボタンをクリックして、View detailsを選択します。

スクショ27a.PNG

対象のデプロイの詳細情報が表示されます。View sample codeの三角ボタンをクリックします。

スクショ28.PNG

デプロイしたモデルのエンドポイントを叩くための参考プログラムコードが表示されます。
これを参考にして、Notebookインスタンスから叩いてみます。

スクショ29.PNG

今回はSageMaker StudioのJupyterLabで試してみます。

スクショ30.PNG

test_ForQiita.ipynb
import boto3
import pandas as pd


data1 = ["11111", "50", "12", "220", "65"]
data2 = ["22222", "100", "5", "250", "75"]
data3 = ["33333", "75", "8", "200", "60"]

client = boto3.client("runtime.sagemaker")
body = pd.DataFrame([data1, data2, data3]).to_csv(header=False, index=False).encode("utf-8")

response = client.invoke_endpoint(
    EndpointName="canvas-deployForQiita",
    ContentType="text/csv",
    Body=body,
    Accept="application/json"
)

結果を確認してみます。

test_ForQiita.ipynb
print(response)
{'ResponseMetadata': {'RequestId': '70941f63-16ff-4277-a1d5-*****', 'HTTPStatusCode': 200, 'HTTPHeaders': {'x-amzn-requestid': '70941f63-16ff-4277-a1d5-*****', 'x-amzn-invoked-production-variant': 'canvas-model-variant-2024-07-11-02-00-56-194512', 'date': 'Thu, 11 Jul 2024 02:40:51 GMT', 'content-type': 'application/json', 'content-length': '107', 'connection': 'keep-alive'}, 'RetryAttempts': 0}, 'ContentType': 'application/json', 'InvokedProductionVariant': 'canvas-model-variant-2024-07-11-02-00-56-194512', 'Body': <botocore.response.StreamingBody object at 0x7f71e09*****>}

予測結果の確認は、readメソッドを使うみたいです。

test_ForQiita.ipynb
print(response['Body'].read().decode('utf-8'))
{"predictions": [{"score": 6.932327747344971}, {"score": 6.297735214233398}, {"score": 6.183495998382568}]}

アパート価格の予測結果を取得出来ました。

2.5. 後片付け

デプロイしたモデルのエンドポイントを残し続けると、インスタンスが稼働し続けている状態になってしまうので、課金対象になってしまいます。そのため、デプロイしたモデルのエンドポイントを削除します。

SageMaker CanvasのMy Modelsから対象のモデルをクリックします。

スクショ31.PNG

Version欄のV1をクリックします。

スクショ32.PNG

画面上のDeployタブに切り替えて、対象のモデルのデプロイの画面右の縦三点ボタンをクリックして、Delete deploymentをクリックします。

スクショ33.PNG

Deleteボタンをクリックします。

スクショ34.PNG

デプロイしたモデルのエンドポイントが削除されました。

スクショ35.PNG

試しにJupyterLabで先程実験したコードを叩いてみると、想定通りエラーになります。

ValidationError: An error occurred (ValidationError) when calling the InvokeEndpoint operation: Endpoint canvas-deployForQiita of account ***** not found.

以上になります。

まとめ

SageMaker CanvasのGUI操作でモデルの自動作成からデプロイまでを行う事が出来ました。デプロイしたモデルのエンドポイントを使った推論も簡単に出来ましたので、データを用意さえすれば、簡単にモデルの作成からデプロイまで出来そうと思いました。

参考

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