Watson Studio AutoAIで作ったモデルをAPI使ってNode-REDで遊ぶ話

この記事は [IBM Cloud Advent Calendar 2020](https://qiita.com/advent-calendar/2020/ibmcloud) 24日目の記事です。IBM様とCall for Codeの縁で医療 x AI の記事としました。

#概要
この記事は、Watson Studioの「[AutoAI](https://www.ibm.com/jp-ja/cloud/watson-studio/autoai)」を使って作成した機械学習モデルを、Watson Machine Learning 環境に配置し、Node-REDから接続、機械学習モデルによる予測をNode-REDで確認するものです。ライトプランを前提にしておりますので、Watson Machine Learning v2環境になります。

## AutoAIの学習(訓練)に使用したデータ

- [Kaggle : Pima Indians Diabetes Database](https://www.kaggle.com/uciml/pima-indians-diabetes-database)

糖尿病に関するデータです。あくまで例の１つであり、皆様がお持ちのデータをWatson Studio Auto AIに投入してお楽しみください。

##AutoAIで上記データを実行した結果
CSVファイルをデータソースとして投入し、予測内容として「Outcome」を選び、学習(訓練)を実施します。上記データにおける「Outcome」列は病気であるかどうかを、0と1で表現しています。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/41414/e41d8b1b-60d0-9558-9675-c89c2aa1af28.png)
後は自動で「勾配ブースティング」などを使った機械学習モデルを作成することができます。Watson StudioのAutoAIは無料プランでも使えます。今回使用したデータは、5分程度の学習(訓練)時間でモデルを作成することが出来ました。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/41414/413cccfb-222d-5ed8-3265-1ff70946da29.png)

AutoAIを使うことで、データをきちんと準備さえできていれば、マウスの左ボタンを数回押していくだけで機械学習モデル作成が出来ます。機械学習モデル作成に多くの時間を割くことなく、アプリケーション開発に貴重な時間とコストを集中させることができます。
しかし、インターネット接続が許可されていない組込み機器やエッジ環境に機械学習モデルを用いる場合は、今までのように手動で機械学習モデルを作成する必要があります。 インターネット接続が可能であれば、組込み機器やエッジ環境であっても、AutoAIは選択肢の１つになるでしょう。

# 実施内容
## 今回作るもの
Watson Studio AutoAIで作った機械学習モデルを、Watson Machine Learningに配置し、Node-REDからAPI接続します。病院等での検査結果をNode-REDから送り、機械学習モデルによる予測結果を返す仕組みを作ります。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/41414/54dd4f17-6eaa-3d00-66ee-b9716684499c.png)

Node-REDでは、JSON形式のデータを取り扱います。医療情報のデータ連携の国際規格「HL7」のうち、「FHIR」では、「JSON」及び「XML」形式のデータを扱うため、Node-REDとの相性が非常に良いです。

## 前提
Watson StudioとWatson Machine Learning は、リージョンを「ダラス」に指定し、サービスを作成しているものとします。

Watson Studioの「Auto AI」を使って、前述のKaggleの「Pima Indians Diabetes Database」のデータについて学習を済ませ、Watson Machine Learning環境に、「デプロイメント・タイプ」を「オンライン」として配置し、「APIリファレンス」と「テスト」のタブが表示されたところからから始まります。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/41414/604195cc-e2c9-d613-ff91-9bda5d785ba7.png)

「コード・スニペット」に表示された「cURL」サンプルをアレンジし、Node-REDに組込みます。

## IBM Cloud API キーの作成
IBM Cloudにログイン後、「アクセス(IAM)」で「APIキー」を発行します。URLであれば、https://cloud.ibm.com/iam/apikeys にアクセスすることで直通です。
「IBM Cloud API キーの作成」をクリックし、APIキーを作成します。作成したAPIキーは、別の場所に保管しておきましょう。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/41414/71b5fbf8-5242-0b70-2ac6-c606a473e37c.png)

### IBM Cloud CLIを使用してAPIキーを作成する場合
コマンドプロンプトやターミナルなどの場合は、IBM Cloud CLIをインストールし、下記コマンドを実行してください。

