LoginSignup
4
2

More than 3 years have passed since last update.

Watson MLのWebサービスをNode-REDから呼び出す(v2対応済み)

Last updated at Posted at 2021-01-15

はじめに

Node-REDから、Watson ML上にdeployしたWebサービスを呼び出す方法としては

に部品があるのですが、コードを調べてみたところ古いインターフェースのままで、バージョンアップも止まっていました。
(というか、API仕様が根本的に変わったので 、ML v2対応しようとすると全部作り直しになりそう)

ということで、昨年9月にリリースした新しいWatson ML API仕様v2に対応するにはどうしたらいいか、考えてみました。
頑張って全部JavaScriptで実装して、新しいNode-REDの部品も作れなくないはずですが、しばらくJavaScriptから離れているため、コールバック先の関数から値を戻すのをどうしたらいいか思い出せず。。。
あまりきれいでないのですが、ひな形のフローファイルを作ってお茶を濁すことにしました。

完成イメージ

下の図が、完成イメージです。

screen-01.png

呼び出し先の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呼び出し」
の二つのノードです。

screen-02.png

「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呼び出し」の設定ノードです。

screen-03.png

この中でURLの欄に、事前に調べたscring_urlの値を貼り付けます。

テスト

これで準備はすべて整いました。正しく設定ができていれば、一番左のinjectノードのクリックで、Watson MLのAPIが呼び出せるはずです。

フロー解説

最後に、フローの各ノードで何をやっているか解説します。

screen-02.png

基本的には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にしています。

screen-04.png

それ以外のパラメータはその前のノードで設定済みなので、これだけで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の戻り値の解説をします。
リクエストの戻りをパースすると、次のような結果になります。

screen-05.png

戻り値は、赤枠で示した予測値(prediction)と青枠で示した確率値(probability)に分けられます。
このモデルの目的は、アヤメの花の種類(0か1か2)を区別することなのでが、モデルの予測結果としての種類がpredictionの値です。
もう一つのprobabilityとは、それぞれの判断結果に対する確信度だと思って下さい。
今回の2件の予測結果に関して言うと、「1件目の予測結果が2である」ことは100%自信があるが、「2件目の予測結果が0である」ことに対しては、確信度が99%で、多少自信がないということになります。

4
2
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
4
2