【AWS】Amazon SageMaker ~ 入門編 ~

■ はじめに

今日、 Amazon SageMaker について、少し触れたので
基本的な用語やチュートリアル まで、まとめる

個人的な感想

使い勝手はいい。

Amazon SageMaker

=> Sage(セージ) = (思慮深く経験に富んで)賢い,賢明な, 賢人

https://ejje.weblio.jp/content/sage

* 完全マネージド型の機械学習サービス
(まさに、AWS版・機械学習のための統合開発環境)
 => 具体的には、おおきくわけて、以下の3つを簡単にAWS上で行えるサービス
 (1)コーディング / AWS上での開発環境提供(Jupyter Notebook etc)
 (2)トレーニング環境&機械学習モデル構築
 (3)デプロイ

料金

https://aws.amazon.com/jp/sagemaker/pricing/

SageMakerによる機械学習方法

SageMakerで機械学習する場合、3種類ある。

1)組み込みアルゴリズム (Built-in Algorithms)
2)機械学習用フレームワーク
3)独自実装

1)組み込みアルゴリズム (Built-in Algorithms)

 => SageMakerで用意してある機械学習アルゴリズムを
  組み込みアルゴリズム(ビルトインアルゴリズム)という
 => 学習データが必要

★ 今回は、これの「XGBoost」を使用する(詳細は、以下の関連記事を参照。)

https://dk521123.hatenablog.com/entry/2020/03/20/221553

2)機械学習フレームワーク
https://docs.aws.amazon.com/ja_jp/sagemaker/latest/dg/frameworks.html

 => TensorFlow、PyTorch、Apache MXNet、Chainer など
  による機械学習用フレームワークを使用
 => 学習データ、学習用コードが必要

3)独自実装

 => 独自の学習と推論用のコンテナを作成して使用
 => 学習データ、学習用コード入りのコンテナが必要

■ サンプル

チュートリアル - 定期預金申込見込み顧客予測
https://aws.amazon.com/jp/getting-started/tutorials/build-train-deploy-machine-learning-model-sagemaker/

などで、Hello world的なチュートリアルがあったので、やってみる
よくできたチュートリアルなので、すんなりできると思う
 => 強いていうなら、データセットの説明を詳しく、
 見やすいレイアウトだったら良かったが、、、

目的

* 銀行定期預金の申込見込み顧客を予測する
-> そのために、銀行顧客データと XGBoostを使用して、
  機械学習モデル(教師あり学習)を開発する

使用するデータ について

* カリフォルニア大学アーバイン校
 (UCI; University of California, Irvine)により
 監修された機械学習用データセット中の
 「Bank Marketing Data Set (銀行マーケティング・データセット)」を使用

https://archive.ics.uci.edu/ml/datasets/bank+marketing

* ポルトガルの銀行が行った電話による
 定期貯金のダイレクトマーケティングの結果データセット (Moro et al., 2014)


* データセットの列には、各ユーザーの年齢、職業、学歴などのデータがあり、
 銀行からのダイレクトマーケティングで、
 定期預金に申し込んでくれたかどうかが示されている
-> 顧客が申し込みをした(=1)、お申し込みをしなかった(ラベル=0)

-> 詳細は、以下のサイトによく書かれているので、そちらを参照

https://www.codexa.net/amazon-sagemaker-tutorial-marketing-offers/

* 実データは以下のURLから取得できる

https://d1.awsstatic.com/tmt/build-train-deploy-machine-learning-model-sagemaker/bank_clean.27f01fbbdf43271788427f3682996ae29ceca05d.csv

大きな流れ

ステップ 1: Amazon SageMaker コンソールにログインする
ステップ 2: Amazon SageMaker notebook instance を作成する
ステップ 3:データの準備
ステップ 4:データからのモデルのトレーニング
ステップ 5:モデルのデプロイ
ステップ 6:モデルの性能評価
ステップ 7:リソースを終了する

ステップ 1 ~ ステップ 3 / 3b

ステップ 1 ~ ステップ 3 / 3b までは、以下のサイトに従ってやればOK

