【新機能】AWS IoT のRules EngineがAmazon machine Learningをサポート。IoTと機械学習が一体に

2016.04.12

こんにちは、せーのです。今日はAWS IoTの新機能をご紹介します。 ここ数年でのバズワードでもある「IoT」「機械学習」、この2つがシームレスにつながる、という夢が広がる機能です!

Amazon MLによる予測を自動化

Amazon Machine Learning(Amazon ML)はAmazonの独自アルゴリズムを使用して簡単に機械学習と予測が出来るようになるサービスです。教師となるデータを元にAWSが与えられた値を分析し、予測値をはじき出します。現在のAmazon MLからは例えば「このメールはSPAMかどうか」「この商品は肉か魚か」「今期の売上の着地予想は」等が簡単に予測できます。 Amazon MLの詳しい説明はこちらを御覧ください。
今回の新機能によりデバイスから自動で吸い上げたデータをそのままAmazon MLに投げ、予測値を計算した上でその値を別なTopicにrepublishして別な計算をさせたり、S3にデータとして蓄積させたり出来るようになります。

どうやるの

具体的にAWS IoTとAmazon MLはどのように繋がるのでしょう。これはRules ActionとしてAmazon MLが選択できるのではなく、[machinelearning_predict()]というSQL functionの値としてAmazon MLが使えるようになっています。COUNT()やSUM()と同じ分類ですね。つまり、machinelearning_predictをRuleのSelectやWhereに書くことによって入ってきたデータに対して指定したAmazon MLのモデルを元に機械学習にて分析し、返ってくる戻り値をデータと共にActionで新たな処理を行う、という流れになります。

aws_iot_ml

このmachinelearning_predictの引数と戻り値は次のようになります。

machinelearning_predict(modelId, roleArn, record)

引数

名前 内容
modelId ModelのIDを指定(リアルタイムエンドポイントは必ずEnabledにすること)
roleArn machinelearning:Predictとmachinelearning:GetMLModelを許可したIAM RoleのARNを指定
record 検証するデータを指定

※recordに指定するのはSingle JSON Object方式。入れ子になっているようなJSONはAWS側で自動的にフラット化される。

{ "key1": {"innerKey1": "value1"}, "key2": 0}

これは

{ "key1": "{\"innerKey1\": \"value1\"}", "key2": 0}

こうなる

戻り値

戻り値はJSONの形で返ってきます。

名前 内容
predictedLabel 分類結果。カテゴリ型式(肉か魚か、的な)のモデルにデータを投げるとここに予測値が返ってくる
details - PredictiveModelType モデルのタイプREGRESSION(数値予測), BINARY(二項分類), MULTICLASS(多項分類)の3種類。
details - Algorithm 使用したアルゴリズム型式。Amazon MLは確率的勾配降下法(SGD:Stochastic Gradient Descent)を使うので"SGD"と入る
predictedScores 予測の"確からしさ"が入る。例えば"1": 0.6だと6割の確率で1だろう、という意味
predictedValue 数値結果。数値予測のモデルにデータを投げるとここに予測値が返ってくる

やってみた

ではやってみましょう。今回はAWSがサンプルとして提供しているbanker.csvというデータをモデル作成に使います。このデータはカリフォルニア大学アーバイン校が公開しているポルトガルの定期預金のキャンペーンのデータです。年齢や職業、婚姻やキャンペーンの時期などが入っており、最後の"y"のところに定期預金の契約をしたかどうか(したら1、しなかったら0)が入っています。Amazon MLのセットアップ部分の詳細はこちらを参考にしてみてください。でははじめていきましょう。

Amazon MLを構築する

まずはAmazon MLを作っていきます。Amazon MLは現在東京リージョンには来ていないので北米リージョンで試します。

aws-iot-ml1

banking.csvをS3のバケットにアップロードし、そのパスを指定します。そしてデータソース名を入力します(ここは好きな名前を入れて下さい)。Schemaはデフォルトのままいきます。

aws-iot-ml2

Targetを決めます。今回は「定期預金に契約したかどうか」をTargetとするので、一番最後の「y」という項目を指定します。特にID的なものは無さそうなのでRecord IDはなしにします。

aws-iot-ml3

こんな感じになります。Continueを押すとモデルの設定となります。

aws-iot-ml4

モデルのtypeがBINARY(二項分類)になっているのを確認して次に進みます。データを分析する間20分ほどコーヒーを飲みます。

aws-iot-ml5

