はじめに
Node-REDから、Watson ML上にdeployしたWebサービスを呼び出す方法としては
に部品があるのですが、コードを調べてみたところ古いインターフェースのままで、バージョンアップも止まっていました。
(というか、API仕様が根本的に変わったので 、ML v2対応しようとすると全部作り直しになりそう)
ということで、昨年9月にリリースした新しいWatson ML API仕様v2に対応するにはどうしたらいいか、考えてみました。
頑張って全部JavaScriptで実装して、新しいNode-REDの部品も作れなくないはずですが、しばらくJavaScriptから離れているため、コールバック先の関数から値を戻すのをどうしたらいいか思い出せず。。。
あまりきれいでないのですが、ひな形のフローファイルを作ってお茶を濁すことにしました。
完成イメージ
下の図が、完成イメージです。
呼び出し先のAPIは、別記事Watson Studioでscikit-learn機械学習モデルをWebサービス化するで作ったものです。
(Iris datasetを学習データにした分類モデル)
こちらに関しては、Webサービスのデプロイまで済んでいることが前提になりますので、その点はご注意下さい。
フローファイルは、以下のGithubサイトにアップしてあります。
このフローをNode-REDに取り込んで、2箇所ノードの設定(apikeyとscroring_url)を変更すると、Watson MLのAPIを呼び出せるようになります。
サンプルの動かし方
設定値の取得
API_KEYの値
1.3 API Keyの取得を参照して下さい。
scoring_urlの値
6.3 URL取得を参照して下さい。Node-REDから呼び出す場合は、バージョンIDも付加したscoring_url2
の方を使う必要があるので、その点を注意して下さい。
Node-RED上の設定
取り込んだフローの中で修正が必要なのは
① 「token取得準備」
② 「API呼び出し」
の二つのノードです。
「token取得準備」ノードの設定
下記が、該当functionノードのコードです。
// header設定
msg.headers = {};
msg.headers['Accept'] = "application/json";
msg.headers['Content-Type'] = "application/x-www-form-urlencoded";
// apikey設定
var apikey = "xxxx";
msg.payload = "apikey=" + apikey + "&grant_type=urn:ibm:params:oauth:grant-type:apikey";
return msg;
この中で、
var apikey = "xxxx";
の行に調べたAPI_KEYの値を設定します。
「API呼び出し」ノードの設定
下記が「API呼び出し」の設定ノードです。
この中でURLの欄に、事前に調べたscring_urlの値を貼り付けます。
テスト
これで準備はすべて整いました。正しく設定ができていれば、一番左のinjectノードのクリックで、Watson MLのAPIが呼び出せるはずです。
フロー解説
最後に、フローの各ノードで何をやっているか解説します。
基本的には6. 予測(Watsonライブラリを使わない方法とまったく同じことを、Node-RED上でやっているだけです。
元記事も合わせて読んでいただけると、より理解が深まると思います。
Token取得準備
コードは1章で一度載せていますが、再掲します。
// header設定
msg.headers = {};
msg.headers['Accept'] = "application/json";
msg.headers['Content-Type'] = "application/x-www-form-urlencoded";
// apikey設定
var apikey = "xxxx";
msg.payload = "apikey=" + apikey + "&grant_type=urn:ibm:params:oauth:grant-type:apikey";
return msg;
この後のHTTPリクエストノードでの準備をしています。
リクエストヘッダはmsg.headers
に、データはmsg.payload
にそれぞれ設定しています。
Token取得
http requestノードで、メソッドをPOST
に、URLをhttps://iam.cloud.ibm.com/identity/token
にしています。
それ以外のパラメータはその前のノードで設定済みなので、これだけでTokenが取得できます。
API呼び出し準備
下記が、API呼び出し準備用のfunctionノードの内容です。
// token取得
value = JSON.parse(msg.payload);
console.log(value);
console.log(value["access_token"]);
var token = value.access_token;
// header設定
msg.headers = {};
msg.headers['Content-Type'] = "application/json";
msg.headers['Authorization'] = 'Bearer ' + token;
// data設定
msg.payload = '{"input_data": [{"values": [[6.9, 3.1, 5.4, 2.1], [4.4, 2.9, 1.4, 0.2]]}]}'
return msg;
まず、token取得APIの戻り値をパースした後で、キー値access_token
に対応するvalueを取得します。
この値が、次のAPI呼び出しで必要なtokenになります。
header設定で、Bearer
の後に、今取得したtokenを追加し、これをAuthorization
の値にします。
最後のmsg.payload
は、APIの引数になる入力データ部分です。
今は、iris datasetの入力値2行分をベタうちにしてしまっていますが、実際のアプリでは、他からのデータを使ってこの部分を組み立てることになります。
戻り値の読み取り方
最後にWatson MLの戻り値の解説をします。
リクエストの戻りをパースすると、次のような結果になります。
戻り値は、赤枠で示した予測値(prediction)と青枠で示した確率値(probability)に分けられます。
このモデルの目的は、アヤメの花の種類(0か1か2)を区別することなのでが、モデルの予測結果としての種類がprediction
の値です。
もう一つのprobability
とは、それぞれの判断結果に対する確信度だと思って下さい。
今回の2件の予測結果に関して言うと、「1件目の予測結果が2である」ことは100%自信があるが、「2件目の予測結果が0である」ことに対しては、確信度が99%で、多少自信がないということになります。