https://aws.amazon.com/jp/getting-started/tutorials/build-train-deploy-machine-learning-model-sagemaker/

ステップ 3:データの準備

3c

# import libraries
import boto3, re, sys, math, json, os, sagemaker, urllib.request
from sagemaker import get_execution_role
import numpy as np                                
import pandas as pd                               
import matplotlib.pyplot as plt                   
from IPython.display import Image                 
from IPython.display import display               
from time import gmtime, strftime                 
from sagemaker.predictor import csv_serializer   

# Define IAM role
role = get_execution_role()
prefix = 'sagemaker/DEMO-xgboost-dm'

# each region has its XGBoost container
containers = {'us-west-2': '433757028032.dkr.ecr.us-west-2.amazonaws.com/xgboost:latest',
              'us-east-1': '811284229777.dkr.ecr.us-east-1.amazonaws.com/xgboost:latest',
              'us-east-2': '825641698319.dkr.ecr.us-east-2.amazonaws.com/xgboost:latest',
              'eu-west-1': '685385470294.dkr.ecr.eu-west-1.amazonaws.com/xgboost:latest'}

# set the region of the instance
my_region = boto3.session.Session().region_name

print("Success - the MySageMakerInstance is in the " + my_region + " region."
 + "You will use the " + containers[my_region] + " container for your SageMaker endpoint.")

# Jupyter の再生ボタンまたは Shift + Enter を押して、コード実行

準備

# ★ここを新規S3バケットを指定する(既に使用しているS3を指定した場合エラー)★
# <--- CHANGE THIS VARIABLE TO A UNIQUE NAME FOR YOUR BUCKET
bucket_name = 'your-s3-bucket-name'

s3 = boto3.resource('s3')
try:
    if  my_region == 'us-east-1':
      s3.create_bucket(Bucket=bucket_name)
    else: 
      s3.create_bucket(Bucket=bucket_name, CreateBucketConfiguration={ 'LocationConstraint': my_region })
    print('S3 bucket created successfully')
except Exception as e:
    print('S3 error: ',e)

ダウンロード

# .csv ファイルとして提供されるデータセットをダウンロード
try:
  urllib.request.urlretrieve (
   "https://d1.awsstatic.com/tmt/build-train-deploy-machine-learning-model-sagemaker/bank_clean.27f01fbbdf43271788427f3682996ae29ceca05d.csv",
   "bank_clean.csv")
  print('Success: downloaded bank_clean.csv.')
except Exception as e:
  print('Data load error: ',e)

# Pandasによるデータの読み込み
try:
  model_data = pd.read_csv('./bank_clean.csv',index_col=0)
  print('Success: Data loaded into dataframe.')
except Exception as e:
    print('Data load error: ',e)

# Pandasの最大表示カラム数と行数の設定を変更
pd.set_option('display.max_columns', 30)
pd.set_option('display.max_rows', 30)
 
# 最初の10行を表示
model_data.head(10)

3e (トレーニングデータとテストデータに分ける)

# トレーニングデータ : 顧客の 70%使用
# テストデータ : 残りの 30% の顧客
train_data, test_data = np.split(model_data.sample(frac=1, random_state=1729), [int(0.7 * len(model_data))])

print(train_data.shape, test_data.shape)

ステップ 4:データからのモデルのトレーニン

4a

# SageMakerのxGboost
# 1)最初の列に予測変数を設定する
# 2)ヘッダー行は使わない
pd.concat(
  [train_data['y_yes'],
  train_data.drop(['y_no', 'y_yes'], axis=1)],
  axis=1).to_csv('train.csv', index=False, header=False)

# S3 にアップロード
boto3.Session().resource('s3').Bucket(bucket_name).Object(
  os.path.join(prefix, 'train/train.csv')).upload_file('train.csv')

# 入力するトレーニングデータを抽出
s3_input_train = sagemaker.s3_input(
  s3_data='s3://{}/{}/train'.format(bucket_name, prefix),
  content_type='csv')

4b

# Amazon SageMaker セッションをセットアップ
sess = sagemaker.Session()

