AWS Machine Learning のサンプルを動かしてみる

# あらすじ
これまで、混同行列とROC 曲線について学んでいきました。その知識を活かしてAWS Machine Learning を触っていきたいと思います。

![p.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/70152/d9bf3a34-2d5d-ed6b-68ac-f81f1eefa796.png)

前回までの話:
[混同行列(Confusion Matrix) とは 〜 2 値分類の機械学習のクラス分類について](https://qiita.com/TsutomuNakamura/items/a1a6a02cb9bb0dcbb37f)
[ROC 曲線とAUC を用いて2値分類機械学習モデルの性能を計測・チューニングする](https://qiita.com/TsutomuNakamura/items/ef963381e5d2768791d4)

# ストーリー
今回はAWS 側のチュートリアルで準備されている「とあるお店にて新しい商品を出したときにそれに顧客は反応(購入)をしてくれるか？」という推測を機械学習(ロジスティック回帰)を利用して学んでいきます。

## 利用するデータについて

今回はMachine Learning(以下:ML)でチュートリアルとして公開されている以下のデータを使います。

ML チュートリアル用データ(banking.csv)
<https://s3.amazonaws.com/aml-sample-data/banking.csv>

このデータは過去の顧客の詳細な動向(商品の購入や銀行の引き落としなど)の情報がCSV 形式で記録されていてこれを学習用データとして使います。
そして学習後、特定の顧客があなたの新しい製品を出したときにアクションを起こす可能性が高いかどうかを機械学習を使って推測してみましょう。

## 学習用データの形式

学習用データはAmazon ML 用の独自CSV 形式で準備します。どういったところが独自CSV 形式なのかというと、例えばCSV の先頭1
行目にはカラム名を挿入する等といったルールがあります。
詳しいデータのフォーマット形式については、以下のドキュメントを参考にしてください。

Understanding the Data Format for Amazon ML
<https://docs.aws.amazon.com/machine-learning/latest/dg/understanding-the-data-format-for-amazon-ml.html>

実際に上記の学習用データをテキストエディタで開くと、以下のように1 行目にカラム名が来てそれ以降はアトリビュートとして顧客の実データが入っています。

![AWSMachineLearning_Tutorial0000_02.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/70152/356c6a67-dbbd-f2e9-fce5-0700f7b7b833.png)

データの解説を少しすると、例えば上記の`job` はカスタマーの職業を表しており、`contact` は問合せしたときのデバイスが記録されています。
そして一番右のフィールドはML モデルに「このカスタマーは新しい製品をサブスクライブしますか？」という質問への回答になり、いわゆるこれが、機械学習でいわれる**教師データ**になります(Amazon ML ではターゲット属性と呼んでいる)。 この値は0(no) or 1(yes) の値になっており、オリジナルのデータはyes, no という文字列から、ML で学習させるために変換されています。
データの変換が完了したらML から読み取らせるために、あなたのS3 バケットにアップロードしてください。ただし、今回はAmazon で用意されているチュートリアルのファイル`s3://ami-sample-data/banking.csv`を使ってを動かすため、S3 へのアップロード手順及び作業は割愛します。

## その他の機械学習で使えそうなデータについて

今回利用するお店の顧客の動向以外にも、機械学習に使えそうなデータが公開されているUCI Machine Learning Repository という場所があります。

UCI Machine Learning Repository
<http://archive.ics.uci.edu/ml/index.php>

例えば上記サイトでは山火事が発生した場所の学習用データであったり、アイリスの花弁や萼片の長さと種類のデータであったり機械学習で使えるデータを無料で利用することができます。
CSV 形式で提供されてはいますが、Amazon ML で使う場合は一部CSV の形式をAmazon ML 形式に適用するよう修正する必要があります。

# データソースを作成する

学習用のデータが準備できたら、ML のデータソース作成へ進みます。
データソースとは、Amazon ML で使用する入力データのロケーション情報といった重要なデータやメタデータを含むAmazon ML のオブジェクトです。 Amazon ML はトレーニングや評価といったオペレーションのために、このデータソースを使います。
データソースを作成するために、以下の情報を設定します。

-   データのS3 のロケーションとアクセス権限
-   データ属性の名前及び型(Numeric(数値), Text(文字), Categorical(分類),
    binary(0 か1 か))
-   ML
    が予測フェーズで回答してほしい属性名。すなわちターゲット属性、教師データの属性名

それでは実際にチュートリアル用のデータソースを作成していきましょう。まずはデータソース作成画面を開きます。

| ![AWSMachineLearning_Tutorial0000.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/70152/f27ad5e4-cd9e-496d-38a4-e0ae4009d08f.png) |
|-----|

学習用データはAmazon S3 もしくはAmazon Redshift 上に格納されているものが利用できます。今回指定するのは公開S3 上に格納されている`s3://ami-sample-data/banking.csv` です。
必要事項を入力すると以下のようになります。

| ![AWSMachineLearning_Tutorial0001.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/70152/489edc10-e300-f2ff-1617-6071531b5fba.png) |
|-----|

`Verify` をクリックして検証を開始します。 ML がS3 のデータにアクセスする権限がない場合は、ここで権限を与えてよいか質問が来ます。

| ![AWSMachineLearning_Tutorial0002.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/70152/be433da1-dea1-73a5-7215-aa5fd3b54df9.png) |
|-----|


検証が完了すると次へ進めるので**Continue** をクリックします。
スキーマ作成画面へ進みます。スキーマを作成する方法は主に以下の2 通りの方法があります。

-   S3
    にデータをアップロードする時に分割されたスキーマファイルをアップロードする方法
-   Amazon ML サービス側に推測させる方法

今回はAmazon ML サービス側に推測させる方法で行ない、推測の結果を我々でレビューし、適宜修正して上げる方法で実施していきます。

【補足】スキーマファイルについての説明
<https://docs.aws.amazon.com/machine-learning/latest/dg/creating-a-data-schema-for-amazon-ml.html>

スキーマ作成画面を見るとCSV データの1 行目に書いてあるカラム名からデータの型が推測されるので、これをレビューして正しいデータの型となるように適宜修正していきます。
設定できるデータの型のとしては以下のものがあります。

-   Binary: yes またはno 等の2 つの状態のみを持つ属性
-   Category: 種類を示すために数値または文字列が使用される属性
-   Numeric: 順序に意味を持つ数値が使用される属性
-   Text:
    空白で区切られた、単語から成る文字列として使用される属性(「空白で区切られた」ということは現状英語しか対応してなさそう)

| Binary   | yes またはno 等の2 つの状態のみを持つ属性                                                                              |
|----------|------------------------------------------------------------------------------------------------------------------------|
| Category | 種類を示すために数値または文字列が使用される属性                                                                       |
| Numeric  | 順序に意味を持つ数値が使用される属性                                                                                   |
| Text     | 空白で区切られた、単語から成る文字列として使用される属性(「空白で区切られた」ということは現状英語しか対応してなさそう) |

このデータが間違ったままだとML が正しく学習を行えず、予測フェーズにて支障をきたす場合がありますので、注意してレビューを行うようにします。

内容を確認したら`Continue` をクリックします(今回のチュートリアル用データでは、全て正しく推測されるようになっている)。

| ![AWSMachineLearning_Tutorial0004.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/70152/fdffc4a4-8914-8b7b-c8ae-e717b58ffad0.png) |
|---|





すると、次はターゲット属性(教師データ)の選択画面へ移動します。 `y` カラムを選択して`Continue` をクリックします。

| ![AWSMachineLearning_Tutorial0005.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/70152/b37b4f8c-d292-4e0a-fb42-becc3c102fdc.png) |
|------------------------------------------------------------------------|

任意で行識別子(予測の時に、インプットデータのどの行に対応するのかを指し示すためのもの)を挿入するかどうかの選択が聞かれますので`no` を選択して`Review` をクリックします。

| ![AWSMachineLearning_Tutorial0006.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/70152/ea99ef67-2697-e666-51df-cf1d9493783d.png) |
|------------------------------------------------------------------------|

内容に問題なければ`Continue` をクリックします。これでML モデルを作成する準備ができました。

# ML(Machine Learning) モデルを作成する

データソースを作成後、ML モデルを作成してトレーニングし、その結果を評価します。 ML モデルとはAmazon ML がトレーニング中にデータを見つけるパターン(どのような解析法を使う、学習の方法等)の集合でモデルを作成して予測に利用することができます。

ML モデル設定画面で、モデルの設定を行ないます。

| ML model type                           | BINARY                | 2 値分類。ロジスティック回帰アルゴリズムを使用してトレーニングされます                                                |
|-----------------------------------------|-----------------------|-----------------------------------------------------------------------------------------------------------------------|
| ML model target                         | y                     | ターゲット属性。教師データとする属性                                                                                  |
| ML model target(任意)                   | Banking tutorial      | ML model 名。デフォルトでデータソース作成時に指定した値が表示される                                                   |
| Select training and evaluation settings | Default (Recommended) | ML の学習プロセスにおいてそれをコントロールするレシピとトレーニングパラメータ。今回は推奨となっている`Default` を選択 |
| Evaluation Name                         | Banking tutorial      | この評価の名前。デフォルトでデータソース作成時に指定した値が表示される                                                |

内容を確認したら`Review` をクリックします。

| ![AWSMachineLearning_Tutorial0007.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/70152/8343b4e0-9f24-16a1-de04-a6faaaff3dc8.png) |
|------------------------------------------------------------------------|

内容に問題がなければ`Create ML model` をクリックしてML モデルを作成します。

| ![AWSMachineLearning_Tutorial0008.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/70152/be7969c1-efc9-c512-1631-7afa51af2522.png) |
|------------------------------------------------------------------------|

ボタンをクリックするとAmazon ML はプロセスキューにあなたのML 入れます。
ML を作成した直後はStatus が`Pending` になり、学習処理が開始されると`In Progress` に変わり、完了すると`Completed` に変わります。
なおML で行われている学習ですが、今回のML ではデータ全体のうち70% のデータを学習用のデータとして抽出して残り30% を評価(テスト)として利用します。

# モデルの予測のパフォーマンスの確認と、スコアの閾値の設定

業界標準の**Area Under the (Receiver Operating Characteristic) Curve (AUC: 曲線下面積)**メトリクスというML モデルのパフォーマンス品質を計測する精度法を提供しています。 AUC はネガティブ(ポジティブ)なサンプルとポジティブ(ネガティブ)なサンプルに対する、正しさの精度(ML としての性能)を計測する指標を持っています。
ここでは実際にAUC を使ってML の性能を確認し、ML が使われるビジネスの戦略に適合した挙動となるように閾値を調整してみましょう。

Amazon ML のリストページに移動しましょう。すると、以下のようなリストが表示されます。

| ![AWSMachineLearning_Tutorial0010.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/70152/f23c0de4-71bd-e0cc-54fd-4c15d358d06e.png) |
|---|

その中で`Evaluation` を選択します。

| ![AWSMachineLearning_Tutorial0011.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/70152/af2eacd3-29c3-8fe8-40c0-7e795b5a4c98.png) |
|---|

すると上記のようなページが表示されるのでAUC(Area Under the Curve)パフォーマンスメロリックを確認しましょう。 するとAUC の値が0.936 と表示されており性能が良いということを表しています。
上記のままML を利用するのもアリなのですが、閾値を調整してML 推測の傾向をチューニングしてみましょう。 別の言い方をすれば、ML が「顧客は新しい商品を買ってくれますか？」という推測に対して、甘めの判断でYes!と推測するようにするか、厳し目の判断でNo!と推測とするかといった塩梅を、閾値を変更することで調整することができます。

では閾値を調整するために`Adjust score threshold` をクリックしてみましょう。

| ![AWSMachineLearning_Tutorial0012.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/70152/5852f50f-b9b5-55ea-c84e-9d0a244e844c.png) |
|---|

すると**TP(True Positive)**, **TN(True Negative)**, **FP(False Positive)**, **FN(False Negative)**の成績及び閾値を調整する項目が出現します。
表示されている内容を確認すると、正しく識別できている確率は91%($\\dfrac{TP + TN}{TP + TN + FP + FN}=0.91$) で、だいたいの推測は問題なくできていることを示しています。

この画面で調整できるのは主に閾値です。
閾値を上げたり下げたりすることで、ML の推測の性能がどのように変わっていくかという簡単な表は以下の通りです(ML モデルが出した推測結果の分布によっては必ずしもこうなるとは限りません)。

| 閾値 | TP  | TN  | FP  | FN  |
|------|-----|-----|-----|-----|
| ↑    | ↓   | ↑   | ↓   | ↑   |
| ↓    | ↑   | ↓   | ↑   | ↓   |

また、Advanced Metric に表示されている各項目の意味は以下の通りです。

# False Positive Rate (FPR: 誤検出率)

本当は0(negative) と判断すべきところを誤って1(positive) と判断してしまう割合です。値が小さいほど性能が良いことを意味します。

-   False Positive Rate(FPR)

$FPR=\\dfrac{FP}{FP + TN}$

## Presision(精度)

1(Positive) と予測されるべき全結果の中で実際に1(Positive) として予測できた割合です。この値が大きいほど性能が良いことを意味します。

-   Presision

$Presision=\\dfrac{TP}{TP + FP}$

## Recall(リコール)

実際に1(Positive) を識別されるべき全データ(TP + FN)の内、実際に1(Positive)と識別されたデータ(TP)の割合を示します。この値が大きいほど性能が良いことを意味します。

-   Recall

$Recall=\\dfrac{TP}{TP + FN}$

## Accuracy(正確さ)

全予測結果のうち、正しく1(Positive)と推測できたものと、正しく0(Negative)
と推測できたものの割合です。正しく予測できた割合です。この値が大きいほど性能が良いことを意味します。

-   Accuracy

$Accuracy = \\dfrac{TP + TN}{TP + FP + FN + TN}$

# 実際どれくらいの閾値に設定するか

今回のように新しい製品を打ってどれだけの人が反応してくれるかという問題については、本当は0(Negative)と判断すべき所を1(Positive)と判断してしまう(False Positive(FP))ことによって、余計な広告コストを払ってしまう可能性が高くなります(FP な人は買ってくれる見込みが殆どないので)。
そのため今回は誤検出率(FPR)を【下げる】ために、閾値を【上げる】というチューニングをして、余計な広告コストを払わない戦略を取るようにしてみましょう。

ということで、画面より閾値を`0.77` あたりまで上げてみることにします。
すると全体の約3% の顧客を1(Positive) として推測されるようになります。そして、誤検出率(FPR) については0.8% 程までに下がるようになります。
(幾つか注意してほしい点としては、この約3% の中にはTP もFP も含まれていること、閾値0.5 の時よりPositive の総数が下がっていること、閾値を上げることでTP をいくつか失うこと等があります)

| ![AWSMachineLearning_Tutorial0014.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/70152/87c0363a-531a-28d1-dbbd-bff977185865.png) |
|---|

以上で閾値のチューニングは完了です。設定を保存してML の完成です。

## 誤検出率を下げすぎる(閾値を上げすぎる)とどうなるか

誤検出率を下げすぎると、ML はほぼすべてのケースで1(Positive) を回答してくれなくなります。

| ![AWSMachineLearning_Tutorial0015.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/70152/c96ebb47-2474-b09d-4c48-4d5ee55777d0.png) |
|---|

そして最大限まで誤検出率を下げる(閾値を上げる)と、ML はすべての推測要求に対して0(Negative)を返すようになってしまいます。 そのため、閾値は適度に設定するよう注意しましょう。

# ML を使って予測をする

ML ができたところで、次はML を使って予測を実施してみましょう。
予測を実施する方式として、Amazon ML では主に以下の2 つの方法が用意されています。

-   リアルタイム推測(real-time predictions)
-   バッチ推測(iBatch Predictions)

## リアルタイム推測(Try real-time predictions)

Web 画面から気軽に単発の推測要求を出すことができる、リアルタイム推測のやり方です。
`ML model report` のナビゲーションペインから`Try real-time predictions` を選択します。

| ![AWSMachineLearning_Tutorial0016.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/70152/c02d715c-8561-2f95-30ed-b173bd3a5920.png) |
|-----------------------------------------------------------------|

`Paste a record` を選択して以下の通りCSV レコードを入力します。

| ![AWSMachineLearning_Tutorial0017.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/70152/7d795d46-a980-5b56-5c1e-5a4afe241b94.png) |
|------------------------------------------------------------------------|

`32,services,divorced,basic.9y,no,unknown,yes,cellular,dec,mon,110,1,11,0,nonexistent,-1.8,94.465,-36.1,0.883,5228.1`

このCSV レコードはとある32 歳の人のデータになります。この32 歳の人が新しい商品を買ってくれそうか推測してみましょう。

ペーストして、Submit ボタンを押すとCSV の定義が画面に整形されてた状態で表示されます。

| ![AWSMachineLearning_Tutorial0018.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/70152/62f1c9e9-4670-056a-47f9-48ae2c0dd5ba.jpeg) |
|------------------------------------------------------------------------|

入力内容を確認したら`Create Prediction` をクリックします。
すると、ページ右側に予測の結果が出力されます。

| ![AWSMachineLearning_Tutorial0019.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/70152/a991594d-af42-30e2-b5fe-fc9e65b7118c.png) |
|------------------------------------------------------------------------|

結果を確認すると`predictedLabel` が0 となっています。すなわち、この32 歳の顧客は新しい製品を出しても、きっと購入してくれないだろうというML の予測結果になりました。
このようにしてリアルタイム推測を使うことで、単発の推測を即時で実行することができます。

## バッチ推測(Batch Predictions)

バッチ推測はあらかじめ推測させたい対象をCSV 形式でまとめておき、それをバッチ処理として推測させる方式です。
バッチ推測を利用するには画面左上の`Amazon Machine Learning` のメニューをクリックし`Batch Predictions` をクリックします。

| ![AWSMachineLearning_Tutorial0020.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/70152/e61b4db1-1987-6c86-b64e-36d6ac8cb38c.png) |
|------------------------------------------------------------------------|

`Create new batch prediction`をクリックします。

| ![AWSMachineLearning_Tutorial0021.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/70152/bc710a31-164d-8f29-2bc2-634a5a305fbd.png) |
|-----------------------------------------------------------------|

作成したML モデルの一覧が表示されるので、先程作成したML を選択します。

| ![AWSMachineLearning_Tutorial0022.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/70152/c3174303-2b2a-1968-1894-c3073ea7c33d.png) |
|------------------------------------------------------------------------|

内容を確認して`Continue` をクリックします。

| ![AWSMachineLearning_Tutorial0023.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/70152/9c45fc2b-3da1-0ee3-ca4f-aae805288936.png) |
|------------------------------------------------------------------------|

バッチ推測で使用するデータは、サンプルとして用意されている`s3://aml-sample-data/banking-batch.csv` を利用します。
ラジオボタンで`My data is in S3, and I need to create a datasource` を選択し、その他ファイルのロケーション情報等を入力し`Continue` ボタンをクリックします。

| ![AWSMachineLearning_Tutorial0024.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/70152/69c8ed9f-552c-bd0f-1a00-dd8c38fa1833.png) |
|------------------------------------------------------------------------|

次に、結果を格納するS3 バケットのロケーションを設定します。このS3 ロケーションは予め作成しておく必要がありますが、S3 バケットの作成方法については説明を割愛します。

| ![AWSMachineLearning_Tutorial0025.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/70152/ad9dfc2d-0a11-0a28-931f-97e98f99772e.png) |
|------------------------------------------------------------------------|

以下のように書き込み権限を要求されたら、Yes をクリックして書き込み権限を与えるようにしてください。

| ![AWSMachineLearning_Tutorial0026.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/70152/8aee6ae8-102e-21bd-e32c-611c7c47c0da.png) |
|------------------------------------------------------------------------|

確認画面が表示されるので、確認して`Create batch prediction` をクリックします。

| ![AWSMachineLearning_Tutorial0027.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/70152/1d003d55-5e6a-983b-7ad8-b396ece2416d.png) |
|------------------------------------------------------------------------|

すると処理キューの中に推測バッチ処理が入り`Batch prediction summary` が表示され、処理が完了していない間はStatus が`In progress` で表示されます。
しばらくして画面を更新すると`Status` が`Completed` に更新されます。



| ![AWSMachineLearning_Tutorial0028.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/70152/95bd12f8-2f82-05cb-113f-3ed44ca25e82.png) |
|-----------------------------------------------------------------|

<your backet name>`/batch-prediction/result/` ディレクトリ配下にCSV ファイルをgz 圧縮したファイルが格納されているので、それをダウンロードして展開して中身を確認してみましょう。
中身は`bestAnswer, score` の2 項目が表示されています。 score は指数表記になっている場合があるのでスプレッドシートなどに張り替えて変換すると良いでしょう。

結果を確認すると総計4119 件で、1: Positiveは122 件、0: Negativeは 3997件あり、Positive とNegative の境界はML の評価のページで設定した0.77 になっています。

``` text
1   0.771587
1   0.771126
1   0.770161
0   0.767255
0   0.765271
```

またPositive の中での最高スコアは約0.993179で最低スコアは約0.770161、Negative の中での最高スコアは約0.767255で最低スコアは約0.000678 となっていることがわかります。

本チュートリアルを通して、新しい商品に対して購入のアクションをしてくれそうな人をML で予測してコストを削減しながら効率的な宣伝をするといった戦略をとる手助けとしてAmazon ML を使うこともできるのです。

# 参考
Amazon Machine Learning
<https://aws.amazon.com/jp/machine-learning/>

UCI Machine Learning Repository
<http://archive.ics.uci.edu/ml/datasets.html>

チュートリアルの解説
<https://docs.aws.amazon.com/machine-learning/latest/dg/tutorial.html>

AUC の簡単な説明
<https://docs.aws.amazon.com/machine-learning/latest/dg/binary-model-insights.html?shortFooter=true#measuring-ml-model-accuracy>