いろいろ倉庫

KNIME、EXCEL、R、Pythonなどの備忘録

【Python】ネットワークの中の大事なノードを見つけたい

・お題:先日、ネットワークの図を描いてみた。たくさんあるノードの中で、どれが大事っぽいのか推定してみたい。

 

・大事さと私がイメージしていることは、ネットワーク界隈では中心性と呼ぶらしい。私の「大事さ」はぼんやりとしたイメージだけれど、「中心性」にはたくさんの定義と種類が存在する。

・以下の記事で詳しく解説されていた。ぜひそちらをご参照いただきたい。

qiita.com

qiita.com

yamaguchiyuto.hatenablog.com

・試しにやってみる。まず、データセットを作成する。

import numpy as np
np.random.seed(2)

edges=[("A","B"),
       ("A","C"),
       ("A","D"),
       ("A","E"),
       ("A","F"),
       ("F","G"),
       ("F","H"),
       ("F","I"),
       ("H","I"),
       ("I","J"),
       ("I","K"),
       ("I","L"),
       ("I","M"),
       ("G","O"),
       ("G","P")]
edges1=[]
for n in range(len(edges)):
    edges1.append( (edges[n][0], edges[n][1], abs(np.random.normal(3, 4) ) ) )

・これでエッジリストedges1が以下のような感じになる。。

[('A', 'B', 1.3329686103781175),
 ('A', 'C', 2.774932691094682),
 ('A', 'D', 5.544784382673816),
 ('A', 'E', 9.561083233619954),
 ('A', 'F', 4.1737423407794525),
 ('F', 'G', 0.366989462624816),

......

・次に、ネットワークに読み込んでこれを図示。これでもなんとなくAとIを大事にしたくなる。

import networkx as nx
G1 = nx.Graph()
G1.add_weighted_edges_from(edges1)

%matplotlib inline
import matplotlib.pyplot as plt
pos = nx.spring_layout(G1, k=0.2)

nx.draw_networkx_edges(G1, pos, edge_color="gray",width=[n[2] for n in edges1], alpha=0.5)
nx.draw_networkx_nodes(G1, pos,node_color="white",edgecolors="gray")
nx.draw_networkx_labels(G1, pos)
plt.show()

・次に、それぞれの中心性を求める。いろいろな中心性を算出してみる。

dc=nx.degree_centrality(G1)
cc=nx.closeness_centrality(G1)
bc=nx.betweenness_centrality(G1)
ec=nx.eigenvector_centrality(G1)
pr=nx.pagerank(G1)
Centralities={"Degree Centrality":dc,
       "Closeness Centrality":cc,
       "Betweenness Centrality":bc,
       "Eigenvector Centrality":ec,
       "PageRank":pr}

・中身を見てみると、こんな感じ。確かになんだか違う。

import pandas as pd
pd.DataFrame(Centralities)

・例えば、Degree Centralityを可視化してみる。

Centralitiey="Degree Centrality"

plt.figure(figsize=(5, 5))
nx.draw_networkx_edges(G1, pos, edge_color="gray", width=[n[2] for n in edges1],alpha=0.5)
nx.draw_networkx_nodes(G1, pos, node_color=list(Centralities[Centralitiey].values()), cmap=plt.cm.Reds,edgecolors="gray",alpha=0.6)
nx.draw_networkx_labels(G1, pos)
plt.title(Centralitiey)

plt.show()

・次に、PageRankも可視化してみる。PageRankを無向グラフに適用するのが正しいのかよく分からない(有向グラフで使われているイメージを私は持っている)が、以下のようになった。

Centralitiey="RageRank"

plt.figure(figsize=(5, 5))
nx.draw_networkx_edges(G1, pos, edge_color="gray", width=[n[2] for n in edges1],alpha=0.5)
nx.draw_networkx_nodes(G1, pos, node_color=list(Centralities[Centralitiey].values()), cmap=plt.cm.Reds,edgecolors="gray",alpha=0.6)
nx.draw_networkx_labels(G1, pos)
plt.title(Centralitiey)

plt.show()

・参考として、Page RankのWikipediaも貼っておく。

ja.wikipedia.org

・原理を理解し、必要な時に必要な手法を適用できると判断できるのが大事なんだけれど、それが難しい。。

 

 

おわり。