Amazon Machine Learning + AWS Lambda + API Gateway でリアルタイム予測APIを構築する

この記事は公開されてから1年以上経過しています。情報が古い可能性がありますので、ご注意ください。

Amazon MLはリアルタイム予測APIを機能として提供しており、モデルを構築した後は簡単に予測結果を都度問い合わせることができます。

ですがAmazon MLの予測APIを直接叩くためには、モデルのIDやIAM Roleの認証情報が必要なため、クライアントにAccess Keyを渡すことや、モデルを更新するごとにIDを書き換えることを考えると、そのままでは使いづらい面もあります。

そこで、今回はAmazon ML + AWS Lambda + API Gatewayを組み合わせて公開用の予測APIを構築してみました。

構成図

構成は、このような形になります。

Untitled

API GatewayはAPIの提供と鍵認証の管理をし、Lambdaを通してAmazon MLに予測の問い合わせを行います。

Lambdaを中間に挟むことで、Amazon MLのモデルが更新された場合や、予測に複数のモデルを用意し、入力されたデータによって切り替えたい場合などに柔軟に対応することができるようになります。

roleの作成

まずは、LambdaからAmazon MLにアクセスするためのIAM Roleを作成します。

マネジメントコンソールからIAMの管理ページに移り、以下の手順でRoleを作成します。

  1. 「Set Role Name」からRole名を入力
  2. 「Select Role Type」から「AWS Lambda」を選択
  3. 「Attach Policy」から 「AmazonMachineLearningRealTimePredictionOnlyAccess」を選択
  4. 確認して「Create Role」からRoleを作成

realtime endpoint の公開

次に、Amazon MLの管理画面に移り、対象となるモデルのエンドポイントを作成します。

  1. 対象のモデルの詳細画面に移る
  2. 「Create real-time endpoint」を選択してエンドポイントを作成する。

create_realtime_endpoint

この時に表示されるendpoint urlmodel-idはlambdaから予測APIに問い合わせする際に必要となるので、控えておきます。

endpoint_url

AWS Lambda Functionの作成

これでLambdaからAmazon MLにアクセスするための準備ができたので、Lambda Functionを実装していきます。

今回はひとまずlambdaに渡されたデータをそのままモデルに渡し、結果を返すだけの関数をjavascriptで実装しました。

exports.handler = function(event, context) {
    var aws = require('aws-sdk');
    aws.config.region = 'us-east-1';

    var ml = new aws.MachineLearning();

    var params = {
        MLModelId: 'ml-xxxxxxxx', 
        PredictEndpoint: 'https://realtime.machinelearning.us-east-1.amazonaws.com', 
        Record: event
    };

    ml.predict(params, function(err,data){
        if (err) context.fail(err.stack);
        else {
            context.succeed(data['Prediction']);
        }
    });
};

モデルの更新や変更を行いたい場合は、ここに書かれたモデルのIDやエンドポイントを更新すれば対応できます。

lambdaに渡されるイベントに以下のような形式で予測用のデータを渡し、予測結果が返ってくることを確認します。

{
  "var1" : "1.2",
  "var2" : "3.4",
  "var3" : "5.6",
  "var4" : "7.8"
}
{
  "details": {
    "Algorithm": "SGD",
    "PredictiveModelType": "MULTICLASS"
  },
  "predictedLabel": "Iris-versicolor",
  "predictedScores": {
    "Iris-setosa": 0.3780616819858551,
    "Iris-versicolor": 0.5742364525794983,
    "Iris-virginica": 0.047701895236968994
  }
}

APIをつくる

最後に作成したLambda Functionを API Gatewayにつなげて、公開用の予測APIを作成します。

  1. APIを作成する
  2. 「Create Resource」からResourceを作成し、「Create Method」からPOST Methodを作成
  3. Integration Type に 「Lambda Function」を選択し、作成したLambda Functionを指定
  4. 「Save」を選択してMethodを作成
  5. 「Deploy API」を選択し、デプロイ先のstageを設定して公開

これで、予測用のAPIが公開されました。画面に表示されているURLから予測APIから試してみます。

$ curl -X -d "{\"Var1\":\"1.2\",...}" \
  https://xxxxxxxxx.execute-api.us-east-1.amazonaws.com/test/predict 

{"details":{"Algorithm":"SGD","PredictiveModelType":"MULTICLASS"},"predictedLabel": ...

APIの接続を制限したければ、API GatewayからAPI Keyを作成し、鍵認証を設定することができます

まとめ

API GatewayとLambdaを組み合わせることで、非常に簡単に予測APIを外部に公開することができます。

これからも作成した予測モデルを公開する場合なんかは、この二つのサービスにはお世話になりそうですねー。

参考資料

Amazon API GatewayでAPIキー認証を設定する