📊

pyvis ネットワーク図を使って分かりやすく因果分析したい!

2022/03/22に公開

【python】pyvisを使ってみる。
アンケート分析等、複数の要素から因果関係を見つけるのって大変ですよね。相関係数から繋がりを説明することもできますが、グラフを使って可視化すれば分かりやすくなるはず。

もくじ

  1. 環境
  2. モジュールのインポートと分析するデータの読み込み
  3. (参考)相関係数を求め、ヒートマップを作成します。
  4. エッジリストの作成(相関係数と思ってください。)
  5. networkxグラフを作り、pyvisグラフに変換
  6. pyvisでインタラクティブなグラフを表示

1.環境

anaconda
jupyterLab 32.9
データ:hitoe(TX02)から取得した心拍、湿度、体温のデータ(2回分を並べています。)を使っています。
デスクトップ上にtestフォルダを作りその中にtest.csvという名前で保存しています。
ユーザ:user1

2.モジュールのインポートと分析するデータの読み込み

# pyvisのインストール
pip install pyvis

# モジュールのインポート
import pandas as pd
import seaborn as sns
import numpy as np
import matplotlib.pyplot as plt
import networkx as nx
from pyvis.network import Network

# データの読み込み
in_file = "C:\\Users\\user1\\Desktop\\test\\test.csv" 
df = pd.read_csv(in_file)

df にうまくtest.csvが定義されたか確認

df.head()

こんなふうに出力されました。

3.(参考)相関係数を求め、ヒートマップを作成します。

相関係数を求めてみます。

# 相関係数を求める。
df_corr = df.corr()

# 右上の三角行列をマスクする。
mask_df = df_corr.mask(np.triu(np.ones(df_corr.shape)).astype(bool), None)

# 出力してみます。
mask_df

黄色い網掛け部分がマスクされたところです。

ヒートマップも作ってみます。

# 相関をヒートマップで可視化
plt.figure(figsize=(10,5))

sns.heatmap(df_corr, # データ
            vmin=-1, vmax=1, # 範囲
            annot=True, fmt='0.2f', # 数値表示
            cmap=sns.color_palette('coolwarm', 100), # 色指定
            # square=True, # ヒートマップを正方形で表示
            );

こんな感じになります。

4.エッジリストの作成(相関係数と思ってください。)

# エッジリストを生成します。
edge_lists = mask_df.stack().reset_index().apply(tuple, axis=1).values
 
# 確認してみます。
edge_lists

array([('program', 'pc', 0.15075567228888176),
('people', 'pc', -0.06579516949597687),
('people', 'program', -0.07273929674533083)], dtype=object)
エッジリストの中身は上記の通りで、例えば ‘people’ と ‘program’ の相関係数は約-0.072…のようです。

5.networkxグラフを作り、pyvisグラフに変換

# 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

[{'weight': 0.15075567228888176, 'from': 'program', 'to': 'pc'},
{'weight': -0.07273929674533083, 'from': 'program', 'to': 'people'},
{'weight': -0.06579516949597687, 'from': 'pc', 'to': 'people'}]

weightが付きましたね。
次に相関係数の絶対値が0.1以上のエッジを強調してみます。

# weightに応じて、エッジの太さを変更します。
for i, edge in enumerate(g.edges):
    if abs(edge['weight']) > 0.1:
        g.edges[i]['width'] = abs(edge['weight']) * 10.0
    else:
        g.edges[i]['width'] = 0.0

# 確認してみます。
g.edges

[{'weight': 0.15075567228888176,
'from': 'program',
'to': 'pc',
'width': 1.5075567228888176},
{'weight': -0.07273929674533083,
'from': 'program',
'to': 'people',
'width': 0.0},
{'weight': -0.06579516949597687, 'from': 'pc', 'to': 'people', 'width': 0.0}]

6. pyvisでインタラクティブなグラフを表示

# ボタンやバーなどのGUIを有効にします。
g.show_buttons(filter_=['physics', 'nodes'])  # 一部の機能のみ使用
# g.show_buttons(True)   # 全機能使用

# グラフをhtmlで表示します。
g.show("test.html")

こちらが完成したグラフです。
[pc]と[program]の相関が強そうだということが、一目で分かります。エッジ部分を持って引っ張ると、相関の強い項目も動くので、もっと複雑なデータで試してみると面白いと思います!

参考

https://pyvis.readthedocs.io/en/latest/tutorial.html

Discussion