三亩地 三亩地SAN MU DI · CODE DIARY
ARTICLE DETAIL

日记详情

真实记录编程学习的某一天,欢迎挑你感兴趣的翻一翻。

用NetworkX和PyG玩转空手道俱乐部数据集:从社交网络到GCN实战

用NetworkX和PyG玩转空手道俱乐部数据集:从社交网络到GCN实战

用NetworkX和PyG玩转空手道俱乐部数据集:从社交网络到GCN实战

在探索图神经网络(GNN)的旅程中,找到一个合适的入门数据集就像获得一把打开新世界的钥匙。Zachary's karate club dataset正是这样一把钥匙——它不仅结构简单、易于理解,还蕴含着丰富的社交网络特性,堪称图数据分析领域的"Hello World"。本文将带你用Python两大主流库NetworkX和PyTorch Geometric(PyG),从不同角度把玩这个经典数据集,最终实现一个极简的图卷积网络(GCN)分类任务。

1. 认识空手道俱乐部数据集

1977年,人类学家Wayne Zachary发表了一项有趣的研究:他观察了一个大学空手道俱乐部的社交关系,记录了34名成员之间的互动。当俱乐部因管理矛盾分裂时,Zachary惊人地发现,仅凭成员间的社交关系就能预测他们最终会加入哪个阵营。

这个数据集之所以经典,在于它完美展现了现实世界社交网络的几个关键特性:

  • 小世界特性:大多数成员之间只需通过少数中间人就能建立联系
  • 社区结构:数据天然包含两个明显社群(后来分裂的两个阵营)
  • 稀疏连接:78条边意味着平均每个成员只与4-5人直接互动
# 数据集基本信息速览 节点数 = 34 边数 = 78 特征维度 = 34 类别数 = 2 (原始)/4 (PyG处理版)

2. NetworkX基础操作指南

NetworkX作为Python图分析的标准库,提供了最直观的数据处理方式。让我们从创建图对象开始:

2.1 数据加载与基础属性

import networkx as nx # 加载空手道俱乐部数据 G = nx.karate_club_graph() # 查看图的基本信息 print(f"节点数: {G.number_of_nodes()}") print(f"边数: {G.number_of_edges()}") print(f"节点属性: {list(G.nodes[0].keys())}")

关键属性说明:

属性说明示例值
club节点所属阵营'Mr. Hi' 或 'Officer'
degree节点度数0-17之间的整数

2.2 可视化与社区发现

NetworkX内置的绘图功能虽简单,但能快速呈现网络结构:

import matplotlib.pyplot as plt # 按club属性着色 color_map = [] for node in G: if G.nodes[node]['club'] == 'Mr. Hi': color_map.append('orange') else: color_map.append('skyblue') # 绘制网络图 plt.figure(figsize=(10,8)) nx.draw_spring(G, node_color=color_map, with_labels=True) plt.show()

可视化时你会发现:

  • 节点0(Mr. Hi)和节点33(Officer)是网络的两个中心
  • 橙色和蓝色节点已初步形成两个群落
  • 少数节点位于两个群落交界处(正是这些节点后来分类预测出错)

3. PyG中的高级图表示

PyTorch Geometric(PyG)为图神经网络提供了专业支持,其对空手道俱乐部数据做了深度处理:

3.1 数据加载与结构解析

from torch_geometric.datasets import KarateClub dataset = KarateClub() data = dataset[0] print(data)

PyG版数据包含以下关键组件:

属性形状说明
x[34, 34]节点特征矩阵(独热编码)
edge_index[2, 156]边索引(无向边存储为双向)
y[34]节点标签(4分类)
train_mask[34]训练集掩码

3.2 数据预处理技巧

PyG版本相比原始数据有几个重要改进:

  1. 特征工程:使用34维独热编码替代原始的无特征设计
  2. 标签扩展:将二分类扩展为基于模块度的4分类
  3. 训练划分:每类选取一个节点作为监督信号
# 查看训练集划分 print(f"训练节点索引: {data.train_mask.nonzero().squeeze().tolist()}") print(f"对应标签: {data.y[data.train_mask].tolist()}")

4. 极简GCN分类实战

现在让我们用PyG构建一个微型GCN模型,体验图神经网络的魅力:

4.1 模型构建

import torch import torch.nn.functional as F from torch_geometric.nn import GCNConv class GCN(torch.nn.Module): def __init__(self): super().__init__() self.conv1 = GCNConv(dataset.num_features, 4) self.conv2 = GCNConv(4, dataset.num_classes) def forward(self, data): x, edge_index = data.x, data.edge_index x = self.conv1(x, edge_index) x = F.relu(x) x = F.dropout(x, training=self.training) x = self.conv2(x, edge_index) return F.log_softmax(x, dim=1)

模型架构说明:

输入层(34) → GCN层(4) → ReLU → Dropout → GCN层(4) → LogSoftmax

4.2 训练与评估

device = torch.device('cuda' if torch.cuda.is_available() else 'cpu') model = GCN().to(device) data = data.to(device) optimizer = torch.optim.Adam(model.parameters(), lr=0.01) model.train() for epoch in range(200): optimizer.zero_grad() out = model(data) loss = F.nll_loss(out[data.train_mask], data.y[data.train_mask]) loss.backward() optimizer.step()

训练完成后,我们可以可视化节点的嵌入表示:

model.eval() out = model(data) visualize(out, color=data.y)

你会观察到:

  • 相同颜色的节点在嵌入空间聚集
  • 四个类别形成了相对独立的簇
  • 部分边界节点仍存在混淆

5. 双库对比与进阶思考

通过NetworkX和PyG的不同视角,我们对同一数据集有了立体认识:

特性NetworkXPyG
数据获取nx.karate_club_graph()KarateClub()
图类型无向、无权无向、带特征
节点特征无34维独热编码
标签系统二分类(club属性)四分类(模块度)
主要用途网络分析、可视化图神经网络训练

这个简单数据集仍有许多可探索方向:

  • 尝试不同的GNN架构(GAT、GraphSAGE等)
  • 对比有监督与无监督学习效果
  • 研究不同特征工程对结果的影响
  • 探索社区发现算法的应用

在实际项目中遇到类似的小规模社交网络时,不妨回想这个经典案例——它教会我们,即使最简单的图结构也能蕴含丰富的信息,而选择合适的工具才能充分挖掘这些价值。

← 返回列表