AWS

Amazon SageMakerを使って銀行定期預金の見込み顧客を予測【SageMaker +XGBoost 機械学習初心者チュートリアル】

  • このエントリーをはてなブックマークに追加

Amazonの新しい機械学習プラットフォーム「Amazon SageMaker(アマゾン・セージメーカー)」ですが、早速、機械学習初心者向けのハンズオンチュートリアル第一弾をまとめました!オンラインで公開されている銀行顧客のデータを利用して、Amazon SageMaker+XGBoostを使って、データの前処理からモデルホスティング、さらに評価確認までを一緒に行ってみましょう。

本チュートリアルですが、AWS 無料枠(Free Tier)を使用していません。ノートブックインスタンス、モデルトレーニング、モデルホスティングで料金が発生します。本チュートリアルを行うのに、3ドル〜5ドル発生します。料金は各自の責任でしっかりと確認した上でコードの実行をお願いします。(料金発生に関する必要な箇所はその都度、注釈を入れています)

SageMaker入門チュートリアル概要

所要時間目安
1時間〜3時間

実行する内容

  • SageMakerノートブックインスタンスの立ち上げ
  • データの処理
  • SageMaker XGBoostのモデル訓練
  • モデルのホスティング
  • テストデータをホスティングされたモデルで予測計算
  • モデルの評価

参考
https://bank-tutorial.notebook.us-east-1.sagemaker.aws/notebooks/bank-tutorial-1.ipynb

Amazon SageMakerの登録

まずはAmazon SageMakerへの登録を行いましょう。SageMakerの発表記事でも記載をしましたが、現段階で使えるリージョンはまだ4つのみとなっています。残念ながら東京リージョンは現時点で未対応です。本記事では、「米国東部(バージニア北部)」のリージョンを使っています。

12月11日時点では4つのリージョンのみ対応

Amazon SageMakerへのサインアップが完了するとダッシュボードへ遷移します。早速、ノートブックインスタンスの作成を行ってみましょう。

ノートブックインスタンスの作成をクリックすると、次画面でインスタンス作成画面へ遷移します。インスタンスの名前はとりあえず「 bank-tutorial 」として、またノートブックのインスタンスタイプも最小の「 ml.t2.medium 」を選びました。無料枠が使える方は、おそらくこちらで無料枠用のインスタンスが出てくるかと思いますので、ご希望の方はそちらを選んだ方が良いかと思います。

IAMロール(AWS内の権限を管理する機能)ですが、「 任意のS3バケット 」を選択しています。チュートリアルですので、セキュリティ面は深く考えていませんが、重要なデータを扱う場合は、IAMロールの設定を必ずしっかりと確認しましょう

他のVPCや暗号化キーはオプションとなっていますので、今回は特に指定せずノートブックインスタンスを作成します。

ノートブックインスタンスの作成が完了したら、ノートブックを立ち上げてみましょう。ノートブックインスタンス(下記キャプチャ)のページから、「オープン」をクリックするとJupyter Notebookのトップへ遷移します。

Jupyter Notebookページ(下記キャプチャ)の「New」からconda_python3を選択して、新しいノートブックを立ち上げましょう。

ノートブックの画面(下記キャプチャ)へ遷移しますので、解りやすいように名前の変更をしましょう。Jupyterのロゴのすぐ横の「 Untitled 」をクリックするとノートブックの名前の変更が可能です。「bank-tutorial-1」と名前を変更しておきましょう。

最後のステップとして、AWS S3のバケットネームの確認を行います。

本チュートリアルでは、後ほどSageMakerのノートブックとS3の連携を行いますので、S3の登録をまだ行っていない方は、こちらからどうぞ。またS3をすでに使っている方でも、リージョンが異なる場合は「米国東部(バージニア北部)」にて、新しいバケットの作成をお願いします。SageMakerとS3の連携ですが、リージョンが異なると行えないようです。

さて、これでアカウント周りの準備は完了です。次のステップでは、機械学習モデル構築の大まかな手順をみていきましょう。

