Algorithmiaの構築済みアルゴリズムをTableauから直接利用する #tableau

どうも。データアナリティクス事業本部@大阪オフィスの玉井です。

Tableau社ブログでAlgorithmiaというサービスを利用したビューの作成例があったので、自分もやってみました。

Algorithmiaとは

機械学習のためのプラットフォームを提供しているサービスです。作成したアルゴリズムをアップロードするだけで、そのアルゴリズムを利用できるAPIエンドポイントを作成できたり、元々備わっているアルゴリズムを利用することもできます。詳細は上記サイトをご覧ください。

やってみたこと

太陽の位置情報を加味した地震ダッシュボードを作成する

今回は「地震」に関するダッシュボードを作成します。

アメリカ地質調査所(USGS)のデータをTableauで分析することで、地震の位置・時間・大きさを地図上にプロットすることができます。

発生したそれぞれの地震の特徴として、もちろん震度の大小の違いもあるのですが、「昼間に発生したものか夜間に発生したものか」という違いも非常に大きいです。夜間の地震は見通しが悪いため、倒壊した建物内での避難が困難となり、死傷者の発生リスクが高くなります。だから、その地震が発生した時、「周りが暗いかどうか」というデータはとても大事なことです。

「周りが暗いかどうか」を判別するには、地震の発生時刻がわかればよい…と考えますよね。それでもいいのですが、もっと精密に判別しようとすると「太陽の位置」データも必要です。なぜでしょうか。極端な例をあげると、12月21日正午の北極点には太陽がありません。時間だけでその場所が明るいかどうかは厳密にはわからないのです。だから、今回作成する地震ダッシュボードには太陽の位置情報データも必要、ということになります。

太陽の位置情報を計算するために、上記に書いてあるAlgorithmiaというサービスを利用します。

実践

今回やってみた環境

  • Windows 10 Pro
  • Tableau Desktop 2019.2

USGSのデータをTableauで可視化する

データの取得

下記にUSGSのデータを取得できるAPIリストがあります。

しかし、今回は手っ取り早くCSVをGETします。

  • https://earthquake.usgs.gov/fdsnws/event/1/query?starttime=2019-01-1&endtime=2019-12-31&minmagnitude=6&format=csv

Tableau Desktopで読み込む

csvを読み込み→緯度経度をプロット→マグニチュードをサイズにプロット…という流れで下記の地図を作成。ここまではTableauユーザーなら5秒くらいで終わると思います

Tableau DesktopをTabPyと連携させる

TabPyの準備

下記を参考にTabPyを準備します。

algorithmiaライブラリをインストールする

pip install algorithmiaで algorithmiaライブラリをインストールします。

>pip install algorithmia
Collecting algorithmia
  Downloading https://files.pythonhosted.org/packages/ff/d4/cfefad004dc166c5276243f8644a8061c1645475ed56ee4088bf4ea963f0/algorithmia-1.1.4-py2.py3-none-any.whl
Collecting enum34 (from algorithmia)
  Downloading https://files.pythonhosted.org/packages/af/42/cb9355df32c69b553e72a2e28daee25d1611d2c0d9c272aa1d34204205b2/enum34-1.1.6-py3-none-any.whl
Requirement already satisfied: six in c:\programdata\anaconda3\lib\site-packages (from algorithmia) (1.12.0)
Requirement already satisfied: requests in c:\programdata\anaconda3\lib\site-packages (from algorithmia) (2.21.0)
Collecting algorithmia-api-client<2.0,>=1.0.0 (from algorithmia)
  Downloading https://files.pythonhosted.org/packages/c9/68/fa92d7dd7c643695565af48090bbcc047a0ab74aafbf1c83502d937fc6a2/algorithmia_api_client-1.0.1-py2.py3-none-any.whl (85kB)
    100% |████████████████████████████████| 92kB 3.9MB/s
Requirement already satisfied: idna<2.9,>=2.5 in c:\programdata\anaconda3\lib\site-packages (from requests->algorithmia) (2.8)
Requirement already satisfied: urllib3<1.25,>=1.21.1 in c:\programdata\anaconda3\lib\site-packages (from requests->algorithmia) (1.24.1)
Requirement already satisfied: certifi>=2017.4.17 in c:\programdata\anaconda3\lib\site-packages (from requests->algorithmia) (2019.3.9)
Requirement already satisfied: chardet<3.1.0,>=3.0.2 in c:\programdata\anaconda3\lib\site-packages (from requests->algorithmia) (3.0.4)
Requirement already satisfied: python-dateutil in c:\programdata\anaconda3\lib\site-packages (from algorithmia-api-client<2.0,>=1.0.0->algorithmia) (2.8.0)
Installing collected packages: enum34, algorithmia-api-client, algorithmia
Successfully installed algorithmia-1.1.4 algorithmia-api-client-1.0.1 enum34-1.1.6

