Health PlanetのデータをKibana Timelionで可視化してみた

# はじめに

身近なデータと手段があれば可視化してみたくなるものです。

先日見かけた記事を手元の環境で試してみて、その手軽さにとても驚きました。(Google Drive APIも初めて使ってみましたがとても便利だなぁと思いました。Spreadsheetにリアルタイムに行が追加される様子は、まさに「ポコポコ」という表現がピッタリでした)

* [Health Planet からデータをエクスポートするための embulk-input-healthplanet プラグイン - 無印吉澤](http://muziyoshiz.hatenablog.com/entry/2016/01/11/234921)
* [タニタの Health Planet から新しいデータだけエクスポートして Google Spreadsheet にポコポコ足していく方法 - 無印吉澤](http://muziyoshiz.hatenablog.com/entry/2016/01/23/201957)

ちょうどHeath Planetに登録したデータはありますので、KibanaプラグインのTimelionの使い方の勉強も兼ねてEmbulkでElasticsearchに登録して可視化を試してみました。

# 必要なもの（環境）

1. そこそこ溜まっている タニタの Health Planet のデータ
1. Embulk 0.8.8
1. Docker 1.10.1
  1. Elasticsearch 2.3.0
  1. Kibana 4.5.0

試した環境は `Debian GNU/Linux 8.4 (jessie)` です。DockerはElastic環境構築の手間を省くために使用しているので必須ではありません。

Elasticsearch、Kibana、Embulkの導入は以下の記事と同じですので、そこからの差分という形で説明します。

* [シェルのヒストリをKibanaで可視化してみた - Qiita](http://qiita.com/yoshikaw/items/c8661ef83d6301ffb53c)

# 可視化結果

一年ほど前に体組成計を買い換えてからチマチマと登録していたデータです。今年入ってから計測サボっているのが一目で分かりますね。。。

![kibana-timelion.png](https://qiita-image-store.s3.amazonaws.com/0/6124/a22d3a86-7fec-6557-5fef-548edd504e51.png)

iPhoneアプリケーションだと最大2軸しか表示できませんし、Webアプリケーションだと範囲が狭すぎて長期スパンで把握できません。Kibanaを使うことでどちらの不満点も解消できます。

|iPhoneアプリケーション|Webアプリケーション|
|:----|-----|
|![](https://qiita-image-store.s3.amazonaws.com/0/6124/5957e057-0f88-9452-ea08-017c5ccebd11.png)|![](https://qiita-image-store.s3.amazonaws.com/0/6124/aeb8817f-a018-cf5f-73e1-ad3d39eceb5e.png)|


# Kibana

## Kibanaプラグイン

### timelion

* [Timelionの紹介 - Elasticsearch Advent Calendar 2015 1日目 - @johtaniの日記 2nd](http://blog.johtani.info/blog/2015/12/01/introduction-timelion/)
* [Timelion: Kibanaの時系列コンポーザ | Elastic](https://www.elastic.co/jp/blog/timelion-timeline)

```bash
sudo docker exec kibana /bin/bash -c '/opt/kibana/bin/kibana plugin -i kibana/timelion'
```

プラグインを読み込ませるためにKibanaを再起動します。

```bash
sudo docker retsart kibana
```

# Embulk

## Embulkプラグイン

### embulk-imput-healthplanet

Health Planetからの入力プラグイン。

* [muziyoshiz/embulk-input-healthplanet: Embulk Input Plugin for Health Planet](https://github.com/muziyoshiz/embulk-input-healthplanet)

```bash
embulk gem install embulk-input-healthplanet
```

Health Planet APIの利用登録やプラグインの使用方法やは冒頭のリンクで確認してください。

# Embulkでデータローディング

入力をHealth Planet、出力をElasticsearchにするだけのシンプルな定義です。

```yaml:healthplanet-es.yml
in:
  type: healthplanet
  login_id: {{Health PlanetのログインID}}
  password: {{Health Planetのパスワード}}
  client_id: {{Client ID}}
  client_secret: {{Client Secret}}
  lang: ja

out:
  type: elasticsearch
  nodes:
    - {host: localhost, port: 9300}
  index: healthplanet
  index_type: healthplanet
```

Embulkで実行する場合には、次回以降実行時に参照するデータ記録ファイルを `-c` で指定します。(`-o`で同じ定義ファイルを上書きするのはdeprecatedになっています)

```bash
embulk run healthplanet-es.yml -c healthplanet-es-diff.yml
```

今回はElasticsearchのインデックステンプレートを作成していませんが、`lang:ja`の場合は以下のようなマッピングが作成されます。

```bash
% curl 'localhost:9200/_mapping/healthplanet?pretty'
{
  "healthplanet" : {
    "mappings" : {
      "healthplanet" : {
        "properties" : {
          "モデル" : {
            "type" : "string"
          },
          "体内年齢" : {
            "type" : "long"
          },
          "体脂肪率" : {
            "type" : "double"
          },
          "体重" : {
            "type" : "double"
          },
          "内臓脂肪レベル2" : {
            "type" : "double"
          },
          "基礎代謝量" : {
            "type" : "long"
          },
          "推定骨量" : {
            "type" : "double"
          },
          "測定日時" : {
            "type" : "date",
            "format" : "strict_date_optional_time||epoch_millis"
          },
          "筋肉スコア" : {
            "type" : "long"
          },
          "筋肉量" : {
            "type" : "double"
          }
        }
      }
    }
  }
}
```

# Timelionでグラフ作成

データの登録が出来たらTimelionでのグラフ作成です。1行2列の定義を作成してグラフを追加します。

基本的な使い方は以下の記事を参考にしました。

* [Timelionで線、棒、固定値を含んだグラフを描く - Qiita](http://qiita.com/kirareyaku/items/53eae9a4982ccefa4ebc)

あとは公式の紹介動画にある画面の式をひたすら眺めました。

* [Timelion: Time Series Analytics for Kibana - YouTube](https://www.youtube.com/watch?v=-sgZdW5k7eQ)

今回のグラフ式で考慮した点。

* 一日に複数回計測することもあったので値は平均
* 紹介動画を見ていると、ひとつのグラフに複数データソースを入れている場合に$変数を使用していたので.es関数の索引とタイムスタンプ列の指定で使用(`$i`,`$t`)
* 第2軸(`.yaxis(2)`)は何もしないと0始まりになる(逆に言うと1軸の場合では0始まりにできない？)
* (画面キャプチャを考慮して)グラフ領域の高さが狭いので凡例は横並びに(`.legend(column=3)`)

```txt:グラフ1の式
$i=healthplanet, $t=測定日時, .es(index=$i, timefield=$t, metric=avg:体重).label('体重(kg)').title('Health Planet Data').legend(columns=3), .es(index=$i, timefield=$t, metric=avg:体脂肪率).yaxis(2).label('体脂肪率(%), 右軸'), .es(index=$i, timefield=$t, metric=avg:内臓脂肪レベル2).yaxis(2).label('内臓脂肪レベル, 右軸')
```

```txt:グラフ2の式
$i=healthplanet, $t=測定日時, .es(index=$i, timefield=$t, metric=avg:体内年齢).precision(0).label('体内年齢').color(#ddd).legend(columns=3), .es(index=$i, timefield=$t, metric=avg:推定骨量).yaxis(2).points(symbol=cross).label('推定骨量(kg), 右軸'), .es(index=$i, timefield=$t, metric=avg:筋肉スコア).precision(0).yaxis(2,0,4).points(symbol=cross).label('筋肉スコア, 右軸')
```

# おわりに

Kibanaプラグインとして登場したTimelionは、今はKibanaのTimeseriesというVisualizeとして保存できますので、Dashboardに追加して、ほかのグラフとあわせて参照することで新たな発見があるかも知れません。

<blockquote class="twitter-tweet" data-lang="ja"><p lang="en" dir="ltr"><a href="https://twitter.com/hashtag/timelion?src=hash">#timelion</a> panels: Now for <a href="https://twitter.com/hashtag/kibana?src=hash">#kibana</a> dashboards! No kibana filters yet, but it works. Reinstall <a href="https://twitter.com/hashtag/timelion?src=hash">#timelion</a> to get it! <a href="https://t.co/cekEJVc6Kx">pic.twitter.com/cekEJVc6Kx</a></p>&mdash; Rashid Khan (@rashidkpc) <a href="https://twitter.com/rashidkpc/status/705409344007868416">2016年3月3日</a></blockquote>

まだまだTimelionについてはマニュアルが追いついていないようですので、いろいろ試してみようと思います。(紹介動画には別グラフのデータソースで割った値を表示する例がありました)

* https://www.youtube.com/watch?v=-sgZdW5k7eQ&t=27s

```txt:グラフ1の式
.es(*).divide(@2)
```
```txt:グラフ2の式
.es(*,metric=cardinality:user).label('Count of Unique Users').color(#c66)
```

それと、計測データをながめてみて、そろそろ運動しなきゃなと思いました。