# XGBoost モデル (estimator) のインスタンスを作成
xgb = sagemaker.estimator.Estimator(
  containers[my_region],
  role,
  train_instance_count=1,
  train_instance_type='ml.m4.xlarge',
  output_path='s3://{}/{}/output'.format(bucket_name, prefix),
  sagemaker_session=sess)

# モデルのハイパーパラメーターを定義
# https://docs.aws.amazon.com/ja_jp/sagemaker/latest/dg/IC-Hyperparameter.html
xgb.set_hyperparameters(
  max_depth=5,
  eta=0.2,
  gamma=4,
  min_child_weight=6,
  subsample=0.8,
  silent=0,
  objective='binary:logistic',
  num_round=100)

4c (モデルのトレーニング)

# 勾配最適化を使用してモデルをトレーニング
xgb.fit({'train': s3_input_train})

ステップ 5:モデルのデプロイ

5a (デプロイ)

# モデルをサーバーにデプロイし、アクセス可能なエンドポイントを作成する
xgb_predictor = xgb.deploy(initial_instance_count=1,instance_type='ml.m4.xlarge')

5b (予測)

# テストデータの顧客が銀行の商品に申し込みを行ったかどうかを予測する

# load the data into an array
test_data_array = test_data.drop(['y_no', 'y_yes'], axis=1).values
# set the data type for an inference
xgb_predictor.content_type = 'text/csv'
# set the serializer type
xgb_predictor.serializer = csv_serializer
# predict!
predictions = xgb_predictor.predict(test_data_array).decode('utf-8')
# and turn the prediction into an array
predictions_array = np.fromstring(predictions[1:], sep=',')
print(predictions_array.shape)

ステップ 6:モデルの性能評価

6a (モデルの性能評価)

cm = pd.crosstab(index=test_data['y_yes'], columns=np.round(predictions_array), rownames=['Observed'], colnames=['Predicted'])

tn = cm.iloc[0,0]; fn = cm.iloc[1,0]; tp = cm.iloc[1,1]; fp = cm.iloc[0,1]; p = (tp+tn)/(tp+tn+fp+fn)*100

print("\n{0:<20}{1:<4.1f}%\n".format("Overall Classification Rate: ", p))
print("{0:<15}{1:<15}{2:>8}".format("Predicted", "No Purchase", "Purchase"))
print("Observed")
print("{0:<15}{1:<2.0f}% ({2:<}){3:>6.0f}% ({4:<})".format("No Purchase", tn/(tn+fn)*100,tn, fp/(tp+fp)*100, fp))
print("{0:<16}{1:<1.0f}% ({2:<}){3:>7.0f}% ({4:<}) \n".format("Purchase", fn/(tn+fn)*100,fn, tp/(tp+fp)*100, tp))

# テストデータにおける顧客の 90% に対して
# 申込者に対しては 65% (278/429)
# 申し込みしなかった顧客に対しては 90% (10,785/11,928) の精度で、
# 預金証書の申し込みを正確に予測できた

ステップ 7:リソースを終了する

6a (リソースを終了)

# Amazon SageMaker 関連のリソースを終了
# 重要: あまり使用されていないリソースを終了することは
# コストの削減につながるベストプラクティスです
# リソースを終了しないと、料金が発生することになります。

#.Amazon SageMaker エンドポイントを削除する
sagemaker.Session().delete_endpoint(xgb_predictor.endpoint)

#  S3 バケット内のオブジェクトを削除する
bucket_to_delete = boto3.resource('s3').Bucket(bucket_name)
bucket_to_delete.objects.all().delete()

参考文献

https://www.ogis-ri.co.jp/otc/hiroba/technical/intro-amazon-sagemaker/part1.html
https://www.codexa.net/amazon-sagemaker-tutorial-marketing-offers/

関連記事

Amazon SageMaker ~ 基本編 ~
https://dk521123.hatenablog.com/entry/2020/03/19/231652
Amazon SageMaker ~ 組み込みアルゴリズム
https://dk521123.hatenablog.com/entry/2020/03/20/221553
Pandas ~ データ解析支援ライブラリ ~
https://dk521123.hatenablog.com/entry/2019/10/22/014957