はじめに
Zachary’s Karate Clubやスター型ネットワークなどで違いを実感する
背景・目的
-
ネットワーク解析
- SNSのユーザー関係や交通路など、ノードとエッジで表せる事象を可視化・分析する手法
-
中心性指標
- ネットワーク内で「重要なノード」を定量的に示す指標
- 代表的なものとして Degree / Betweenness / Closeness がある
本記事では、Google Colab で Python (NetworkX) を使いながら、簡単に中心性指標を計算する方法を紹介します。
特に「Zachary’s Karate Club」データセットや、小規模ネットワーク(スター型・ライン型など)を例に挙げることで、違いがより実感しやすくなる点に注目します。
1. 代表的な中心性指標
1-1. Degree Centrality(次数中心性)
-
意味
- あるノードの直接のつながり(エッジ数)の多さに基づいて重要度を評価
-
数式(無向グラフの場合)
- (\text{DegreeCentrality}(v) = \frac{\text{deg}(v)}{N - 1})
- (\text{deg}(v)):ノード (v) の次数(つながりの数)
- (N):ノード総数
-
使いどころ
- SNSでフォロワー数が多いユーザーを見つける
- 被引用数が多い論文を見つける
- とにかく「直接つながりの多さ」が重要視される文脈に適している
1-2. Betweenness Centrality(媒介中心性)
-
意味
- あるノードが「他のノード間の最短経路をどれだけ媒介しているか」に注目
-
数式(概要)
- (\text{BetweennessCentrality}(v) = \sum_{s \neq t}\frac{\sigma_{s,t}(v)}{\sigma_{s,t}})
- (\sigma_{s,t}):ノード (s) から (t) への最短経路の総数
- (\sigma_{s,t}(v)):その最短経路のうちノード (v) を通る本数
-
使いどころ
- ネットワークの分断を防ぐ「橋渡し役(ハブ)」を見つける
- SNSで複数コミュニティをまたぐ影響力のあるユーザーを特定
- 交通ネットワークで渋滞の起点になりやすい場所を把握
1-3. Closeness Centrality(近接中心性)
-
意味
- あるノードが他の全てのノードにどれだけ近いか(=最短距離の合計が小さいか)に注目
-
数式(無向グラフの場合)
- (\text{ClosenessCentrality}(v) = \frac{N-1}{\sum_{t} d(v, t)})
- (d(v, t)):ノード (v) と (t) 間の最短距離
- (N):ノード総数
-
使いどころ
- ネットワーク全体の「中心にいる」ノードを抽出
- 連絡や情報が最も効率的に行き届く位置を知る
2. Google Colabでの実践:Zachary’s Karate Club
2-1. データセット概要
- アメリカの大学の空手クラブにおけるメンバー間の人間関係ネットワーク
- 1977年の Wayne Zachary による有名な研究データ
- メンバーの対立が原因でクラブが分裂した経緯があり、コミュニティ構造の例としてよく使われる
2-2. サンプルプログラム
以下のコードをGoogle Colabに貼り付けて実行してください。
# ============================
# 1. ライブラリのインストールとインポート
# ============================
!pip install networkx
import networkx as nx
import matplotlib.pyplot as plt
%matplotlib inline
# ============================
# 2. Zachary’s Karate Club グラフを取得
# ============================
G = nx.karate_club_graph()
# ============================
# 3. 中心性指標を計算
# ============================
degree_dict = nx.degree_centrality(G)
betweenness_dict = nx.betweenness_centrality(G)
closeness_dict = nx.closeness_centrality(G)
# 上位5ノードだけ表示してみる
print("Degree Centrality (上位5件):")
for node, cent in sorted(degree_dict.items(), key=lambda x: x[1], reverse=True)[:5]:
print(f" Node {node}: {cent:.4f}")
print("\nBetweenness Centrality (上位5件):")
for node, cent in sorted(betweenness_dict.items(), key=lambda x: x[1], reverse=True)[:5]:
print(f" Node {node}: {cent:.4f}")
print("\nCloseness Centrality (上位5件):")
for node, cent in sorted(closeness_dict.items(), key=lambda x: x[1], reverse=True)[:5]:
print(f" Node {node}: {cent:.4f}")
# ============================
# 4. ネットワークの可視化
# ============================
pos = nx.spring_layout(G, seed=42)
plt.figure(figsize=(8, 6))
nx.draw_networkx_nodes(G, pos, node_size=400, node_color='lightblue')
nx.draw_networkx_edges(G, pos, width=1, alpha=0.7)
nx.draw_networkx_labels(G, pos, font_size=10, font_color='black')
plt.axis('off')
plt.show()
2-3. 実行結果のポイント
-
Degree Centrality
- ノード(0, 33など)が高い値を示すことが多い。クラブの中心人物として、直接多くのメンバーとつながっている。
-
Betweenness Centrality
- ネットワーク分断の橋渡しをしているノード(33, 0など)が上位に来る。
-
Closeness Centrality
- 全体に距離が短いノード(1, 2, 3あたりなど)も上位に入ることがある。
ここから「誰がたくさんの人と繋がっているか」「誰がネットワークの橋渡しをしているか」「誰が全体へアクセスしやすい位置にいるか」が見えてきます。
3. 小規模ネットワーク例で比較
Zachary’s Karate Clubはそこそこ規模がありますが、さらに直感を得たい場合はスター型やライン型など極端な構造を作ってみると、指標の違いがより分かりやすくなります。
3-1. スター型ネットワーク
- 中心ノードひとつを軸に、他ノードが直接つながる
-
中心ノード
- Degree Centralityが圧倒的に高い
- Betweenness Centralityでもほぼ全経路を仲介するので高い
- Closeness Centralityでも、全ノードから距離1でアクセスできるため高い
3-2. ライン型ネットワーク
- ノードが直線状に並び、隣接ノードのみ接続
-
中央ノード
- Degree Centralityは両端以外は同じか少し高め
- Betweenness Centralityは中央ノードが経路を多く通過するため高い
- Closeness Centralityも中央に近いノードほど全体へ距離が小さくなるので高い
3-3. クリーク型ネットワーク(完全グラフ)
- すべてのノードが互いに直接つながっている状態
-
どのノードも同じ値
- Degree Centralityは全ノードが同数のエッジを持つ
- Betweenness Centralityはすべてのノードが最短経路で等価
- Closeness Centralityも全ノードが最短距離1で全ての他ノードにアクセス可能
4. まとめ
- Degree:直接の繋がり数に注目
- Betweenness:他ノード間をどれだけ「媒介」しているかを測る
- Closeness:全ノードとの距離(近さ)を総合的に評価
主なポイント
- どの指標も「ネットワーク内での重要度」を示すが、着目する観点が異なる
- Zachary’s Karate Club のような現実っぽいデータセットで試すと、コミュニティ構造との関連が見えて面白い
- スター型・ライン型・クリーク型など極端な構造を自作することで、指標の動きをより直感的に理解しやすい
実際にコードを動かしてみながら「どのノードが上位に来るのか」を眺めてみると、ネットワーク解析の面白さを実感いただけると思います。