Google Facetsでデータ可視化職人に!
24日目、うめきumeki.iconです。
みなさんはGoogleのFacetsという可視化ツールをご存知でしょうか?
簡単に言うと、膨大なデータの可視化をささっとやってくれる超便利ツールです。
本日は環境構築を含めてFacetsの使い方について説明したいと思います。
ちょっと寄り道もするので、よくわからないところは読み飛ばしちゃってください。
Google Facetsの概要
Facetsには2つのメイン機能が存在します。
Facets Overview
データセットの特徴を把握したり、複数のデータセットの比較(トレーニングデータとテストデータなど)したりするのに使います。データセット間でのデータの偏り、不足している特徴量、欠損の多い特徴量などを把握することができます。
https://gyazo.com/ec8b29c41d14af2508e7ff244489c948
Facets Dive
データ点間の関係を分析するのに使います。ユーザはデータセットの各特徴量を自由に制御して可視化することができます。例えば、画像認識問題においては、正解ラベルと予測ラベルの関係がわかります(本当はカエルと認識されてほしいけど猫と認識されてしまった画像たちをまとめてみることができたり!)。
https://gyazo.com/d3a8cedbfa1c52bd41a71f0f5b2eccab
https://gyazo.com/55f9140695dd18d22c2bf44a4fe72dd5
どうでしょうか?何か試してみたくなった方はオンラインでも試せるのでぜひこちらで遊んでみてください。 ただ、オンラインだとまずい!とか、もっとカスタマイズしたい!という方には以下の環境構築が必要になります。
環境構築
開発環境とか使ったものとか:
windows10
git
Anaconda
proxy環境
Anacondaとは、Pythonで使うライブラリをまとめてインストールしてくれたり、パッケージ管理をしてくれたり、仮想環境を提供してくれたり、、と、簡単に言ってしまえばPythonを使いやすくしてくれる便利なプラットフォームです。Pythonをとりあえず試してみたいという方はぜひ使ってみてください。 さて、環境構築においてはたくさんのライブラリやパッケージをいれたことによりローカルの環境がめちゃくちゃになるなんてことはしばしばですよね。。それを避けるために仮想環境を用いて開発ごとに環境を独立させることができます。Pythonの仮想環境構築については何種類か方法があるので興味のある方はぐぐってみると良いと思います。Anacondaはcondaコマンドにより仮想環境を構築し、任意のバージョンのライブラリのインストールを行うことができます。今回はせっかくなのでAnacondaの仮想環境でFacetsを動かしてみようと思います。
code:install.sh
conda create -n facets ## 名前がfacetsの仮想環境を作る
conda info -e ## 現在利用できる仮想環境の一覧を確認(デフォルト環境名はbase)
conda activate facets ## facets環境にはいる
これでfacets用の仮想環境を作ることができました。次にこの環境下にfacetsを利用するために必要なものをインストールしていきます。
code: install.sh
conda install python=3.6
conda install -c anaconda protobuf
conda install -c anaconda jupyter
conda install -c anaconda pandas
conda install -c anaconda requests # optional
conda install -c anaconda scikit-learn # optional
conda install -c conda-forge bazel
次に、facetsをインストールします。
code: install.sh
cd facets
Jupyter notebookでfacetsを用いるためには以下の操作が必要です。
jupyter nbextension install facets-dist/ --user
また、可視化を行うデータのサイズが非常に大きいときでもエラーがでないようにJupyter notebookの設定を変更します。まず以下のコマンドをコマンドプロンプトで実行します。
jupyter notebook --generate-config
これにより、.jupyter/jupyter_notebook_config.pyができているはずですので、エディタで開き以下の行を追加します。なお、jupyter notebookがChromeで起動されるように設定しておきましょう。Chrome以外では未解決の挙動が存在することが報告されています。
code: jupyter_notebook_config.py
# 可視化データのサイズ上限を変更
c.NotebookApp.iopub_data_rate_limit = 10000000 # 1000000 -> 10000000に変更(大きくすればOK)
# デフォルトのブラウザをChromeに変更
import webbrowser
webbrowser.resister('chrome', None, webbrowser.GenericBrowser("chrome.exeのパス"))
c.NotebookApp.browser = 'chrome'
動かしてみる!…とその前に
さて、長かった環境構築も終わりです。早速デモを動かしてみましょう。
デモ用のファイルは、Dive_demo.ipynbとOverview_demo.ipynbの2つです。なお、本筋からはそれてしまいますが、これらのソースコードはproxy環境下では動きませんので一部修正が必要です(以下ではファイル拡張子ipynbをpyで表記します)。
code: Dive_demo.py
# Load UCI census and convert to json for sending to the visualization
import pandas as pd
import io
import requests
features = ["Age", "Workclass", "fnlwgt", "Education", "Education-Num", "Marital Status",
"Occupation", "Relationship", "Race", "Sex", "Capital Gain", "Capital Loss",
"Hours per week", "Country", "Target"]
# Load dataframe from external CSV and add header information
proxy_dict = {
}
s = requests.get(url, proxies=proxy_dict).text
df = pd.read_csv(io.StringIO(s),
names=features, # name features for header row
sep=r'\s*,\s*', # separator used in this dataset
engine='python',
skiprows=0, # skip first row without data na_values="?") # add ? where data is missing
こんな感じになります。オリジナルのコードだと、urlが開けませんみたいなエラーが出ると思いますが、proxy設定を加えてurlを指定することで正しく処理が完了するようになりました。まあ、ローカルにファイルをおいて読みこめばいいんですけどね。せっかくなのでproxy環境に対応できるようにデモファイルを書き換えてみました。同様のことがOverview_demo.ipynbにも言えるのでそちらも適宜修正してみてください。
動かしてみる!
今回はDive_demo.ipynbを例に動かしてみます。Jupyter notebookはShift+Enterでブロックの実行になります。df.head()でデータフレームの先頭5行を可視化してみます。
code:Demo_dive.py
df.head()
https://gyazo.com/dec011156785eeaa24f7d10440d02fdf
たくさんの大人の属性について記録されたデータであるとわかりますね(説明が雑)。
次にこのデータテーブルをFacetsで表示するためにJSON形式に変換します。
code:Demo_dive.py
jsonstr = df.to_json(orient='records')
引数orientによって、データフレームの行ラベルindex、列ラベルcolumns、値valuesをどのようにJSONに変換するか指定できます。"records"によって指定された場合、[{column_1: value_1}, {column_2: value_2}, ..., {column_n: value_n}]というように変換されます。したがって、上記のデータは以下のように変換されます。
[{"Age": 25, "Workclass": Private, "fnlwgt": 226802, "Education-Num": 11th, ..., "Target": <=50K.},
{"Age": 38, "Workclass": Private, "fnlwgt": 89814, "Education-Num": HS-grad, ..., "Target": <=50K.},
...
]
次にsprite_sizeなる変数を定義しています。これはFacetsが描画する1つのデータ点の画像サイズです。データ数が非常に大きいときには、1つのデータ点のサイズが大きくなりすぎないように設定しています。
code:Demo_dive.py
# set the sprite_size based on the number of records in dataset,
# larger datasets can crash the browser if the size is too large (>50000)
sprite_size = 32 if len(df.index)>50000 else 64
最後に、ここまで準備してきたjsonstrやsprite_sizeを用いて、Facetsの可視化部分を表示するHTMLコンポーネントを作成します。このとき、jsonstrやsprite_sizeは変数としてHTML_TEMPLATEを定義しています。display関数により作成されたhtmlオブジェクトを出力すればFacetsのグラフが出力されます。
code:Demo_dive.py
# Display the Dive visualization for this data
from IPython.core.display import display, HTML
# Create Facets template
HTML_TEMPLATE = """
<link rel="import" href="/nbextensions/facets-dist/facets-jupyter.html">
<facets-dive sprite-image-width="{sprite_size}" sprite-image-height="{sprite_size}" id="elem" height="600"></facets-dive>
<script>
document.querySelector("#elem").data = {jsonstr};
</script>"""
# Load the json dataset and the sprite_size into the template
html = HTML_TEMPLATE.format(jsonstr=jsonstr, sprite_size=sprite_size)
# Display the template
display(HTML(html))
最初に見せたことと同じことができるようになっているはずです。
https://gyazo.com/d3a8cedbfa1c52bd41a71f0f5b2eccab
おわりに
今回は公式のデモを解説する形になりましたが、pandasのデータフレームで表現できる形、もっと簡単にいうならばエクセルで表現できる形になっているデータであればFacetsを用いて簡単にデータの可視化ができます。なお、今回はJupyter notebookで環境構築したのでやや大変な感じになっていますが、GoogleColaboratoryでやればもうちょっと楽そうです(詳細はこちら)。 P.S. めっちゃ余力があればGoogleColoboratoryでCIFAR-10を使った可視化を試すかも
参考文献