Jupyter + redash + Docker + git で作るデータ分析の知見をチーム内で共有しやすい環境

こんにちは @muddydixon です。

HAROiD では毎日、 TV 視聴ログをはじめ、ご利用いただいているサイトのアクセスや動画配信サイトの再生ログなど大量のデータを収集し、これらを自社のサービスの改善、放送局様・広告主様との実験・実績の確認のため分析しています。

日々のレポート出力などのように定常的に行う分析は git などで適切に管理・改修を行い、メンバとも共有しつつ育んでいけますが、企画のレポートや自社でのマイニング作業などは、当然のことながら企画ごとに分析内容がまちまちなため「write once, run anyware」とはならず、どうしても書きなぐりされがちです。

その為、容易に下記のような状態が発生します。

  • 好きな言語・フレームワークで解析する: 解析環境がばらばらになり、解析をレビューしようと思うと環境構築を都度行うことになる
  • ローカルないしは個人用のクラウドで分析する: ソースコードが蓄積されない。分析者が急に休んだ場合に対応できない
  • 個人の属人的なスキルとしてのみ tips が蓄積される: 「あー、そうやって書けば簡単ですね!」とかのノウハウが共有されない

分析者が担うアウトプットは「レポート」「ファクト」「それに基づいた改善策/施策」なので、その過程であるコードが共有されにくいのは当然といえば当然だと思います。

上記のような状況を脱し、1) tips の共有、2) code の共有、を目的として HAROiD では下記のようなフレームに移行しつつあります。

  1. Redash
  2. Redash + Jupyter
  3. Redash + Jupyter + Docker
  4. Redash + Jupyter + Docker + git

Redash

多くの記事で語られているので詳細は触れませんが Redash は、「クエリを保存・可視化・共有」するための GUI / API を備えたツールです。 HAROiD でも導入しており、 MySQL (Aurora) や Bigquery に接続し、日々様々な集計を実施しています。

HAROiD では、エンジニア以外の方も Redash を見る機会が多く、我々が Query を作成して、そのリンクを社内の Slack に投稿しています。 Redash は解析のひとつ下のレイヤである一次データから集計結果という二次データを取り出す「クエリの共有」という知見の共有には非常に利便性の高いツールだと考えています。

Redash は template を利用することが可能で

SELECT * FROM mytable WHERE created_at BETWEEN "{{BEGIN}}" AND "{{END}}"  

と記述するとパラメタと BEGIN / END を変数として扱ってくれます。 パラメタごとにいっぱいクエリ書かなくていいので、「前に出してくれた集計結果だけど、最新の結果って出る?」と聞かれたときにも便利!

Jupyter + Redash

SQL によって手に入れたデータの結果からだけでも insight を導くことはできるのですが、統計的な有意性を求めたり、散布図行列の作成といった可視化、主成分の抽出などの処理を実施することは流石にできません。こういったデータの分析などを行う際に便利なのが Jupyter です。

Jupyter は分析をしている方なら多くの方がご存知だとは思いますが、 notebook という形式で複数のコードスニペッツをまとめて管理/実行を行うことができます。
markdown も利用できるので、例えば最初のパートにこのノートの目的や経緯、参考リンクなどを付与しておくことで、新しいメンバが入ったとしても目的やなにを対象としていたかを理解できます。

当然 python が動作するので直接 orm を利用し mysql や Bigquery を叩いてもいいのですが、知見を「集計・分析・解析」として一緒くたに閉じ込めるのではなく、 Redash で分析・解析より低いレイヤでも有意義なデータは SQL として保存し、 Redash で共有したいところです。 そして Redash は都合よく API でリクエストすることもできます!

こうすることで

  1. SQL レベルの集計
  2. より複雑な可視化、検定・分析、機械学習

の2つのレベルに分離し、一旦 SQL レベルを Redash で共有することができるようになりました。

しかし、一点、課題が有ります。 issueが長年立ち続けていますが、 API からは前述の template に対して値を渡すことができません。

この課題を HAROiD ではリードエンジニアの @toritsuyo の開発した redash-dynamic-qyery を利用して対応しています。 (利用方法等は こちら をごらんください) この module によって、

query_id = 111  
bind = {  
    'start_date': '2017-01-01T00:00:00',
    'end_date': '2017-01-01T23:59:59',
}
result = redash.query(query_id, bind)  

こんな風に SQL の template 機能を利用できるのでハイパー便利です。

Redash + Jupyter + Docker

Jupyter の環境構築には当然 python が必須で、それなりに環境構築は手間がかかります。
データ解析をしてほしいのに、環境構築に手間取るのは本質ではありません。

そこでとてもよい環境として Jupyter が提供している Docker image で jupyter/datascience-notebook があります。 これは起動するとすぐに Julia / R / Python 2 / Python 3 を利用することができます。

% docker run -it -d --name jupyter -p 8888:8888 jupyter/datascience-notebook
% docker logs jupyter
% open http://localhost:8888

log の中に token がありますので、それでログインしすぐに使い始めることができます。

Docker 環境があれば一発で立ち上がって即、解析を始められるのほんとうに便利ですね!

Redash + Jupyter + docker + git

Jupyter の notebook は実はそれぞれ .ipynb のファイルになっています。
ファイルということは git で管理できます。加えて docker 起動時に volume を利用することでローカルのファイルを Docker の中で処理することができます。

つまり、下記のようなコマンドを実行すると

% git clone some-analysis.git
% cd some-analysis
% docker run -it -d --name jupyter -p 8888:8888 -v $(pwd):/home/jovyan --restart=always jupyter/datascience-notebook

解析の知見を git で管理・共有することができるようになります。

共有し、環境に依存せずにすぐに解析に取り掛かることができ、 SQL レベルの知見は Redash でエンジニア以外にも共有し こうすることで、環境構築を簡略化し、分析で書き捨てになっていたコードを管理・ git により共有することが可能になります。

まとめ

Redash + Jupyter (+ redash-dynamic-query) + Docker + git によって

  • 開発のための環境構築に時間を取られない (言語も縛らない)
  • 解析の知見を書捨てではなく蓄積できる
  • 解析・SQL の知見を共有できる を実現することができます。

また Jupyter を導入し、共有するハードルを下げるだけで、そもそもどういう解析をするのか、などをパワポなどのレポートレベルではなく notebook に記録しておけるので、共有が捗ります

下記のように README.md を書いておけばなお良さげです。

Data analysis  
----

## Getting start
 ```
% git clone git@mygithost:muddydixon/data-analysis.git
% cd data-analysis
% docker run -it -d --name jupyter -p 8888:8888 -e REDASH_API_TOKEN=${REDASH_API_TOKEN} -v $(pwd):/home/jovyan --restart=always jupyter/datascience-notebook
% docker logs jupyter

...
[C 10:02:48.951 NotebookApp]

    Copy/paste this URL into your browser when you connect for the first time,
    to login with a token:
        http://localhost:8888/?token=XXXXXXXXXXXXXXXXXXXXXXXXX
...
 ```

* use above token to login jupyter notebook (http://localhost:8888)

気をつける点

Jupyter は実行をするとそれがそのまま .ipynb の変更として記録されます。
なので、気軽にちょっと叩くだけで git diff が入ります。

対象外の箇所を触ったときはおとなしく git checkout HEAD してください。

脚注

  • ※1: HAROiD では Matlab も Octave も使っていません

We are hiring!!

HAROiD では大量の視聴ログデータ・属性データ・アンケートデータや参加型 CM のデータをマネタイズする仲間を募集しています!!