BluemixでWatson API のVisual Recognition を使う by python

# はじめに
[BluemixでWatson API のVisual Recognition を使う by curl](http://qiita.com/MoriKen/items/6403cf5f6775bb8aa4c4) のPython版．

構成は下記の通りです．

- サーバ：Bluemix上でVisual Recognitionのサービスをインスタンス化する
- クライアント：コマンドラインから`python`コマンドで学習と判別を行う

基本的には下記チュートリアルを参照しました．

- [Visual Recognition Tutorials](https://www.ibm.com/watson/developercloud/doc/visual-recognition/tutorials.shtml)

Bluemix アカウントはトライアル版です．Bluemixにログインをした状態からスタートします．

# 手順
## Visual Recognition のサービスを準備する
[BluemixでWatson API のVisual Recognition を使う by curl](http://qiita.com/MoriKen/items/6403cf5f6775bb8aa4c4#visual-recognition-%E3%81%AE%E3%82%B5%E3%83%BC%E3%83%93%E3%82%B9%E3%82%92%E6%BA%96%E5%82%99%E3%81%99%E3%82%8B)と同一の手順を実行する．

## Visual Recognition Python 用SDKをインストールする
ローカルで下記を実行．

```bash
pip install watson-developer-cloud
```

## ユーザが用意した画像で学習させる
1. ポジティブ画像群を***{positive_images}.zip***で保存する．
 - 名称は任意でよい．
 - 保存場所はローカルで良い．
 - 今回はチュートリアル参考に[beagle.zip](https://github.com/watson-developer-cloud/doc-tutorial-downloads/raw/master/visual-recognition/beagle.zip)，[husky.zip](https://github.com/watson-developer-cloud/doc-tutorial-downloads/blob/master/visual-recognition/husky.zip)，[golden-retriever.zip](https://github.com/watson-developer-cloud/doc-tutorial-downloads/raw/master/visual-recognition/golden-retriever.zip) を保存した．
2. ネガティブ画像群を***{negative_images}.zip***で保存する．
 - 名称は任意でよい．
 - 保存場所はローカルで良い．
 - 今回はチュートリアル参考に[cats.zip](https://github.com/watson-developer-cloud/doc-tutorial-downloads/raw/master/visual-recognition/cats.zip) を保存した．
2. 下記のようなコードで従って学習コマンドを実行する

```py
import json
from os.path import join, dirname
from watson_developer_cloud import VisualRecognitionV3


def main():
    visual_recognition = VisualRecognitionV3('2016-05-20', api_key='{api-key}')

    print('Start Creating Classifier')
    with open(join(dirname(__file__), '{positive_images}.zip'), 'rb') as file1, \
            open(join(dirname(__file__), '{negative_images}.zip'), 'rb') as file2:
        print(json.dumps(
            visual_recognition.create_classifier('{classifier_name}',
                                                 {classname}_positive_examples=file1,
                                                 negative_examples=file2, indent=2))
    print('Finish Creating Classifier')

if __name__ == '__main__':
        main()
```

 - 書式
   - ***{positive_images}.zip***: ポジティブクラスの画像群を格納したzipファイル．本ソースコードのファイルパスを基点とした相対パスを想定．
   - ***{classname}*** にクラス名が入る．
        - 各クラスの接尾詞である"_positive_examples"と"_negative_examples"は固定．
   - ***{negative_images}.zip***：ネガティブクラスの画像群を格納したzipファイル．
   - ***{classifier_prefix}***：分類器名接頭辞
   - ***{api-key}***：先に取得したapi-key名
   - versionを入れないと動かない．
 - 例（チュートリアルを参考）

```py
import json
from os.path import join, dirname
from watson_developer_cloud import VisualRecognitionV3


def main():
    visual_recognition = VisualRecognitionV3('2016-05-20', api_key='{api-key}')

    print('Start Creating Classifier')
    with open(join(dirname(__file__), '../../resources/beagle.zip'), 'rb') as beagle, \
            open(join(dirname(__file__), '../../resources/husky.zip'), 'rb') as husky, \
            open(join(dirname(__file__), '../../resources/golden-retriever.zip'), 'rb') as golden_retriever, \
            open(join(dirname(__file__), '../../resources/cats.zip'), 'rb') as cats:
        print(json.dumps(
            visual_recognition.create_classifier('dogs',
                                                 beagle_positive_examples=beagle,
                                                 husky_positive_example=husky,
                                                 goldenretriever_positive_examples=golden_retriever,
                                                 negative_examples=cats), indent=2))
    print('Finish Creating Classifier')

if __name__ == '__main__':
        main()
```

4.結果を確認する．

 - 分類器のidや，クラスの種類等学習機に関わるパラメータが出力されたら，学習完了．

```js
{
    "classifier_id": "dogs_xxxxxxxxxx",
    "name": "dogs",
    "owner": "xxxx-xxxxx-xxx-xxxx",
    "status": "training",
    "created": "2016-xx-xxTxx:xx:xx.xxxZ",
    "classes": [
        {"class": "husky"},
        {"class": "goldenretriever"},
        {"class": "beagle"}
    ]
}
```
 
## ユーザ学習によるカスタム分類器を利用する
1. 下記内容を`myparams.json`として保存する．
- `{
    "classifier_ids": ["dogs_xxxxxxxxxx", "default"] 
}`
     - `"dogs_xxxxxxxxxx"`は，先の処理で取得した`"classifier_id"`と対応させる．
     - `"default"`は元々Visual Recognitionが持っている分類器のid．
     - こうして指定することで，複数の分類器の結果を得られる．
2. 認識させたい画像を用意する．
 - 名称は任意でよい．
 - 保存場所はローカルで良い．Web上の画像でも良い．
 - 今回はチュートリアル参考に[bdogs.jpg](https://github.com/watson-developer-cloud/doc-tutorial-downloads/raw/master/visual-recognition/dogs.jpg)を保存した．
2. 認識させたい画像をカスタム分類器に送信し，学習結果と照合させる．

```py
import json
from os.path import join, dirname
from watson_developer_cloud import VisualRecognitionV3


def main():
    visual_recognition = VisualRecognitionV3('2016-05-20', api_key='{api-key}')

    print('Start Classifying')

    with open(join(dirname(__file__), '{image}.jpg'), 'rb') as file:

        print(json.dumps(visual_recognition.classify(
            images_file=file,  threshold=0.1, classifier_ids=['{classifier_id}', 'default']), indent=2))

    print('Finish Classifying')


if __name__ == '__main__':
        main()
```

 - 書式
   - ***{image}.jpg***: 認識対象の画像ファイル．本ソースコードのファイルパスを基点とした相対パスを想定．
   - ***{classifier_id}***：分類器id
   - ***{api-key}***：先に取得したapi-key名

 - 例（チュートリアルを参考）

```py
import json
from os.path import join, dirname
from watson_developer_cloud import VisualRecognitionV3


def main():
    visual_recognition = VisualRecognitionV3('2016-05-20', api_key='{api_key}')

    print('Start Classifying')

    with open(join(dirname(__file__), '../../resources/dogs.jpg'), 'rb') as dogs:

        print(json.dumps(visual_recognition.classify(
            images_file=dogs,  threshold=0.1, classifier_ids=['dogs_xxxxxxxxxx', 'default']), indent=2))

    print('Finish Classifying')


if __name__ == '__main__':
        main()
```

4.結果を確認する．
 -  前半は元々Visual Recognitionが持っている分類器("classifier_id": "default")による結果．
     -  "animal", "mammal", "dog"
 -  後半はカスタム分類器("classifier_id": "dogs_xxxxxxxxxx")による結果．
     - "goldenretriever"  

```js
{
    "images": [
        {
            "classifiers": [
                {
                    "classes": [
                        {
                            "class": "animal",
                            "score": 1.0,
                            "type_hierarchy": "/animals"
                        },
                        {
                            "class": "mammal",
                            "score": 1.0,
                            "type_hierarchy": "/animals/mammal"
                        },
                        {
                            "class": "dog",
                            "score": 0.880797,
                            "type_hierarchy": "/animals/pets/dog"
                        }
                    ],
                    "classifier_id": "default",
                    "name": "default"
                },
                {
                    "classes": [
                        {
                            "class": "goldenretriever",
                            "score": 0.610501
                        }
                    ],
                    "classifier_id": "dogs_xxxxxxxxxx",
                    "name": "dogs"
                }
            ],
            "image": "dogs.jpg"
        }
    ],
    "images_processed": 1
}
```