TabPyを起動する

TabPyを起動して、Tableau Desktopと連携させます。

Algorithmiaを使用する

Algorithmiaのフリーアカウントを作成する

下記よりアカウントを作成します。

APIキーの取得

Algorithmiaにログイン後、API Keysのタブを選択し、simから始まるAPIキーをコピーします。

Algorithmiaを利用する計算フィールドを作成する

Tableau Desktopに戻り、下記の計算フィールドを作成します。

SCRIPT_INT("
import Algorithmia
import math
client = Algorithmia.client('さっき取得したAPIキー')
algo = client.algo('jhurliman/SunMoonCalculator/0.1.0')
if _arg1[0] and _arg2[0]:
    input = {'lat': _arg1, 'lon': _arg2, 'time': _arg3}
    response = algo.pipe(input)
    rads = response.result['sun_altitude']
    return int(math.degrees(rads))
else:
    return 0
",
ATTR([latitude]),
ATTR([longitude]),
ATTR([time])
)

この計算フィールドは何をやっとるねん?という話をします。

簡単に説明すると下記の通りです。

  • Tableau DesktopのデータをPythonコード内に渡す
    • 緯度、経度、時間
  • Pythonコード内にAlgorithmiaライブラリを呼び出し
  • Algorithmia のSun + Moon Calculatorを実行する
  • 帰ってきた位置情報データ(太陽の高度)が返ってくる
    • 返却値はラジアンだが、Tableauのスピードを考えてintに変換する

SCRIPT_INTというのは、TabPy用の関数です。TabPyにPythonコードを実行させて、結果を受け取るための関数ですね(いくつか種類があるんですけど、今回は返り値が整数のため〜INTを使用します)。

Pythonコードを渡す関数なので、この関数の最初の引数はPythonコードそのものとなります。以降の引数には、Tableau Desktopに読み込んだデータを指定します。ここに指定したデータは、Pythonコード内に渡すことができます(リストオブジェクト)。

太陽の位置情報(高度)をプロットする

上記の計算フィールドを「色」に配置するだけで、地震発生時の太陽の高度が色で表現されます。

色の感じがしっくりこないので、変更します。

地震発生時にその場所が明るかったのかどうか直感的にわかるようになりましたね。

応用編

残念ながら、上記の例はいくつかの欠点があります。

  • APIキーが計算フィールドにベタ書き
  • Algorithmiaクライアントがワークブックを更新するたびに再作成される
  • そもそも計算フィールドが長い

これらの欠点を除くため、TabPyに先にコードをデプロイし、Tableau Desktopからは最小限の計算フィールドで、Algorithmiaを利用できるようにします。

TabPyにコードをデプロイ

TabPyを実行している状態で、下記のスクリプトを実行します(TABPY_SERVER_URLは実行する環境によって、調整してください)。

import Algorithmia
import tabpy_client

ALGORITHMIA_API_KEY = 'AlgorithmiaのAPIキー'
TABPY_SERVER_URL = 'http://localhost:9004/'
DEBUG = True


def algorithmia(algorithm_name, input):
    if DEBUG: print("algorithm: %sinput: %s\n"%(algorithm_name,input))
    try:
        client = Algorithmia.client(ALGORITHMIA_API_KEY)
        algo = client.algo(algorithm_name)
        result = algo.pipe(input).result
    except Exception as x:
        if DEBUG: print(x)
        raise Exception(str(x))
    if DEBUG: print("result: %s"%result)
    return result


tabpy_conn = tabpy_client.Client(TABPY_SERVER_URL)
tabpy_conn.deploy('algorithmia', algorithmia, 'Run a function on Algorithmia: algorithmia(algorithm_name, input)', override=True)

実行に成功すると、上記コード内で定義されているPythonコードがTabPyにデプロイされます。

Tableau Desktopからデプロイしたコードを利用する

最初に作成した計算フィールドを下記のように変更します。

SCRIPT_INT(“
import math
algoname = ‘jhurliman/SunMoonCalculator/0.1.0’
if _arg1[0] and _arg2[0]:
    input = {‘lat’: _arg1, ‘lon’: _arg2, ‘time’: _arg3}
    rads = tabpy.query(‘algorithmia’, algoname, input)[‘response’][‘sun_altitude’]
    return int(math.degrees(rads))
else:
    return 0            
“,
ATTR([Latitude]),
ATTR([Longitude]),
ATTR([Time])
)

先程TabPyにデプロイしたコードを利用する形になっています。ですので、APIキーをベタ書きする必要ありません。

同じ計算結果が返ってきました(色の設定は改めてする必要がありますが…)

おわりに

今回はTableau社のブログをそのままやってみた形となりましたが、Algorithmiaというサービスをうまく使えば、例えばAlteryxから利用して計算した後、Tableauで可視化する…といったこともできそうです。