データセットとモデル構築の概要

本チュートリアルでは、カルフォルニア大学アーバイン校が公開している「
Bank Marketing Data Set (銀行マーケティング・データセット)」を利用します。機械学習エンジニアなら、一度は耳にする初心者向けの非常に有名なデータセットです。

こちらのデータセットですが、ポルトガルのとある銀行が実際に行った、電話による定期貯金のダイレクトマーケティングの結果となります。各ユーザーの年齢や職業、さらには学歴などのデータがあり、ダイレクトマーケティングを行った結果、定期預金へお申し込みをした(ラベル=1)、お申し込みをしなかった(ラベル=0)が付与されています。

SageMakerを使ってこのデータセットの前処理を行い、XGBoostを使って予測を行います。本チュートリアルですが、SageMakerノートブックインスタンスを「ml.t2.medium」を使用しています。特に問題はありませんでしたが、ところどころ10分程度、時間がかかる処理がありました。ml.t2.mediumですが、vCPUが2、メモリーが4GBとなっています。もっと大規模な処理を行う場合には、上級インスタンスへ簡単に変更が可能なのは大きなメリットですね。(当然、料金も高くなりますが)

では、早速、Amazon SageMakerのノートブックを使ってデータセットを紐解いていきましょう。

ノートブックの立ち上げと準備

すでに前項目でSageMakerのノートブックインスタンスの立ち上げと、S3の設定(または新規登録)を行いましたので、早速ノートブックで下準備をしていきましょう。SageMakerの「ノートブックインスタンス」のページへアクセスしていただき、先ほど作った「bank-tutorial」を立ち上げましょう。

本チュートリアルの通りに設定をした方であればSageMakerのノートブックを立ち上げて、Jupyter Notebookのトップ画面で「bank-tutorial-1.ipynb」が作られているかと思います。こちらをクリックして、ノートブックを開きましょう。

準備編として、必要な設定変数とライブラリのインポートを行いましょう。下記のbucketの「XXXXXXXXXXX」ですが、各自のS3のバケット名へ変更をしましょう。またSageMakerとS3のリージョンが異なると動きませんので、リージョンが同じかどうか注意が必要です。

 prefix で指定したフォルダがS3へ新しく作られます。特に変更は必要ありませんが、適宜変更しても問題ありません。

最後にboto3とIAMのroleの宣言です。boto3ですすが、AWSが開発したPythonとAWSの各種サービスを統合するライブラリとなっています。(詳しくはこちらから)

こちらを最初のセルへ入力して、 Shift + Enter でセルの実行を行いましょう。

次は今回のモデル構築に使う必要なライブラリ各種を一気にインポートしちゃいましょう。

機械学習の定番(?)となるNumpy、Pandas、Matplotlibに加えて、ipython(Jupyter Notebook)で表などをプロッティングするモジュール、さらにsagemakerのPython SDKもインポートします。各ライブラリの詳細の説明は行いませんが、見たことのないライブラリがある方は、軽く調べてみると良いかと思います。

SageMakerノートブックでみると、下記キャプチャの様になっているかと思います。正しく処理が行えてれば、各セルの左上の [ ] に番号が表示されます。何かしらの理由で処理が終わらなかったりすると、こちらに[*]と処理中のマークが出ます。

*SageMakerのノートブックを立ち上げて、全く同じ内容でセル1を実行したら、処理が完了せず[*]が10分程度表示されました。原因不明でしたので、カーネルをリスタートさせて、全く同じ内容で実行したら今度はちゃんと処理が行われましたが・・念のため、同様の現象が出る方もいるかもしれませんので記載しておきます。

さて、次はデータをUCIからデータをダウロードして紐解いていきましょう!

データセットの取得と確認

カルフォルニア大学アーバイン校のサイトにてデータセットが公開されていますので、そちらから直接取得しましょう。特に会員登録などは必要ありません。 wget でURLから直接ダウロードして、 unizip (解答)してあげましょう。

Jupyter Notebookのtreeページを確認すると、ダウロードした bank-additional.zip と解凍された bank-additional というフォルダーが作成されているのが確認できます。

