0
2

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 1 year has passed since last update.

Amazon SageMakerをはじめて使ってみる

Posted at

やりたいこと

SageMakerの特長や使い方などを学習したかったので、AWSのチュートリアルに沿ってひとまず使い始めてみたかった。

参考にしたサイト

やってみる

S3バケットの作成

まずはS3バケットを作成します。こちらのS3バケットにはチュートリアルで作成するノートブックインスタンスがデータを保存する際に、保存先として使います。
image.png

Notebookインスタンスの作成

Amazon SageMakerのコンソールに入り、「Notebook instance >> Create notebook instance」をクリックして、以下の画面からNotebookインスタンスを作成します。こちらのNotebookインスタンスの上で、PythonコードなどをRUNするイメージです。
image.png

S3バケットを選択する設定の部分は、先に作成したS3バケット名を入力します。
image.png

IAMロールは新規に作成し、Root accessはEnableのままとしておきます。ここまで設定したら「Create notebook instance」ボタンをクリックします。
image.png

notebookインスタンスの作成・起動が開始され、少し待つとSageMakerのコンソール画面ではStatusが「InService」となります。

Notebookインスタンスを使ってデータの準備をする

notebookインスタンスの起動が完了したので「Open Jupyter」をクリックします。
image.png

右上の「New」からconta_python3を選択して、Pythonを実行していくnotebookコンソールを表示します。
image.png

さて、ここからPythonを記述していきます。本記事のサンプルコードは全て参考資料にもあるAWS公式チュートリアルからコピーしてきています。

まずは以下のコードを張り付けてRUNをクリックします。ちなみにShift+EnterでもRUNとなります。 以下のコードでは必要なライブラリをインポートしたり、環境変数を定義したりしています。

# 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'
my_region = boto3.session.Session().region_name # set the region of the instance

# this line automatically looks for the XGBoost image URI and builds an XGBoost container.
xgboost_container = sagemaker.image_uris.retrieve("xgboost", my_region, "latest")

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

image.png
Successと出ればOKです。

次に以下のコードを貼り付けます。'your-s3-bucket-name'の個所は、任意のBuket名に置き換えます。先のステップとは別のS3バケットとなるので、新規の名前を付けてください。(そうでないと作成エラーとなります)
また、オプションですが、バケット作成先のリージョンも併せて変更してもOKです。

bucket_name = 'your-s3-bucket-name' # <--- CHANGE THIS VARIABLE TO A UNIQUE NAME FOR YOUR BUCKET
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)

準備ができたらRUN。
image.png

次に以下のコードを張り付けてRUN。サンプルデータをダウンロートしているのと、分析用に使えるようにPandasというライブラリのデータフレームにデータを入れています。model_dataの部分です。

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)

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)

image.png

どんなデータかは以下のコードをRUNすれば最初の5行が見れます。

model_data.head()

image.png

次に以下のコードをRUNします。データをシャッフルした上で、トレーニング用のデータとテスト(検証)用のデータに7:3の割合で分割してます。

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)

image.png
ここまででデータの準備が一旦できました。

MLモデルのトレーニング

引き続きnotebookに記述していきます。
以下のコードでは、準備したトレーニング用のデータに対して、形式を整えてS3バケットにcsvとしてアップロードしています。RUNします。

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)
boto3.Session().resource('s3').Bucket(bucket_name).Object(os.path.join(prefix, 'train/train.csv')).upload_file('train.csv')
s3_input_train = sagemaker.inputs.TrainingInput(s3_data='s3://{}/{}/train'.format(bucket_name, prefix), content_type='csv')

image.png

次に、sagemakerのセッションを作成して、XGBoostモデル(機械学習の広く使われるモデル)用のインスタンスを作成します。

sess = sagemaker.Session()
xgb = sagemaker.estimator.Estimator(xgboost_container,role, instance_count=1, instance_type='ml.m4.xlarge',output_path='s3://{}/{}/output'.format(bucket_name, prefix),sagemaker_session=sess)
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)

image.png

トレーニングJobを開始します。以下のコードをRUN。

xgb.fit({'train': s3_input_train})

image.png

ml.m4.xlarge instanceの上でトレーニングJobを実施しているのですが、思ったよりも待ちました。以下のように「Training secounds, Billable secounds」のログが出力されれば完了です。
image.png

モデルのデプロイ

MLモデルのトレーニングが終わったあとは、そのモデルをデプロイします。この辺もAmazon Sagemakerですんなりとできちゃうのが便利ですね。
以下のコードを実行します。5分弱くらい待ちました。

xgb_predictor = xgb.deploy(initial_instance_count=1,instance_type='ml.m4.xlarge')

image.png

「------!」ログが確認できれば完了してそうです。(公式ドキュメントもそうだった)
これでモデルに対するエンドポイントが使えるようになりました。
image.png

デプロイしたエンドポイントを使っていきます。
テスト用データセットから各顧客が商品に申し込んだか、申し込んでいないかどうかの予測を実施します。

from sagemaker.serializers import CSVSerializer

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

image.png
結果は次のコードをRUNして見れます。

モデルの評価

以下のコードをRUNして、作成しトレーニングしたモデルがどの程度の性能かを評価しています。

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))

テストデータ中の89.5%の顧客データに対して、申込みをしなかった場合は90%、申込みを行った場合は63%の精度で予測ができたと結果がでました。
image.png

以上までが、SageMaker利用によるメインの部分です。以降はクリーンアップ作業となります。

クリーンアップ

まずはSageMakerのエンドポイントを削除。

xgb_predictor.delete_endpoint(delete_endpoint_config=True)

image.png

次にS3バケットの中身を削除。
以下のコードではS3バケット自体は削除していないので、残ってしまって気持ち悪い方はコンソールからS3バケットも削除してOKです。

bucket_to_delete = boto3.resource('s3').Bucket(bucket_name)
bucket_to_delete.objects.all().delete()

image.png

最後にNotebookインスタンスをストップして、削除。
image.png
image.png

ここまでが作業となります。

おわりに

かなり簡単に開発環境の構築や、作成したモデルのデプロイまで実施できた印象です。機械学習のプロジェクトでは、開発環境の構築やメンバー間での環境の共有、アクセスの設定、デプロイ先の環境の構築など、データ分析作業以外にも負担になりそうな設定・構築が、Amazon Sagemakerを使うと大分簡略化できるだろうなと思いました。データ分析エンジニアにとってもハッピーな環境構築ができるのではないでしょうか!

0
2
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
2

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?