ただポチポチ押してただけですが、あっという間に構築が完了しました。最後にエンドポイントを作成するため[ML model]の[ID]をクリックします。

aws-iot-ml6

モデル設定画面の下の方に[Create a real-time endpoint]というのがありますので、これを作成します。これでAmazon ML側は完成です。モデルのIDを使うのでコピーしておいて下さい。

IAM Roleを作成

次にIAM Roleを作ります。これは後にRulesでmachinelearning_predict()を指定する時に使うロールですね。必要な権限はmachinelearning:Predictとmachinelearning:GetMLModelなのですが、管理ポリシーにいい感じのものがなかったのでインラインポリシーとして自分で作りました。

aws-iot-ml11

aws-iot-ml12

AWS IoT Rules engineを作成する

最後にAWS IoT部分です。上で作ったAmazon MLを入れ込んだRuleを作ります。

aws-iot-ml13

Nameは適当に入れて下さい。Attributeの所に今回は生データとAmazon MLにかけた結果を入れるようにセットします。

* as data, machinelearning_predict('ml-VTGJWF05Er4',  'arn:aws:iam::123456789012:role/aws-iot-aml', *) as aml

fromのTopic名も自由に決めてOKです。

aws-iot-ml14

ActionとしてS3にデータを入れるようにします。バケットを作成し、AWS IoTからS3へのPutObjectを許可したIAM Roleを作成して設定します。keyのところは自由です。

出来上がったRuleがこちらです。

aws-iot-ml19

以上で構築は完了です。

テストする

さて、それではいよいよテストしてみましょう。AWS IoTのコンソール画面右上の[MQTT Client]からMQTTのテスト画面を出し、Device Gatewayに接続します。Client IDは[Generate client ID]ボタンで自動につけましょう。

aws-iot-ml16

Device Gatewayにつながったら先程設定したTopic[test/awsiotaml]に向けてデータを飛ばしてみます。[Publish to topic]タブを開いて、Topic名とデータを入力します。

aws-iot-ml17

aws-iot-ml18

{
  "age": 28,
  "job": "management",
  "marital": "single",
  "education": "university.degree",
  "default": "no",
  "housing": "yes",
  "loan": "no",
  "contact": "cellular",
  "month": "jun",
  "day_of_week": "thu",
  "duration": 339,
  "campaign": 3,
  "pdays": 6,
  "previous": 2,
  "poutcome": "success",
  "emp_var_rate": -1.7,
  "cons_price_idx": 94.055,
  "cons_conf_idx": -39.8,
  "euribor3m": 0.729,
  "nr_employed": 4991.6
}

データは単純に先程教師データとしてAmazon MLにセットしたbanker.csvから一行引っこ抜いてきてJSON型式に直しただけです。ちなみにこの行は最後の"y"が1、つまり契約した人のデータなので、うまくいけばAmazon MLは「この感じのデータの人なら契約するはずだ」と予測値を返すはずです。ではPublishしてみましょう。

PublishしたらS3のバケットを覗いてみます。

aws-iot-ml20

データが返ってきました。中身を見てみます。

{"data":
  {"nr_employed":4991.6,
  "euribor3m":0.729,
  "cons_conf_idx":-39.8,
  "cons_price_idx":94.055,
  "emp_var_rate":-1.7,
  "poutcome":"success",
  "previous":2,
  "pdays":6,
  "campaign":3,
  "duration":339,
  "day_of_week":"thu",
  "month":"jun",
  "contact":"cellular",
  "loan":"no",
  "housing":"yes",
  "default":"no",
  "education":"university.degree",
  "marital":"single",
  "job":"management",
  "age":28
  },
  "aml":{
  "predictedLabel":"1",
  "predictedValue":null,
  "predictedScores":
    {"1":0.8334648013114929},
  "details":
    {"Algorithm":"SGD",
    "PredictiveModelType":"BINARY"}
  }
}

predictedLabelが1を返しています。predictedScoresが0.83なので、これはつまり「この人は83%くらいの確率で契約します」とAmazon MLは予測した、ということです。テスト成功です!

まとめ

いかがでしたでしょうか。ちなみにAmazon MLに投げるデータは全ての項目が埋まっている必要はありません。ageとjob, educationだけ埋めて投げてみる等、色々な型式で試してみてください。
これでIoTデータに予測値を自動で付加することが出来るようになりました。更にこれをAmazon ESに投げてグラフ化したり、Lambdaに投げて別の処理を施す等、ビジネスの幅が一気に広がりそうです。是非試してみて下さい。

参考サイト