ではこちらのcsvファイルのデータセットを、Pandasのデータフレームとして読み込みましょう。

こちら記事内表示の便宜上、二段に分けて掲載しています。ご覧の通り、「age(年齢)」や「marital(結婚ステータス)」など各ユーザーの情報が格納されています。今後、機械学習を勉強されてる方にも解りやすいよう、簡単に各項目の概要をまとめました。

  • age – 顧客の年齢
  • job – 仕事のカテゴリ
  • marital – 結婚ステータス
  • education – 学歴
  • default – クレジットの支払遅延のステータス
  • housing – 不動産ローンの有無
  • loan – パーソナルローンの有無
  • contact – 銀行と顧客の連絡方法
  • month – 最後に連絡をとった月
  • day_of_week – 最後に連絡をとった曜日
  • duration – 最後の連絡長さ(秒数)
  • campaign – このキャンペーン中に銀行が連絡した回数
  • pdays – 最後のキャンペーンの連絡から経過した日にち
  • previous – このキャンペーン以前に銀行が連絡した回数
  • poutcome – 前回のキャンペーンの結果
  • emp.var.rate – Employment Variation Rate(詳細説明なし)*
  • cons.price.idx – 消費者物価指数 *
  • cons.conf.idx – 消費者信頼感指数 *
  • euribor3m – 3ヶ月スパンユーリボー指標金利 *
  • nr.employed – 四半期の従業員数 *
  • y – 顧客が定期預金を申し込みしたかどうか(予測ターゲット)
「*」の印をつけたものは外部環境要因のデータとなっています。特に「Employment Variation Rate」ですが、詳細の説明がありません。どのような指標なのか不明です。ヨーロッパでは当たり前の指標なのかもしれませんが・・

データセットの各項目の意味が理解できたところで、少し掘り下げてデータセットを紐解いていきましょう。まずは、お決まりの欠損データの確認をしておましょう。

こちら実はデータセットダウロードページでも説明があるのですが、なんと欠損データが一つもありません(感動)!欠損データで頭を悩ます必要がないなんて、嬉しい限りです。

次は各項目のデータの分散を確認してみましょう。

バーっと各項目の度数分布が出てくるのですが、いくつか気になる部分のデータをまとめてみてみましょう。下記画像ですが、左から「job(職業)」「education(学歴)」「martital(結婚ステータス)」の度数分布となっています。

さすが銀行のデータです。職業の項目の「unknown(不明)」の0.8%を筆頭に、他のデータでも不明の項目の割合が比較的小さいです。本記事では細かく触れませんが、他の項目のデータも紐解いていくと、このデータセットの特徴などが見えてきます。

また今回の予測ターゲットとなる「 y 」の項目も確認してみましょう。ご覧の通り、「 no 」が約88.7%とデータの大半を占めているのが解ります。こちらはキャンペーンで顧客が定期預金を申し込みしたかどうかのフラグとなっているので、「 no 」が多いのも納得できますね。

さて、次もお決まりですが、各項目が予測ターゲットとどのような関係となっているかを確認していきましょう。

バーっと表やテーブルが出てきますので、深く理解されたい方は、各項目のテーブルを紐解いてみてください。下記の図は、各項目の相関係数(data.corr())となっています。

いくつかの項目で高い正の相関と負の相関が見受けられますね。当然といえば当然ですが、外部環境要因の指標同士は高い相関があるようです。

ざっくりではありますが、データセットを簡単に紐解いてみました。次のステップでは、データセットの前処理、いわゆる「データクレンジング」をやっていきましょう。

データクレンジング(データセット前処理)

ほぼ全ての機械学習のプロセスで、データセットのクレンジングは必須の工程となっています。何が正しいのか、悪いのかという正解は無く、手探りでトライ&エラーを繰り返しながら進めていくのが通常です。

ただ、いくつか基本となる「前処理の前処理」とでも言いますか、一般的に広く使われている方法・テクニックがあります。

  • 欠損データを処理
  • カテゴリカルデータを処理
  • 特異な分散をしているデータを処理

