RspberryPi + センサ + Jubatus 2(機械学習にかけてみる)

##ディクショナリ型に変換する
前回やったようにMongoDB内のデータを取得してみる．

```
$ python client.py
{u'_id': ObjectId('5567fbdc94e0343f0673444c'), u'data': 174, u'name': u'lux'}
{u'_id': ObjectId('5567fbdc94e0343f0673444d'), u'data': 176, u'name': u'lux'}
{u'_id': ObjectId('5567fbdd94e0343f0673444e'), u'data': 180, u'name': u'lux'}
{u'_id': ObjectId('5567fbdd94e0343f0673444f'), u'data': 176, u'name': u'lux'}
{u'_id': ObjectId('5567fbde94e0343f06734450'), u'data': 177, u'name': u'lux'}
{u'_id': ObjectId('5567fbdf94e0343f06734451'), u'data': 186, u'name': u'lux'}
{u'_id': ObjectId('5567fbdf94e0343f06734452'), u'data': 177, u'name': u'lux'}
{u'_id': ObjectId('5567fbe094e0343f06734453'), u'data': 174, u'name': u'lux'}
{u'_id': ObjectId('5567fbe094e0343f06734454'), u'data': 185, u'name': u'lux'}
{u'_id': ObjectId('5567fbe194e0343f06734455'), u'data': 175, u'name': u'lux'}
{u'_id': ObjectId('5567fbe194e0343f06734456'), u'data': 177, u'name': u'lux'}
```
MongoDBに保存されているデータはJSONではなくBSONです．JSONには
`ObjectId('5567fbdd94e0343f0673444f')`
のような括弧付きの表記はないです．今回は，IDとか特に使わないだろうし，ID自体消してしまおうかと思います．消してしまえば，JSON形式に変換できるようになります.  

最終的に教師データとして渡すには，**JSON形式ではなく，ディクショナリ**にしておきます．なので
`BSON → JSON → ディクショナリ`
という流れで変換を進めます.  
client.pyを書き換えてみましょう

```client.py
# usr/bin/env python
# -*- coding:utf-8 -*-

from pymongo import MongoClient
import json

class getmongo:
    con = MongoClient('172.16.4.83', 27017)
    db = con["sensordb"]
    col = db.sensors

    for data in col.find({'name':'lux'}):
        del data['_id']
# BsonをJsonに変換
        json_list = json.dumps(data)
# Jsonをディクショナリに変換
        print json.loads(json_list)

```
実行してみると

```
$ python client.py
{u'name': u'lux', u'value': 184}
{u'name': u'lux', u'value': 183}
{u'name': u'lux', u'value': 182}
{u'name': u'lux', u'value': 185}
{u'name': u'lux', u'value': 192}
{u'name': u'lux', u'value': 190}
{u'name': u'lux', u'value': 186}
{u'name': u'lux', u'value': 186}
{u'name': u'lux', u'value': 185}
{u'name': u'lux', u'value': 192}
{u'name': u'lux', u'value': 193}
{u'name': u'lux', u'value': 191}
{u'name': u'lux', u'value': 187}
{u'name': u'lux', u'value': 187}
{u'name': u'lux', u'value': 185}
{u'name': u'lux', u'value': 182}
{u'name': u'lux', u'value': 183}
{u'name': u'lux', u'value': 188}
{u'name': u'lux', u'value': 191}
{u'name': u'lux', u'value': 188}
{u'name': u'lux', u'value': 186}
{u'name': u'lux', u'value': 187}
{u'name': u'lux', u'value': 187}
{u'name': u'lux', u'value': 185}
```

ディクショナリ型に変換出来ました．

##センサ値を機械学習にかけてみる

Jubatusチュートリアルのanomalyを参考にプログラムを作成します．  
<http://jubat.us/ja/tutorial/anomaly_python.html>  

その前に！先ほど作成した，BSONからJSONに，そしてディクショナリ型に変換するプログラム`client.py`を利用できるようにしたいです．ディクショナリをメインクラスに渡せるように関数を追加します．

```client.py
# -*- coding:utf-8 -*-

from pymongo import MongoClient
import json

class getmongo:
    con = MongoClient('172.16.4.83', 27017)
    # con = MongoClient('192.168.1.104', 27017)
    db = con["sensordb"]
    col = db.sensors
    global dic
    dic = {}
    count = 0

    for data in col.find({'name':'lux'}):
        del data['_id']
# BsonB$rJsonB$KJQ49
        json_list = json.dumps(data)
# JsonB$r%G%#%/%7%g%J%j$KJQ49
        dic[count] = json.loads(json_list)
        count += 1

    def getDic(self):
        return dic

```

そして，Jubatusのanomalyを利用してみましょう．

```jubalux.py
# -*- coding: utf-8 -*-

import sys, json
from jubatus.anomaly import client
from jubatus.common import Datum
from pymongo import MongoClient
from client import getmongo

NAME = "lux";

if __name__ == '__main__':

    # 1.Jubatus Serverへの接続設定
    anom = client.Anomaly("127.0.0.1",9199,NAME)

    # 2.学習用データの準備
    getmongo =  getmongo()
    dic = getmongo.getDic()
    name = ''
    value = 0
    for line in dic:
        name = dic[line]['name']
        value = dic[line]['value']
        datum = Datum()

        for (k, v) in [
                ['name', name],
                ]:
            datum.add_string(k, v)

        for (k, v) in [
                ['value', value],
                ]:
            datum.add_number(k, v)

        # 3.データの学習（学習モデルの更新）
        ret = anom.add(datum)

        # 4.結果の出力
        if (ret.score != float('Inf')) and (ret.score!= 1.0):
            # print ret, label
            print ret
```

実行するとこうなります．

```
$ python jubalux.py
id_with_score{id: 2005, score: 1.30903303623}
id_with_score{id: 2008, score: 1.26389038563}
id_with_score{id: 2015, score: 0.999999523163}
id_with_score{id: 2016, score: 1.00000071526}
id_with_score{id: 2017, score: 0.925925433636}
id_with_score{id: 2018, score: 1.00247001648}
id_with_score{id: 2019, score: 1.41665911674}
id_with_score{id: 2039, score: 2.05128192902}
id_with_score{id: 2050, score: 1.01709413528}
id_with_score{id: 2052, score: 1.02777767181}
id_with_score{id: 2061, score: 1.1565656662}
id_with_score{id: 2063, score: 1.02314817905}
id_with_score{id: 2077, score: 1.47916650772}
```

異常検知の重みは，config.jsonを書き換えればうまくいく気がします．今回はとりあえず異常検知の結果はどうであれ，Jubatusを利用した機械学習を行うことが出来ました．