Amazon Machine Learning 外部から多項分類を実行出来るAPIを作成する

# 目標
前回の[エントリー](http://qiita.com/fujin/items/e7007deb321a8d1c9de2)で作成した"あやめ"の分類モデルを使い、
外部から多項分類可能なAPIを作成します。

POSTデータをHTTPリクエストで送信し、JSON形式の分類データの取得を目指します。
※送信するPOSTデータの形式は以下となります。

```json
{
  "sl" : "5.7",
  "sw" : "4.4",
  "pl" : "1.5",
  "pw" : "0.4"
}
```

# 構成
外部から AWS Machine Learning 機能を使用するためには、API Gateway、Lambda を経由する必要があるため、
環境としては以下のような構成となります。

![MLAPI_img.png](https://qiita-image-store.s3.amazonaws.com/0/134550/73945742-7d7e-541f-cf0f-35c35425150c.png)

<p>
ここから各々の機能のセットアップをしていきます。

# Machine Learning
- Machine Learning にアクセスするためのロールを作成

"セキュリティ & アイデンティティ" から "Identity & Access Management" を選択

![スクリーンショット_2016-07-26_16_47_51.png](https://qiita-image-store.s3.amazonaws.com/0/134550/125a7c70-b6c5-8436-a9f7-dddd681cd596.png)

"新しいロールの作成" を選択

![スクリーンショット_2016-07-26_16_48_23.png](https://qiita-image-store.s3.amazonaws.com/0/134550/797f7f11-43ba-6d61-62cf-af8ce1f06934.png)

任意のロール名を入力（ここでは"MachineLearningIrisRole"を入力）

![スクリーンショット_2016-07-26_16_52_58.png](https://qiita-image-store.s3.amazonaws.com/0/134550/f48d3cec-65e6-3003-55ad-b7c5a5aa6dfd.png)

"AWS Lambda" を選択

![スクリーンショット_2016-07-26_16_53_08.png](https://qiita-image-store.s3.amazonaws.com/0/134550/8139b431-6043-70da-f2d2-66f51fc827f2.png)

探しやすくするため "MachineLearning" でフィルターをかけ、
"AmazonMachineLearningRealTimePredictionOnlyAccess" にチェックを入れて次へ

![スクリーンショット_2016-07-26_16_57_44.png](https://qiita-image-store.s3.amazonaws.com/0/134550/6c3da881-eb7f-01ba-950a-046d2cdabfca.png)

内容を確認して、"ロールの作成" を選択

![スクリーンショット_2016-07-26_16_57_52.png](https://qiita-image-store.s3.amazonaws.com/0/134550/7f15d20b-25de-d99a-336f-1892103f3a27.png)

- ML model を設定

前回のエントリで作成した モデルを選択

![スクリーンショット_2016-07-26_17_03_51.png](https://qiita-image-store.s3.amazonaws.com/0/134550/abbaa54a-b295-f72b-3f8e-b23a8da6a767.png)


Summary から "Create endpoint" を選択
※エンドポイント生成後に表示されるエンドポイントのURLとこのモデルIDを控えておきます。

![スクリーンショット_2016-07-26_17_04_20.png](https://qiita-image-store.s3.amazonaws.com/0/134550/c54073c7-8d21-0002-7150-15be1c4f236d.png)

# Lambda

"コンピューティング" から "Lambda" を選択します

![スクリーンショット_2016-07-26_17_06_48.png](https://qiita-image-store.s3.amazonaws.com/0/134550/b9e25b72-0330-5139-625a-bb377e6e4c0c.png)

"Create a Lambda function" を選択

![スクリーンショット_2016-07-27_11_24_49.png](https://qiita-image-store.s3.amazonaws.com/0/134550/911bd41a-abe9-8f96-3c4d-72651161fcdc.png)

"node-exec" を選択

![スクリーンショット_2016-07-27_11_25_00.png](https://qiita-image-store.s3.amazonaws.com/0/134550/28803c86-2192-95b3-7a16-5b430626770f.png)

"Next" を選択

![スクリーンショット_2016-07-27_11_25_06.png](https://qiita-image-store.s3.amazonaws.com/0/134550/71b9b5c5-c8f7-3ab5-d6b9-70f525242c79.png)

Name: 任意の関数名を入力（ここでは"IrisCheck" と入力）
Description: 任意
Runtime : "Node.js 4.3" を指定

![スクリーンショット_2016-07-27_11_35_53.png](https://qiita-image-store.s3.amazonaws.com/0/134550/0574e1d5-ae00-2034-3487-0839f811b21a.png)

以下のコードを入力
※[使用するモデルID][使用する予測エンドポイント]には、先ほど控えた内容を入力

```js
'use strict';
console.log('Loading event');

exports.handler = function(event, context) {
    
    // 入力パラメータログ出力
    console.log("sl = " + event.sl);
    console.log("sw = " + event.sw);  
    console.log("pl = " + event.pl);
    console.log("pw = " + event.pw);
    
    // AWS
    var aws = require('aws-sdk');
    aws.config.region = 'us-east-1';
 
    // MachineLearning
    var ml = new aws.MachineLearning();
 
    // パラメータ設定
    var params = {
        MLModelId: '[使用するモデルID]', 
        PredictEndpoint: '[使用する予測エンドポイント]', 
        Record: {
            "Sepal_length" : event.sl,
            "Sepal_width"  : event.sw,
            "Petal_length" : event.pl,
            "Petal_width"  : event.pw
        }
    };

    // 予測実行
    ml.predict(params, function(err, data) {
        if (err) {
            context.fail(err.stack);
        } else {
            context.succeed(data);
        }
    });
    
};
```

Existing role : 先ほど作成したロールを指定（ここでは"MachineLearningIrisRole"を指定）
Timeout : 20秒 を指定（デフォルト値(3秒)だとタイムアウトエラーが発生するため）

"Next" を選択

![スクリーンショット_2016-07-27_11_35_56.png](https://qiita-image-store.s3.amazonaws.com/0/134550/4b87a975-5c37-512a-2ea4-1f2663b0c4e6.png)

内容を確認して "Create function" を選択

![スクリーンショット_2016-07-27_11_36_01.png](https://qiita-image-store.s3.amazonaws.com/0/134550/5b76d37a-c9c6-448e-0339-9e811e85f9db.png)

## 作成した Lambda function をテストする

"Action" から "Configure test event" を選択 

![スクリーンショット_2016-07-27_11_38_29.png](https://qiita-image-store.s3.amazonaws.com/0/134550/14a2a404-d7be-2e09-e465-0b7b604dd331.png)

テストデータを入力し、"Save and test" を選択

![スクリーンショット_2016-07-27_11_38_35.png](https://qiita-image-store.s3.amazonaws.com/0/134550/0bb5c1fe-5ef9-9b72-ed80-c20fc40ab46a.png)

結果を確認し、正しく分類されている事を確認

![スクリーンショット_2016-07-27_11_36_32.png](https://qiita-image-store.s3.amazonaws.com/0/134550/fca5e6f8-a5ce-cdc6-33a3-d5d1d3b1ea8d.png)

# API Gateway

"アプリケーションサービス" から "API Gateway" を選択

![スクリーンショット_2016-07-26_17_21_42.png](https://qiita-image-store.s3.amazonaws.com/0/134550/0eebb6b5-a35e-8d19-be08-967a4539f755.png)

"APIの作成"を選択

![スクリーンショット_2016-07-27_11_40_59.png](https://qiita-image-store.s3.amazonaws.com/0/134550/84698767-d69f-3792-041d-e1dba9bc1359.png)

"新しいAPI"を選択し、以下内容を入力して"APIの作成"を選択
API名 : 任意のAPI名を入力（ここでは"IrisAPI"を入力）
説明 : 任意

![スクリーンショット_2016-07-27_11_41_27.png](https://qiita-image-store.s3.amazonaws.com/0/134550/96aab78a-b0ef-dda2-17ed-cd48fc121223.png)

"/" を選択した状態で、アクションから "メソッドの作成" を選択

![スクリーンショット_2016-07-27_11_41_42.png](https://qiita-image-store.s3.amazonaws.com/0/134550/e005b35c-dbe1-e8ad-7a8f-8830f377e9e0.png)

"POST"を選択後、チェックマークアイコンをクリック

![スクリーンショット_2016-07-27_11_41_54.png](https://qiita-image-store.s3.amazonaws.com/0/134550/b1e3045b-fb4a-e0b4-03ab-5d1de8a15a1f.png)

統合タイプ : Lambda関数
Lambdaリージョン : 任意
Lambda関数 : 先ほど作成した関数名を入力（ここでは"IrisCheck"を入力）

"保存"を選択

![スクリーンショット_2016-07-27_11_42_13.png](https://qiita-image-store.s3.amazonaws.com/0/134550/a68b27df-33cd-6046-a10c-3eaf6d2e6cc1.png)

"OK" を選択

![スクリーンショット_2016-07-27_11_42_22.png](https://qiita-image-store.s3.amazonaws.com/0/134550/3311cccb-6cfc-18d6-e32d-71f19b8ee2a5.png)

## 作成した API をテストする

"テスト" をクリック

![スクリーンショット_2016-07-27_11_42_29.png](https://qiita-image-store.s3.amazonaws.com/0/134550/8b2c7965-288c-6e8f-a257-b785d631c521.png)

リクエスト本文に、データを入力し "テスト" を選択、
レスポンス本文に分析結果が正しく表示されている事を確認

![スクリーンショット_2016-07-27_11_42_58.png](https://qiita-image-store.s3.amazonaws.com/0/134550/a17c36c3-a402-987b-ba1c-a0438d4bd8bf.png)

## 作成した API をデプロイする

アクションから　"APIのデプロイ" を選択

![スクリーンショット_2016-07-27_11_43_15.png](https://qiita-image-store.s3.amazonaws.com/0/134550/7d3bdf91-a1ae-3a3b-a2e8-4648967bba88.png)

デプロイされるステージ : 新しいステージ
ステージ名 : 任意のステージ名（ここでは"IrisStage"と入力）
ステージの説明 : 任意
デプロイメントの説明 : 任意

"デプロイ" を選択

![スクリーンショット_2016-07-27_11_44_12.png](https://qiita-image-store.s3.amazonaws.com/0/134550/2c8016b2-2845-32cc-f17d-1005e52bf6de.png)

外部からAPIの実行テストをするためステージから "POST"を選択した際に表示される URLをコピーしておきます。

![スクリーンショット_2016-07-27_11_44_24.png](https://qiita-image-store.s3.amazonaws.com/0/134550/6a6e400c-947d-b802-8ba5-7bc28d7bdcc8.png)

# 外部から作成した API をテストする

今回は Chromeブラウザで "DHC REST Client" という Webアプリを使って試験を行いました。
先ほどコピーしたURLを入力し、POSTを選択、予測したいデータを入力し "Send"を選択します。
レスポンスに分類結果がJSON形式で取得出来ました。

![スクリーンショット_2016-07-27_11_45_14.png](https://qiita-image-store.s3.amazonaws.com/0/134550/0d9fedee-dd35-ed29-6ff6-0fdd668cd91c.png)

<p>
以上、今回は外部から多項分類を実行出来るAPIの作成を行ってみました。
<p>