すでに確認した通りで欠損データは含まれませんので今回は対応をしなくて大丈夫ですね。実際に行うデータの前処理ですが、下記の4つの処理を行いましょう。各処理の説明も記載しています。

[1] pdaysから連絡の取っていない顧客を抽出する
 pdays ですが、「最後のキャンペーンの連絡から経過した日にち」となります。すでにデータ確認のステップで見ましたが、 pdays は「 999 」のデータが非常に多かったです。つまり前回から連絡を取っていない顧客が大半と言えます。 pdays を少し処理して、999日(つまり連絡を取っていなかった顧客)を「 1 」としてそれ以外を「 0 」とするデータ処理をします。

jobから現在職についてない顧客を抽出する
 job (職業)の項目ですが、 unknown (不明)を含む12種類あります。よくこの項目をみて見ると、「 student (学生)」や「 unemployed (失業中)」など現時点で職についてない顧客が含まれています。そこで、現在働いているか、働いていないかを切り分けて新しく「 not_working 」(働いていない)という項目を追加する処理を行います。

カテゴリカルデータをダミー変数化する
ダミー変数とは、数字てはないデータを数字に変換する手法を指します。例えば、今回のデータで言うと、予測ターゲットの「 y 」ですが、持っている値が「 yes 」「 no 」となっています。これをダミー変数化すると、もともと一つの項目「 y  」が二つの項目「 y_yes 」と「 y_no 」に分裂して、各値に応じて「0」「1」が付与されます。機械学習では、かなり頻繁に行う処理です。Pandasではダミー変数化をするのはとても簡単で、pd.get_dummiesを使うことで、ほぼ自動的にダミー変数化してくれます。(get_dummies以外にも、カテゴリカルデータを数値に変換してくれるpd.cat.codeという便利な関数もあります)

予測モデルに組み込まない項目の削除
さて、最後に外部環境要因の指標( emp.var.rate )など、今回のトレーニングで使わない項目をpd.dropでデータフレームから削除を行います。

下記が、コードとなります。

ご覧の通り、ダミー変数化してますので、列数が多くなっているのが確認できます。また今回のモデルで使用しない項目が削除されていることも確認しておきましょう。

前処理が完了したので、次はデータを訓練データ、確認用データ、テストデータの3つに分けましょう。その前に機械学習では避けて通れない「Overfitting(オーバーフィッティング)(過学習)」について簡単に触れておきましょう。

教師あり学習モデル(Supervised Learning Models)は、与えられたデータで、「予測した値と実際の値の誤差をどれだけ最小にするか」を目的としてデザインされています。つまりモデルは、いかに予測値と実際の値の誤差を小さくするための計算を行うわけなんですが、そのプロセスの中で、モデルが、特異点までもを組み込んで偏った予測をしてしまうことが多々あります。これが過学習です。

特異点が新しいデータでも見られるパターンであれば、それを組み込んだモデルの予測は正確なものになるのですが、そうでないケースは、そのモデルの正確性は落ちてしまいます

この過学習を避けるテクニックは多数ありますが、一般的な方法として、モデルのトレーニングを一つのデータセットで行うのではなく、新しいデータセットでもトレーニングを行う手法です。

一先ず今回は「データを一回だけ訓練させると、そのデータには正確性が高い予測が出るけど・・新しいデータでの予測はそうとは限らないよね。だから元データを複数に分けて、複数回のトレーニングをした方が、今後の新しいデータへの予測に汎用性が高そうじゃない?」というくらいのニュアンスで理解しておきましょう!

ということで、今回のデータセットですが3つに分けることにします。

さて、とうとうデータ前処理の最終ステップとなります。Amazon SageMaker XGBoostのコンテナのデータフォーマットですが、libSVMとなります。libSVMフォーマットですが、feature(特徴量)と予測ターゲット(目的変数)を別々のアーギュメントにしなくてはいけませんので、その処理を行いましょう。

