ML_BearのKaggleな日常

元WEBマーケターのMLエンジニアがKaggleに挑戦する日々を綴ります

JupyterNotebookで簡易ダッシュボードを作ってSlackに投げる方法

ざっくりいうと

JupyterNotebookで広告効果を見るための簡易的なダッシュボードを作って、Slackに毎日投げるようにして簡単に見れるようにした話です。

こんな感じです

もちろんnotebookの中身は仮のものですw

f:id:naotaka1128:20190425220201g:plain:w300

課題

広告運用実績は(GoogleAdsの)出稿データとアプリ内行動データをBigQuery上で結合し、グラフやテーブルを生成して見える化する必要がありました。

しかし、キャンペーンがXX個(たくさん)あるのでBIツールでいくつもグラフを作るのが面倒でした。。

解決策

そこで、グラフを JupyterNotebook 上のPythonでループを回して作り、その結果をSlackに飛ばしてケータイでも気軽に見れるようにしました。

流れ

  1. JupyterNotebook でデータ取得→データ加工→可視化
  2. JupyterNotebookをバッチ実行してHTMLを生成
  3. HTMLをSlackに飛ばす
  4. ↑の流れをCronタスク化して毎日自動実行する

JupyterNotebook でデータ加工とか可視化する

  • データ加工とか可視化はご自由に…。
  • ダッシュボードとして使う際はスクリプト部分が邪魔なので、以下のような スクリプトを非表示にする ボタンを作っておくと便利です。
from IPython.display import HTML

HTML("""
<button id="code-show-switch-btn">スクリプトを非表示にする</button>

<script>
var code_show = true;

function switch_display_setting() {
    var switch_btn = $("#code-show-switch-btn");
    if (code_show) {
        $("div.input").hide();
        code_show = false;
        switch_btn.text("スクリプトを表示する");
    }else {
        $("div.input").show();
        code_show = true;
        switch_btn.text("スクリプトを非表示にする");
    }
}

$("#code-show-switch-btn").click(switch_display_setting);
</script>
""")

JupyterNotebookをバッチ実行してHTMLを生成する

  • ここからが本番
  • runipy を使えば JupyterNotebook をバッチ実行できます
    • インストール
pip install runipy
  • ipynbをバッチ実行して、
# usage: runipy 実行するnotebook 実行結果notebook
runipy notebook.ipynb output.ipynb
  • その後、Jupyterの nbconvert 機能で ipynb ファイルから HTMLファイルを生成します
jupyter nbconvert output.ipynb --to html

HTMLをSlackに飛ばす

  • 作ったHTMLファイルをSlackに飛ばします
  • 以下のような感じで Slack の BotUser としてHTMLを投稿します
# slack_html_upload.py
import requests

TOKEN = 'xoxb-XXXXXXXXXXXXXXXXXXXXXXXXXX'
CHANNEL = 'ZZZZZZZZZZ'

files = {'file': open("output.html", 'rb')}
param = {
    'token': TOKEN,
    'channels': CHANNEL,
    'initial_comment': "【テスト運用中】今日のGoogle Adsのパフォーマンスだよ!"
}
requests.post(
    url="https://slack.com/api/files.upload",
    params=param,
    files=files)

cronで定期実行するように設定する

最後に上記の流れをシェルコマンドにまとめてCronで定期実行するなり何なりすれば簡易ダッシュボードシステムの完成です。

runipy notebook.ipynb output.ipynb &&
jupyter nbconvert output.ipynb --to html &&
python slack_html_upload.py

備考

  • Slackに直接グラフとか投げるんじゃだめだったの?
    • グラフだけなら全然それでよかったですが、テーブルがうまく投げられませんでした。
      • 文字数オーバーしちゃったり、
      • 画像として投げたらサムネイルが小さすぎて見づらかったり…。 という感じでした。