Cloud Pak for DataでOnline型デプロイしたpythonモデルと関数をフォーム形式の入力データでテストする

Cloud pak for Data (以下CP4D) のデプロイメントスペースでモデルをOnline型にデプロイすると、デプロイメントの詳細画面で動作をテストすることができます。
テスト実行に使うサンプル入力データを指定するやり方として、以下のようなフォーム形式での指定と、
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/397277/03e44234-6f81-1423-eece-e819548edce0.png)

JSON形式での指定が可能です。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/397277/2470ebb5-617d-d287-755e-4afde0dc3a5e.png)

フォーム形式を使うには、モデルを入力スキーマ付きで作成する必要があります。
Modeler Flow (SPSS)で作成したモデルは自動的に入力スキーマがつくようですが、Pythonで作成したモデルはWML clientで保存する際にメタ情報として入力スキーマを指定する必要があります。

# Pythonで作成したモデルを入出力スキーマ付きで保存する方法
以下のコードは、WML clientを使って作成したscikit-learnモデルをデプロイメントスペースに保存しているものです。WML clientの使い方については、[こちらの記事](https://qiita.com/ttsuzuku/items/eac3e4bedc020da93bc1)を参照。

フォーム形式に必須なのは入力スキーマだけですが、ついでに出力スキーマもつけています。

```python:モデルの場合
meta_props={
    client.repository.ModelMetaNames.NAME: "sample_iris_model",
    client.repository.ModelMetaNames.RUNTIME_UID: "scikit-learn_0.22-py3.6",
    client.repository.ModelMetaNames.TYPE: "scikit-learn_0.22",
    client.repository.ModelMetaNames.INPUT_DATA_SCHEMA: [{
        "id":"input",
        "type":"list",
        "fields":[
            {'name': 'sepal length (cm)', 'type': 'double'},
            {'name': 'sepal width (cm)', 'type': 'double'},
            {'name': 'petal length (cm)', 'type': 'double'},
            {'name': 'petal width (cm)', 'type': 'double'}
        ]
    }],
    client.repository.ModelMetaNames.OUTPUT_DATA_SCHEMA: {
        "id":"output",
        "fields": [
            {'name': 'iris_type', 'type': 'string','metadata': {'modeling_role': 'prediction'}}
        ]
    }
}

model_artifact = client.repository.store_model(model, meta_props=meta_props, training_data=X, training_target=y)
model_id = model_artifact['metadata']['guid']
```

```python:関数(function)の場合
meta_props = {
    client.repository.FunctionMetaNames.NAME: 'sample_iris_scoring_func',
    client.repository.FunctionMetaNames.RUNTIME_UID: "ai-function_0.1-py3.6",
    client.repository.FunctionMetaNames.SPACE_UID: space_id,
    client.repository.FunctionMetaNames.INPUT_DATA_SCHEMAS: [{
        "id":"input",
        "fields": [
            {"metadata": {}, "type": "double", "name": "sepal length (cm)", "nullable": False},
            {"metadata": {}, "type": "double", "name": "sepal width (cm)", "nullable": False},
            {"metadata": {}, "type": "double", "name": "petal length (cm)", "nullable": False},
            {"metadata": {}, "type": "double", "name": "petal width (cm)", "nullable": False}
        ]
    }],
    client.repository.FunctionMetaNames.OUTPUT_DATA_SCHEMAS: [{
        "id":"output",
        "fields": [
            {"metadata": {'modeling_role': 'prediction'}, "type": "string", "name": "iris_type", "nullable": False}
        ]
    }]
}

function_details = client.repository.store_function(meta_props=meta_props, function=iris_scoring)
function_id = function_details['metadata']['guid']
```

## 補足: CP4D v3.0.1からの変更点
厳密に言うと、CP4DのバージョンではなくWML clientのバージョンv1.0.95からの変更点です。
CP4D v3.0.1にはデフォルトでWML client v1.0.95が含まれています。

変更点は、モデルの入力スキーマをdict型ではなくlist型で指定するようになったことです。上記のサンプルコードはINPUT_DATA_SCHEMAをlist型で指定しています。
この変更は、複数の入力データテーブルに対応するためのもののようですが、v1.0.95より前はdict型で指定していたため、下位互換性のためv1.0.99以降でdict型を指定してもエラーにならないように修正されています。

なお、私が試したところ、v1.0.95でlist型で指定してもエラーになりました。（これはこれで問い合わせ中）
v1.0.103ではうまくいくので、```pip install -U watson-machine-learning-client-V4```でアップグレードしてから使うことをオススメします。