最後に、boto3経由でAWS S3へ、この訓練データセット(libSVM形式)を送っておきます。

最初の準備編で指定したAWS S3のバケットに新しく「 sagemaker 」というフォルダーが作成されているかと思います。繰り返しになりますが、SageMakerのリージョンとS3のリージョンが異なると、処理が行われませんので気をつけてください。

下記のキャプチャのように、 S3 > バケット名 > sagemaker > xgboost-dm > train のディレクトリーにtrain.libsvmが新規作成されているばオッケーです。

訓練(トレーニング)の実行

データセットの確認と前処理が完了しましたので、次はいよいよXGBoostを使ってモデルの構築を行いましょう。その前に、今回使うアルゴリズムとXGBoostの概要を簡単に説明します。

今回の予測モデルのアルゴリズムは「勾配ブースティングGradient Boosting)(グラディアント・ブースティング)」を使います。

勾配ブースティングの大まかなステップ

  • 多数の小さいシンプルな予測モデルを構築
  • この最小限予測モデルの「誤差」と「重み」を算出
  • 最小限予測モデルを最適化して一つの予測モデルとして構築

いまいち意味が解らなくても心配不要です!機械学習と一言で言っても、その内実は多数のアルゴリズム&予測モデルで溢れています。アルゴリズムを理解することで、より深く最適なモデル構築&予測を行うことができますが、そうでなくても、トライ&エラーを繰り返すことで予測はできます。

この「勾配ブースティング(Gradient Boosting)」を、より効率的に使いやすしたのが「XGBoost」です。XGBoostですがオープンソースで、世界中の機械学習エンジニアの間で人気が非常に高いフレームワークです。(XGBoostを使って、Kaggle(機械学習コンペ)の上位になることも可能ですので、初心者用のフレームワークという訳ではありません)

それでは、Amazon SageMakerでXGBoostを使って予測モデルの構築をしてみましょう!やり方は・・驚くくらい単純です。大まかなステップは以下の通り。

  1. Amazon SageMakerのXGBoostのためのECRコンテナの場所を指定
  2. 訓練データ(libSVM)とS3の連携してあげる
  3. sagemaker.estimator.Estimatorに必要な情報を指定
  4. ハイパーパラメーターの指定
  5. フィッティングと出力データのS3の格納先の指定

では、実際にSageMakerノートブックで上記の流れを行ってみましょう。

さて、次はSageMakerのEstimatorへ必要なパラメーターとハイパーパラメーターの指定をしてあげて、フィッティングを行います!下記コードですが、訓練用のインスタンスとして、 ml.m4.xlarge を使用しています。処理ですがおおよそ10分程度で完了します。参考までにですが、本チュートリアル全体(ノートブック、モデルトレーニング、モデルホスティングの全ての合計)で、約3〜4ドルくらいで行えました。

モデルトレーニング用のインスタンスはノートブックインスタンスと別扱いとなっており、別料金が設定されています。各自、各々の責任で設定をお願いします。

さて、いよいよモデルフィッティングとなります!

下記が出力されていれば、問題なくフィッティングが完了しています。

ハイパーパラメーターで設定した通り100ラウンドで完了していますね。ここまでのステップで、前処理を行ったデータを使って、XGBoostアルゴリズムの訓練(トレーニング)が完了できました。次は、この訓練したモデルをデプロイしましょう。

モデルホスティング(Model Hosting)のインスタンスの料金は別料金となります。今回のチュートリアルで使用しているリージョン(US East. N. Virginia)のモデルホスティングの料金表が下記となりますので、発生する料金をご理解した上でコードの実行をお願いします。