```
ibmcloud login
```
実行後、IBM Cloudにログインする際に使用しているメールアドレスとパスワードを求められるのでそれぞれ入力。

```
ibmcloud iam api-key-create apikey4watsonml
```
apikey4watsonmlという名前のAPIキーを作成。名前は英数字であれば何でもOK。実行後、APIキーが表示されるので、メモ帳などにコピーしておく。

## IBM Cloud Shellにて、機械学習モデルを配置したWatson Machine Learning環境に接続するためのアクセストークンを発行
IBM Cloud Shellを開きます。IBM Cloudにログインと、画面右上に、IBM Cloud シェルにアクセスするためのアイコンが表示されています。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/41414/59fef067-b840-1260-60a8-05207141da5e.png)

先ほどの「コード・スニペット」に表示された「cURL」サンプルのうち、1つ目を使用し、アクセストークンを取得します。
1つ目のサンプルに記載されいてる、$API_KEY を、発行したばかりのAPIキー書き換えて、IBM Cloud シェルで実行することで、アクセストークンが発行されます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/41414/c85d43f2-0a84-ebc8-6394-9b5e805cc8c4.png)
作成したIBM Cloud APIキーが、xxxxxxxxxxxxxxxとした場合の例

```
curl --insecure -X POST --header "Content-Type: application/x-www-form-urlencoded" --header "Accept: application/json" --data-urlencode "grant_type=urn:ibm:params:oauth:grant-type:apikey" --data-urlencode "apikey=xxxxxxxxxxxxxxx" "https://iam.ng.bluemix.net/identity/token"
```

上記は例えですので、実際の使用する場合は、xxxxxxxxxxxxxxx の部分を、あなたが作成したIBM Cloud API キーに置き換えてください。

## アクセストークン
発行されたアクセストークンは、{"access_token": から始まり、,"refresh_token"までの範囲でダブルクォーテーションで囲まれた文字列です。1000文字近くあります。IBM Cloud Shell に表示されますので、表示された内容をメモ帳等にコピー&貼り付けした後に、取り出します。

## Node-RED環境の準備
「[2020年4月 Node-REDハンズオン (Node-RED環境の準備)](https://qiita.com/kolinz/items/e331a71d2c68ff14fbda)」を参考に、IBM Cloud ライト・アカウントでNode-RED環境を構築します。

## Node-REDに実装
先ほどの「コード・スニペット」に表示された「cURL」サンプルのうち、2つ目のサンプルをNode-RED向けにアレンジします。
アレンジしたものが、こちらのNode-RED向けサンプルコードになります。

```
[{"id":"d64a01f.b1fdd","type":"tab","label":"Watom ML 予測","disabled":false,"info":""},{"id":"452fe777.f52af8","type":"inject","z":"d64a01f.b1fdd","name":"","props":[{"p":"payload"},{"p":"topic","vt":"str"}],"repeat":"","crontab":"","once":false,"onceDelay":0.1,"topic":"","payload":"{\"input_data\":[{\"fields\":[\"Pregnancies\",\"Glucose\",\"BloodPressure\",\"SkinThickness\",\"Insulin\",\"BMI\",\"DiabetesPedigreeFunction\",\"Age\"],\"values\":[[1,119,44,47,63,35.5,0.28,25]]}]}","payloadType":"json","x":130,"y":40,"wires":[["210386ea.f8e28a","77a7a23.090fe5c"]]},{"id":"210386ea.f8e28a","type":"debug","z":"d64a01f.b1fdd","name":"","active":true,"tosidebar":true,"console":false,"tostatus":false,"complete":"false","statusVal":"","statusType":"auto","x":620,"y":40,"wires":[]},{"id":"77a7a23.090fe5c","type":"function","z":"d64a01f.b1fdd","name":"Create POST","func":"msg.headers = {\"Content-Type\": \"application/json\",\"Accept\": \"application/json\",\"Authorization\": \"Bearer eyJraWQiOiIyMDIwMTFw\"};\nmsg.payload = msg.payload;\nreturn msg","outputs":1,"noerr":0,"initialize":"","finalize":"","x":190,"y":140,"wires":[["3bccd55f.e654fa"]]},{"id":"7c2897d0.fac218","type":"debug","z":"d64a01f.b1fdd","name":"","active":true,"tosidebar":true,"console":false,"tostatus":false,"complete":"true","targetType":"full","statusVal":"","statusType":"auto","x":600,"y":140,"wires":[]},{"id":"3bccd55f.e654fa","type":"http request","z":"d64a01f.b1fdd","name":"","method":"POST","ret":"txt","paytoqs":"ignore","url":"https://us-south.ml.cloud.ibm.com/ml/v4/deployments/f5be961d-8589-4dac-85c4/predictions?version=2020-12-22","tls":"","persist":false,"proxy":"","authType":"","x":420,"y":140,"wires":[["7c2897d0.fac218","310a445.edab2bc"]]},{"id":"310a445.edab2bc","type":"json","z":"d64a01f.b1fdd","name":"","property":"payload","action":"","pretty":false,"x":440,"y":220,"wires":[["43f1ed19.14e5e4"]]},{"id":"43f1ed19.14e5e4","type":"debug","z":"d64a01f.b1fdd","name":"","active":true,"tosidebar":true,"console":false,"tostatus":false,"complete":"false","statusVal":"","statusType":"auto","x":620,"y":220,"wires":[]}]
```

上記のサンプルコードをNode-REDで使用するには、Node-REDの画面右上の「三」>>「読み込み」>>「フローをクリップボードから読み込み」で、上記サンプルコードをコピー、貼り付けを行い、「読み込み」ボタンをクリックします。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/41414/00679e39-e3ff-ae4f-f635-e66864c67f3d.png)

読み込みが成功すると、下図のように表示されます。Node-REDは、「ノード」(箱状の部品)が繋がったものを「フロー」と言います。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/41414/2472e583-615f-35a9-9599-216b0d13cfc8.png)

