Watson Machine LearningのAI Function機能を使って、SPSS Modelerの機械学習モデルをFunction定義する

# はじめに
IBM Watsonの新しいサービスAI OpenScaleは、他社クラウド上の機械学習モデルを含めて管理対象にすることのできる、本番運用中の機械学習モデルを対象としてサービスです。
しかし、対象とすることのできるサービスにはいくつか制約があります。例えばIBM Cloud上で作成した機械学習モデルであってもSPSS Modelerのものは管理対象にすることができません。そういう場合に利用できるのがWatson Machine Learingの新機能であるAI Functionです。これはPythonの関数をラッパーとして、この関数をWatson Machine Learningに登録することで、結果的にAI OpenScaleの管理対象とすることが可能です。
当記事では、Watson Studio上のSPSS Modelerで作った機械学習モデルをAI Functionに登録する手順をサンプルとして提供します。


# 前提
AI Functionはまだベータ版の段階で、今この機能を動かすためには、Watson Machine Learingのベータ版インスタンスを作成する必要があります。今なら無償で作ることができるのでチャンスです。

![スクリーンショット 2018-12-28 21.13.38.png](https://qiita-image-store.s3.amazonaws.com/0/206130/deb62db0-e919-b9f2-69a2-0709dc1c53f3.png)

SPSSの機械学習モデルは [SPSSクラウド版で簡単機械学習](https://qiita.com/makaishi2/items/85d7694168e71ee3c094)で作ったものを対象とします。

# Pythonによる機械学習モデル呼出しのコーディング
最初に行うことは、Pythonによる機械学習モデル呼出しのコーディングです。下の例は、たまたまWatson StudioのSPSS Modelerで作った機械学習モデルを呼び出すコードですが、これは他のプラットフォームでも同様に扱えるはずです。

```py3

# 認証情報
wml_credentials = {
  "apikey": "xxxxxx"
# 以下省略
}

from watson_machine_learning_client import WatsonMachineLearningAPIClient
client = WatsonMachineLearningAPIClient(wml_credentials)

# scoring url はMachine Learningの管理機能で取得したものを利用します。
spss_scoring_url = 'xxxxx'

# 呼出し時のパラメータ
spss_params = {
    "fields": ["CLASS", "AGE", "BP", "AL", "SC", "POT", "PCV"],
    "values": [[None, 75, 70, 0, 0.8, 3.5, 46]]}

# モデル呼出し
spss_scores = client.deployments.score(spss_scoring_url, spss_params)

# 結果表示
print(spss_scores)
```

この呼出し結果が次のような形であったとします。

```
{'values': [[None, 75, 70, 0, 0.8, 3.5, 46, '1_Training', 'ckd', 0.998594297142512, 0.998594297142512, 'ckd', 0.998594297142512]], 'fields': ['CLASS', 'AGE', 'BP', 'AL', 'SC', 'POT', 'PCV', 'Partition', '$L-CLASS', '$LP-CLASS', 'prediction', 'prediction_classes', 'probability']}
```

# SPSS呼出し関数の定義
ここで、次のようなコードでSPSS呼出し用の関数を定義します。
ちょっと難しい実装ですが、``score_generator``というインスタンスを生成すると、これが機械学習モデル呼出しの結果を返す関数になっていることがわかります。

```py3
ai_params = {"wml_credentials": wml_credentials, 
             "spss_scoring_url": spss_scoring_url}
def score_generator(params=ai_params):
    from watson_machine_learning_client import WatsonMachineLearningAPIClient
    wml_credentials = params["wml_credentials"]
    spss_scoring_url = params["spss_scoring_url"]
    client = WatsonMachineLearningAPIClient(wml_credentials)
    def score(payload):
        spss_scores = client.deployments.score(spss_scoring_url, payload)
        fields = spss_scores['fields']
        values = spss_scores['values']
        ret_scores = {'values': values, 'fields': fields}
        return ret_scores
    return score
```

本当にそうなっているか、下記のコードでテストしてみます。

```py3
score = score_generator()
score(spss_params)
```

下記の結果がかえってくるので、よさそうな感じです。

```
{'fields': ['CLASS',
  'AGE',
  'BP',
  'AL',
  'SC',
  'POT',
  'PCV',
  'Partition',
  '$L-CLASS',
  '$LP-CLASS',
  'prediction',
  'prediction_classes',
  'probability'],
 'values': [[None,
   75,
   70,
   0,
   0.8,
   3.5,
   46,
   '1_Training',
   'ckd',
   0.998594297142512,
   0.998594297142512,
   'ckd',
   0.998594297142512]]}
```

# Python関数のAI Functionとしての登録
ここまでくれば、AI Function化はすぐに可能です。
次のコードで、AI Functionとしての登録が行われます。

```py3
meta_data = { client.repository.FunctionMetaNames.NAME: 'SPSS Kidney AI Function v8' }
function_details = client.repository.store_function(meta_props=meta_data, function=score_generator)
```

以下のような結果がかえってくれば登録に成功しています。


```
No RUNTIME_UID passed. Creating default runtime... SUCCESS

Successfully created default runtime with uid: aab70361-3c9a-4f53-804d-411e39ee1978
```

次のコマンドで、登録結果を確認してみます。

```
print(json.dumps(function_details, indent=2))
```

うまくいっていれば次のようになります。

```
{
  "metadata": {
    "guid": "d936336d-d9a3-444f-beec-f504dbc00f94",
    "created_at": "2018-12-28T12:09:19.244Z",
    "url": "https://us-south.ml.cloud.ibm.com/v4/functions/d936336d-d9a3-444f-beec-f504dbc00f94"
  },
  "entity": {
    "type": "python",
    "runtime": {
      "url": "https://us-south.ml.cloud.ibm.com/v4/runtimes/aab70361-3c9a-4f53-804d-411e39ee1978"
    },
    "instance_id": "f7e16611-81a0-442b-95b4-9dd993ffa0e9",
    "revision_number": "1",
    "name": "SPSS Kidney AI Function v9",
    "region": "us-south",
    "function_revision": {
      "url": "https://us-south.ml.cloud.ibm.com/v4/functions/d936336d-d9a3-444f-beec-f504dbc00f94/revisions/65e0971f-ab64-4183-b022-a2074e8f57b7",
      "content_url": "https://us-south.ml.cloud.ibm.com/v4/functions/d936336d-d9a3-444f-beec-f504dbc00f94/revisions/65e0971f-ab64-4183-b022-a2074e8f57b7/content"
    }
  }
}
```

登録したAI Functionは、Watson Studioの管理画面からは、下のようにDeploymentの一つとして見えるようになります。

![スクリーンショット 2018-12-28 21.51.06.png](https://qiita-image-store.s3.amazonaws.com/0/206130/f6811157-db82-d8c5-0d07-31d2ae3d553c.png)

通常のWebサービス同様にscoring-endpoint URLを持っていて、ここに向かってリクエストを投げると、結果がかえってきます。この振る舞いは、機械学習モデルから直接作ったWebサービスとまったく同じです。