それでは、モデルホスティングを行いましょう。下記ですが、 ml.c4.xlarge のインスタンスを利用しています。(

処理完了まで約10分程度かかります

いよいよ、最後のステップ「評価(Evaluation)」となります。次のステップでは、今回、訓練したXGBoostの予測精度を確認してみましょう。

予測の精度確認(評価 / Evaluation)

機械学習モデルの評価方法ですが、多数の手法がありますが、本チュートリアルでは一番単純かつ簡単な「実データとの比較」を行いましょう。復習となりますが、今回の予測ターゲットは銀行のキャンペーンの定期預金のお申し込み状況(Yes or No)でしたね。

訓練したXGBoostアルゴリズムが予測した結果と実際のラベルを照らし合わせて、どれくらいの精度で予測したかを確認してみましょう。

最初のステップとして、評価で使うデータの渡し方と受け取り方を指定してあげます。テストデータですが、現在はSageMakerノートブックのインスタンス上にNumpy配列として置かれています。これをHTTP POSTリクエストで予測モデルに送るために、SageMakerの「 serializer 」を使ってシリアライズ化して、さらに content_type も指定しておきましょう。

次に前のステップで作成した test_data を500行ずつの小さいバッチに小分けして、XGBoostのエンドポイントで予測を行い、Numpyの配列として出力します。

これで、予測した値が predictions としてNumpy配列に格納されました!さぁ、いよいよ結果確認です。Pandasを使って、実際の正解データと予測した「 predictions 」の結果をテーブルにしてあげましょう。

*追記 3月13日*
下記、正解 x 予測比較のテーブルのコードが抜け落ちていましたので追記致しました。

(ドラムロール)(ドラムロール)

 う〜〜〜ん・・・なんとも微妙な感じの予測ですね(苦笑) 。テストデータ全4119件中、約4000人の顧客を「見込み顧客」として考えて、その中の480名が実際に定期預金へお申し込みをしたと言えます。

これを土台に、特徴量の調整やハイパーパラメーターの調整など、予測精度を改善してみると、より深い理解&学習になるかと思います!

最後に重要な作業です!!

本チュートリアルが終わったら、余計な料金が発生しないように、今回作成したエンドポイントを削除しましょう。不安な方は、SageMakerの管理画面で「モデル」「エンドポイント」「ノートブック」の状況が確認できますので、不必要なものは適宜、削除または停止をしておいた方が良いかと思います。

まとめとSageMakerの所感

少々長いチュートリアルになってしまいましたが、Amazon SageMakerは如何でしたでしょうか?個人的な所感ではありますが、機械学習エンジニアにとっては「孫の手」のようなツールだと感じました。

膨大なデータを処理する機械学習ですが、今までクラウド上で処理をされる方も多かったと思いますが、使いたいフレームワークやツールなど、その都度、設定やインストールを行い、全体の管理をするのに、それなりの労力があったかと思います。

また、作成したモデルをホスティングするのに、膨大な作業が必要だったのも事実です。SageMakerを利用することで、機械学習の0から100まで、ほぼ全てのステップが一括して行えるプラットフォームというのは非常に魅力的だと感じました!

他にも似たような機械学習初心者向けチュートリアルをやってみたいという方は、こちらも挑戦してみてください。

機械学習ではありませんが、ここ最近日本語解禁となったAmazon Alexa Skill Kit(ASK)の初心者入門チュートリアルも個人的にはおすすめです!(話題のスマートスピーカーAmazon Echoのスキル開発ができます)

以上、速報バージョンのAmazon SageMakerハンズオンチュートリアルとなります!随時、わかりやすいように改善をしていきますので、ご指摘やご意見はコメントにてお願いできればと思います!

追記 2017年12月21日

Amazon SageMakerチュートリアル第二段目を公開しました!ゲームソフトの売行きをXGBoostで予測してみた【Amazon SageMaker ノートブック+モデル訓練+モデルホスティングまで】

  • このエントリーをはてなブックマークに追加

無料で始める機械学習エンジニア入門

AIエンジニアへスキルアップをしませんか?コデクサでは、機械学習の初心者を対象に0から学べるコースを配信しています。

機械学習に必要な線形代数や統計基礎、さらに初歩的なアルゴリズムなどの無料コースを豊富に取り揃えています!

機械学習エンジニアへキャリアアップをしましょう!

コースを確認する

コメントを残す

*

日本語が含まれない投稿は無視されますのでご注意ください。(スパム対策)