### 各ノードの解説
#### injectノード
以下のノード(箱状のもの)をダブルクリックすることで、編集画面が表示されます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/41414/ef433cdb-4874-1b26-e329-264db7c88e79.png)
injectノードを用いて、JSON形式の病気等の検査結果データを、次のfunctionノードに渡しています。使用するJSON形式のデータは、Watson Machine Learning v2環境に、「デプロイメント・タイプ」を「オンライン」として配置したモデルの「テスト」で確認できるJSONデータに準じます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/41414/b7bcf0a4-bd04-5655-ea8a-5d7b119acdc6.png)

例を以下に記しますので、Node-RED上での動作確認にお使いください。検査結果に関するデータ構成になっています。

```
{"input_data":[{"fields":["Pregnancies","Glucose","BloodPressure","SkinThickness","Insulin","BMI","DiabetesPedigreeFunction","Age"],"values":[[2,197,70,99,0,34.7,0.575,62]]}]}
```
#### functionノード
以下のノード(箱状のもの)をダブルクリックすることで、編集画面が表示されます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/41414/2a49c740-a8dc-9c5b-60cb-56dff5dcf78e.png)

functionノードを用いて、injectノードからJSON形式の検査データを受け取り、Watson Machine Learning環境に送信するためのデータを作成します。次のhttprequestノードにデータを渡します。

Bearerの後の「eyJraWQiOiIyMDIwMTFw」の部分を、アクセストークンの文字列に置き換えてください。Bearerの後に半角スペースが入り、その後にアクセストークンを記述し、ダブルクォーテーションで囲みます。

「msg.payload」で、injectノードから渡された検査結果のJSONデータを受け取ります。

#### httprequestノード
以下のノード(箱状のもの)をダブルクリックすることで、編集画面が表示されます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/41414/bbf99d2b-abce-7925-3fca-a7edd07eabc4.png)
functionノードから受け取ったデータを、httprequestノードで指定した、URLに送信します。送信先のURLは、Watson Machine Learning環境に、「デプロイメント・タイプ」を「オンライン」としてモデルを配置した際に、「コード・スニペット」に表示された、「cURL」のサンプルに記載されていた、https://us-south.ml.cloud.ibm.com/ml/v4/deployments で始まるURLです。このURLににアクセスしてもAPIのためのURLなので、Webサイト等は表示されません。

