【Python】Zachary Karate Clubデータセットの使い方を解説

Zachary Karate Clubデータセットは、グラフ構造を有するデータセットの中で世界で最も有名なものの1つです。1977年にWayne W. Zacharyが空手クラブのメンバー間の交友関係を調査して作成したもので、グラフニューラルネットワーク(GNN)やコミュニティ検出のベンチマークとして広く利用されています。

本記事では、PythonでZachary Karate Clubデータセットをネットワーク可視化ライブラリのNetworkXおよびPyTorch Geometric(PyG)を用いて読み込み、可視化する方法を解説します。

本記事の内容

  • Zachary Karate Clubデータセットの概要
  • NetworkXを用いた読み込みと可視化
  • PyTorch Geometric(PyG)を用いた読み込み
  • グラフの基本的な統計量の計算

前提知識

この記事を読む前に、以下の記事を参考にしてください。

Zachary Karate Clubとは

Zachary Karate Clubは、ある大学の空手クラブにおける34人のメンバー間の友人関係をグラフとして表現したデータセットです。

  • ノード数: 34(メンバー)
  • エッジ数: 78(友人関係)
  • クラブは最終的に、インストラクター(Mr. Hi)派とクラブ会長(Officer)派の2つに分裂

この分裂によるコミュニティ構造が真のラベルとして利用でき、ノード分類やコミュニティ検出のベンチマークに適しています。

NetworkXを用いた方法

NetworkXにはZachary Karate Clubが組み込みデータセットとして用意されています。

import numpy as np
import matplotlib.pyplot as plt
import networkx as nx

# --- データの読み込み ---
G = nx.karate_club_graph()

print(f"ノード数: {G.number_of_nodes()}")
print(f"エッジ数: {G.number_of_edges()}")
print(f"平均次数: {2 * G.number_of_edges() / G.number_of_nodes():.2f}")

# クラブのラベル(Mr. Hi派 or Officer派)
club_labels = [G.nodes[i]['club'] for i in G.nodes()]
color_map = ['red' if label == 'Mr. Hi' else 'blue' for label in club_labels]

# --- グラフの可視化 ---
fig, axes = plt.subplots(1, 2, figsize=(16, 6))

# Spring Layout
ax1 = axes[0]
pos_spring = nx.spring_layout(G, seed=42)
nx.draw(G, pos_spring, node_color=color_map, with_labels=True,
        node_size=300, font_size=8, font_color='white',
        edge_color='gray', alpha=0.8, ax=ax1)
ax1.set_title('Spring Layout')

# Kamada-Kawai Layout
ax2 = axes[1]
pos_kk = nx.kamada_kawai_layout(G)
nx.draw(G, pos_kk, node_color=color_map, with_labels=True,
        node_size=300, font_size=8, font_color='white',
        edge_color='gray', alpha=0.8, ax=ax2)
ax2.set_title('Kamada-Kawai Layout')

plt.suptitle('Zachary Karate Club (Red=Mr.Hi, Blue=Officer)', fontsize=14)
plt.tight_layout()
plt.show()

# --- 基本的な統計量 ---
degrees = dict(G.degree())
print(f"\n各ノードの次数:")
for node, deg in sorted(degrees.items(), key=lambda x: x[1], reverse=True)[:5]:
    print(f"  ノード {node}: 次数 {deg}")

# 次数分布
fig, axes = plt.subplots(1, 2, figsize=(12, 4))

ax1 = axes[0]
degree_values = list(degrees.values())
ax1.hist(degree_values, bins=range(min(degree_values), max(degree_values) + 2),
         alpha=0.7, color='steelblue', edgecolor='black')
ax1.set_xlabel('Degree')
ax1.set_ylabel('Count')
ax1.set_title('Degree Distribution')
ax1.grid(True, alpha=0.3)

# 隣接行列のヒートマップ
ax2 = axes[1]
adj_matrix = nx.adjacency_matrix(G).toarray()
ax2.imshow(adj_matrix, cmap='Blues', interpolation='nearest')
ax2.set_xlabel('Node')
ax2.set_ylabel('Node')
ax2.set_title('Adjacency Matrix')

plt.tight_layout()
plt.show()

# クラスタリング係数
clustering = nx.clustering(G)
avg_clustering = nx.average_clustering(G)
print(f"\n平均クラスタリング係数: {avg_clustering:.4f}")
print(f"グラフの直径: {nx.diameter(G)}")
print(f"平均最短経路長: {nx.average_shortest_path_length(G):.4f}")

PyTorch Geometric(PyG)を用いた方法

PyGでもZachary Karate Clubが利用可能です。PyGではグラフデータがDataオブジェクトとして管理されます。

import torch
from torch_geometric.datasets import KarateClub
from torch_geometric.utils import to_networkx

# --- データの読み込み ---
dataset = KarateClub()
data = dataset[0]

print(f"ノード数: {data.num_nodes}")
print(f"エッジ数: {data.num_edges}")
print(f"特徴量の次元: {data.num_node_features}")
print(f"ノード特徴量 x: {data.x.shape}")
print(f"エッジインデックス: {data.edge_index.shape}")
print(f"ラベル y: {data.y}")

# エッジインデックスの構造
print(f"\nエッジインデックスの例(最初の10辺):")
print(f"  送信元: {data.edge_index[0, :10].tolist()}")
print(f"  受信先: {data.edge_index[1, :10].tolist()}")

# PyGのDataオブジェクトをNetworkXグラフに変換して可視化
G_pyg = to_networkx(data, to_undirected=True)

fig, ax = plt.subplots(figsize=(8, 6))
pos = nx.spring_layout(G_pyg, seed=42)
node_colors = data.y.numpy()
nx.draw(G_pyg, pos, node_color=node_colors, cmap=plt.cm.Set3,
        with_labels=True, node_size=300, font_size=8,
        edge_color='gray', alpha=0.8, ax=ax)
ax.set_title('Zachary Karate Club (PyG)')
plt.tight_layout()
plt.show()

PyGのDataオブジェクトには、ノード特徴量 x、エッジインデックス edge_index、ラベル y がまとめて格納されており、GNNの入力としてそのまま利用できます。

まとめ

本記事では、PythonでZachary Karate Clubデータセットを利用する方法を解説しました。

  • Zachary Karate Clubは34ノード、78エッジのグラフデータセットで、コミュニティ検出のベンチマークとして広く利用されている
  • NetworkXではnx.karate_club_graph()で簡単に読み込み、可視化できる
  • PyTorch GeometricではKarateClub()クラスで読み込み、GNNの入力データとして利用可能
  • グラフの次数分布、クラスタリング係数、隣接行列などの基本統計量を簡単に計算できる

次のステップとして、以下の記事も参考にしてください。