こんにちは。
現役エンジニアの”はやぶさ”@Cpp_Learningです。最近は統計的因果推論を勉強中です。
相関関係をインタラクティブなグラフで可視化してみた pic.twitter.com/5pmkV1vPEu
— はやぶさ@技術ノート (@Cpp_Learning) February 6, 2021
本記事では相関関係をグラフ(ネットワーク)で可視化する方法を紹介します。
Contents
モチベーション -なぜ相関をインタラクティブなグラフで可視化するのか-
相関の可視化には、ヒートマップがよく使われます(下図参照)。
上図の場合は、変数同士の相関の強さを色の濃さで表現しています。例えば、”RAD”と”TAX”には強い相関があるようです。
と感じる人もいれば…
というフクロウもいるかと。
個人的にはヒートマップ大好きですが、説明変数の数や色彩感覚によっては、ヒートマップによる可視化は分かりにくいケースがあります。
そこで、以下の記事のようにグラフで相関関係を可視化したいと思います。
上記の記事では、グラフ(ネットワーク)構造を NetworkX で可視化しましたが、今回はPyvisを使ってインタラクティブなグラフを作成します。
インタラクティブなグラフを活用することで、ノードやエッジの色や位置を調整しならがら、関係性やグラフ構造についてのプレゼンができます
実践!相関関係をインタラクティブなグラフで可視化する
機械学習チュートリアルでお馴染みの ボストンの住宅価格データセット を採用し、各変数の相関関係を可視化します。
インストール
本記事のソースコードはGoogle Colabで動作確認しました(2021/02/07)。
Google Colabの場合は、以下のコマンドでインストールするだけで環境構築完了です。
pip install pyvis
以降からコード書いていきます。
Import
まずはimportから
1 2 3 4 5 6 7 8 9 |
import pandas as pd import numpy as np import matplotlib.pyplot as plt import seaborn as sns from sklearn.datasets import load_boston import networkx as nx from pyvis.network import Network |
データセット
データをダウンロードして、中身(頭の3行)を確認しておきます。
1 2 3 4 5 |
boston = load_boston() boston_df = pd.DataFrame(boston.data, columns=boston.feature_names) # 説明変数 boston_df['PRICE'] = boston.target # 目的変数を追加 boston_df.head(3) |
相関係数の算出とヒートマップによる可視化
以下のコード1行で相関係数を算出できます。
1 2 3 |
df_corr = boston_df.corr() # df_corr |
本題ではありませんが、よく使うのでヒートマップによる相関関係の可視化も紹介します。
1 2 3 4 5 6 7 8 9 |
# 相関をヒートマップで可視化 plt.figure(figsize=(14,12)) sns.heatmap(df_corr, # データ vmin=-1, vmax=1, # 範囲 annot=True, fmt='0.2f', # 数値表示 cmap=sns.color_palette('coolwarm', 100), # 色指定 # square=True, # ヒートマップを正方形で表示 ); |
冒頭のヒートマップと同じものです。seaborn使って可視化してます。
以降から、本題のグラフによる相関関係の可視化を実践します。
前処理
ヒートマップの「右上の三角行列」と「左下の三角行列」は同じ情報なので、「右上の三角行列」にマスクをして、Noneに置き換えます。
1 2 3 4 |
# 右上の三角行列をマスク mask_df = df_corr.mask(np.triu(np.ones(df_corr.shape)).astype(bool), None) # mask_df |
マスクの使い方については、以下の記事で紹介済みなので、参考にしてくださいな。
エッジリスト作成
以下のコードでエッジリストを作成します。
1 2 3 4 5 |
# エッジリストを生成 edge_lists = mask_df.stack().reset_index().apply(tuple, axis=1).values # 確認 edge_lists |
array([(‘ZN’, ‘CRIM’, -0.20046921966254821),
(‘INDUS’, ‘CRIM’, 0.4065834114062593),
…
(‘PRICE’, ‘B’, 0.33346081965706653),
(‘PRICE’, ‘LSTAT’, -0.7376627261740143)], dtype=object)
エッジリストの中身は上記の通りで、例えば ‘PRICE’ と ‘LSTAT’ の相関係数は約-0.74のようです(ヒートマップでも確認できます)
networkxグラフをpyvisグラフに変換
pyvisグラフを作成する方法がいくつかありますが、以下の手順が簡単でした。
- networkxグラフを作成
- networkxグラフをPyvisグラフに変換
- エッジの太さなどを調整(オプション)
- インタラクティブなグラフを出力
順番に実装していきます。
以下のコードでPyvisグラフを作成できました。
1 2 3 4 5 6 7 8 9 10 11 |
# networkxのグラフ作成 G = nx.Graph() G.add_weighted_edges_from(edge_lists) # networkxグラフをpyvisグラフに変換 g = Network() # g = Network(notebook=True, height="750px", width="100%") g.from_nx(G) # 確認 g.edges |
[{‘from’: ‘ZN’, ‘to’: ‘CRIM’, ‘weight’: -0.20046921966254821},
{‘from’: ‘ZN’, ‘to’: ‘INDUS’, ‘weight’: -0.5338281863044747},
…
{‘from’: ‘B’, ‘to’: ‘PRICE’, ‘weight’: 0.33346081965706653},
{‘from’: ‘LSTAT’, ‘to’: ‘PRICE’, ‘weight’: -0.7376627261740143}]
エッジリストのフォーマットが上記のように変換されます。 ‘PRICE’ ⇒ ‘LSTAT’ のweight(相関係数)は約-0.74という定義です。
相関関係からは矢印の向きは分かりません。なので、可視化するときは有向グラフではなく、無向グラフを採用します
weightに応じて、エッジの太さを変更
先ほど作成した、pyvisグラフを出力しても良いのですが、weightに応じてエッジ太さ(width)を調整した方が、相関関係の強弱が際立ちます。
1 2 3 4 5 6 7 8 9 |
# weightに応じて、エッジの太さを変更 for i, edge in enumerate(g.edges): if abs(edge['weight']) > 0.5: g.edges[i]['width'] = abs(edge['weight']) * 10.0 else: g.edges[i]['width'] = 0.0 # 確認 g.edges |
今回は相関係数の絶対値が0.5以上のエッジを強調してみます。
インタラクティブなグラフをhtmlで保存
作成したグラフをhtmlで保存します。
1 2 3 4 5 6 |
# ボタンやバーなどのGUIを有効にする g.show_buttons(filter_=['physics', 'nodes']) # 一部の機能のみ使用 # g.show_buttons(True) # 全機能使用 # グラフをhtmlで出力 g.show("boston-corr.html") |
適当なブラウザ(Chromeなど)で”boston-corr.html”を開けば、以下のようにグラフをぐりぐり動かせます。
相関関係をインタラクティブなグラフで可視化してみた pic.twitter.com/5pmkV1vPEu
— はやぶさ@技術ノート (@Cpp_Learning) February 6, 2021
※冒頭で見せたものと同じです
みたいなデータ分析結果のプレゼンが捗りますね。
htmlファイルなら、pythonコードの提供や環境構築不要でインタラクティブなグラフを共有できるのも嬉しいですね。
今回作成したグラフ(boston-corr.html)を公開するので、自由に触ってみて下さい(*・ω・)ノ♪
まとめ
相関係数をインタラクティブなグラフで可視化する方法を紹介しました。データ分析やプレゼン資料作成などの参考になれば嬉しいです。
グラフの見せ方ひとつで印象がガラッと変わります。自分が本当に伝えたいことが伝わらないのは勿体ないです(><)
分析手法も重要ですが、データの可視化デザインや見せ方を工夫することも重要ですね。
おまけ -因果推論と可視化について-
本記事で説明していた…
ってどういう意味?気になって昼寝できない!フクロウなので!!
原因⇒結果の関係は因果関係と呼ばれています。相関関係≠因果関係なので、相関のみでは、矢印の向きは分かりません。因果関係を把握するには、因果推論が強力な武器になります。
因果推論入門におすすめ本は以下の記事で紹介中なので、ご参考までに。
以下の記事をオススメしておきますね。
あと使ったことないけど、ネットワークの可視化なら netwulf も良さそうでした。
(完)