#### JSONノード
httprequestノードに渡されたfunctionノードのデータに対する機械学習モデルのAPIからのレスポンスのうち、予測結果だけを取り出して、JSON形式のデータとして表示します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/41414/1279f475-5da0-5136-e4bc-e8370135c013.png)

#### debug ノード
フローのうち、オレンジの枠部分が、Debugノードの使用箇所です。接続先のノードで出力された結果を、表示します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/41414/faca1201-4399-d02e-10d7-f425d55effd8.png)
Node-REDのサイドバーのうち、下図の「虫」型のアイコンをクリックすることで表示される「デバッグ」に、各ノードから受け取ったデータを表示するために使用します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/41414/2516f61d-6b5a-13e1-e87f-afd0f401f8a6.png)

### 動作確認
画面右上の「デプロイ」(黄色枠部分)をクリックします。その後、injectノードのボタン(オレンジ枠部分)をクリックします。injectノードに記載した検査結果のJSONデータが送信され、Watson Machine Learning環境に配置し、APIとして使用可能になったモデルから、病気の予測結果がレスポンスとしてJSON形式で届き、Debugノードで受信、表示されます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/41414/2fe793cb-0b0f-0b8f-1ff5-88187513223b.png)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/41414/4852f9e5-0546-d5d3-acb0-0f098c1cabf5.png)
この動きさえ確認できれば、injectノードの代わりに、httpノードとfunctionノードを組み合わせ、Webhookで他のシステムからデータを受け取る仕組みを追加することで、受け取ったデータを機械学習モデルを使って、予測を行い、予測結果を別のシステムに送ることができます。データ処理は、Node-REDが得意分野です。

# 使用したクラウドサービス
## IBM Cloud ライト・アカウント
クレジットカード登録なしで無料で使用できるIBM Cloudの契約です。この記事の内容は、IBM Cloud ライト・アカウントの範囲で実現することができます。

### IBM Cloud Shell
Webブラウザから使用できるシェル環境(コマンドを使って操作する場所)です。

### Watson Studio
IBM Cloud ライト・アカウントで使用可能な、拡張知能(Augmented intelligence、略してAI)を開発をすることができます。IBM Cloud ライト・アカウントで使用可能です。無料枠で使用する場合は利用制限があります。試す分には、無料で良いでしょう。

#### AutoAI
Watson Studioの機能の１つで、CSVファイル等の機械学習向けデータをアップロードし、数回のクリックで機械学習モデルを自動作成することができます。たとえば、今回使用したKaggleのデータは、5分程度で学習(訓練)が完了しました。

### Watson Machine Learning
AutoAIで作成したモデルを配置し、インターネット経由で利用可能にしています。
Watson Studioで同じく、無料枠で使用する場合は利用制限があります。試す分には、無料で良いでしょう。

### Node-RED 
ローコード開発および本番環境です。PCから所有するサーバー、クラウドサービス、Raspberry Piなど、ほとんどどこでも導入できます。IoTの世界では、著名企業で多数採用されている実績豊富なツールでもあります。
IBM Cloud ライト・アカウントでも使用することができます。

操作については、Node-RED User Group Japanの[ドキュメント](https://nodered.jp/docs/user-guide/editor/)をご確認ください。
https://nodered.jp/docs/user-guide/editor/

Node-REDは、IoTやAIと、業務システムを繋げることができるため、この記事では、病院での検査結果を、Watson Studio AutoAIを使って作った拡張知能(AI)にNode-REDを介して渡すことで、病気の可能性があることを予測する仕組みを想定しています。拡張知能により、医師や看護士の行動を助けたり、予防医療が重要になっている昨今では、患者である私達自身の健康管理を支える仕組みとしての活躍が考えられます。

#連絡先
https://kolinz.github.io/