从"猜你喜欢"到精准推荐:用PyG构建电商图神经网络推荐系统
【免费下载链接】pytorch_geometric 项目地址: https://gitcode.com/gh_mirrors/pyt/pytorch_geometric
你是否还在为电商平台推荐系统的"千人一面"而烦恼?用户流失率高、转化率低、用户体验差——这些问题可能都源于传统推荐算法无法捕捉用户与商品间的复杂关系。本文将带你从零开始,使用PyTorch Geometric(PyG)构建一个基于图神经网络(GNN)的个性化推荐系统,解决数据稀疏性和冷启动难题,让你的推荐真正做到"千人千面"。
读完本文,你将掌握:
- 如何将电商数据建模为异构图(Heterogeneous Graph)
- 使用PyG的异构图神经网络(HeteroGNN)捕捉复杂关系
- 实现时间感知的推荐系统以应对动态用户行为
- 评估推荐系统性能的关键指标与优化方法
电商推荐的痛点与图神经网络的优势
传统推荐算法如协同过滤(Collaborative Filtering)和矩阵分解(Matrix Factorization)存在两大致命缺陷:数据稀疏性和无法建模复杂关系。当用户-商品交互数据稀疏时,这些算法的推荐效果会急剧下降。而图神经网络(GNN)通过将用户、商品、类别等实体建模为图中的节点,将它们之间的交互建模为边,能够自然地捕捉实体间的多跳关系和高阶依赖。
PyTorch Geometric(PyG)是一个基于PyTorch的图神经网络库,提供了丰富的图数据处理工具和GNN模型实现。其中,异构图处理能力使其特别适合电商推荐场景,因为电商系统天然包含多种类型的实体(用户、商品、类别、品牌等)和关系(购买、点击、收藏、评价等)。
构建电商推荐系统的核心步骤
1. 数据建模:将电商数据转换为图结构
在推荐系统中,我们通常将数据建模为异构图。以MovieLens数据集为例,我们可以创建包含"用户"(user)和"商品"(movie)两种节点类型,以及"购买"或"评分"(rates)一种边类型的异构图。
PyG提供了HeteroData类来表示异构图数据。以下是构建用户-商品交互图的核心代码:
# 加载MovieLens数据集
path = osp.join(osp.dirname(osp.realpath(__file__)), '../../data/MovieLens')
data = MovieLens(path, model_name='all-MiniLM-L6-v2')[0]
# 添加用户节点特征
data['user'].x = torch.eye(data['user'].num_nodes)
# 只保留高分评价(>=4分)作为有效交互
mask = data['user', 'rates', 'movie'].edge_label >= 4
data['user', 'movie'].edge_index = data['user', 'movie'].edge_index[:, mask]
# 添加反向边以支持消息传递
data = T.ToUndirected()(data)
这段代码来自examples/hetero/recommender_system.py,它展示了如何从原始数据构建异构图,包括节点特征处理、边过滤和图转换等关键步骤。
2. 模型构建:异构图神经网络的实现
在PyG中,我们可以使用to_hetero函数将普通GNN模型转换为适用于异构图的模型。以下是一个基于GraphSAGE的异构图推荐模型:
class GNN(torch.nn.Module):
def __init__(self, hidden_channels):
super().__init__()
self.conv1 = SAGEConv((-1, -1), hidden_channels)
self.conv2 = SAGEConv((-1, -1), hidden_channels)
self.conv3 = SAGEConv((-1, -1), hidden_channels)
def forward(self, x, edge_index):
x = self.conv1(x, edge_index).relu()
x = self.conv2(x, edge_index).relu()
x = self.conv3(x, edge_index)
return x
class Model(torch.nn.Module):
def __init__(self, hidden_channels):
super().__init__()
self.encoder = GNN(hidden_channels)
# 将GNN转换为异构图模型
self.encoder = to_hetero(self.encoder, data.metadata(), aggr='sum')
self.decoder = InnerProductDecoder()
def forward(self, x_dict, edge_index_dict, edge_label_index):
x_dict = self.encoder(x_dict, edge_index_dict)
return self.decoder(x_dict, edge_label_index)
这里,SAGEConv是GraphSAGE模型的卷积层,to_hetero函数将普通GNN转换为能够处理多种节点和边类型的异构图模型。解码器InnerProductDecoder通过计算用户和商品嵌入的内积来预测它们之间的交互分数。
3. 时间感知的推荐:处理动态用户行为
用户行为是动态变化的,一个好的推荐系统应该能够考虑时间因素。PyG提供了时间感知的数据加载器,支持基于时间的训练-测试拆分和采样。
# 按时间排序交互数据
perm = time.argsort()
train_index = perm[:int(0.8 * perm.numel())]
test_index = perm[int(0.8 * perm.numel()):]
# 创建时间感知的训练数据加载器
train_loader = LinkNeighborLoader(
edge_label_index=(('user', 'movie'), edge_label_index[:, train_index]),
edge_label_time=time[train_index] - 1, # 避免数据泄露
neg_sampling=dict(mode='binary', amount=2),
shuffle=True,
data=data,
num_neighbors=[5, 5, 5],
batch_size=256,
time_attr='time',
temporal_strategy='last',
)
这段代码实现了基于时间的数据集拆分,并使用LinkNeighborLoader创建了时间感知的训练数据加载器。通过time_attr参数指定时间属性,temporal_strategy='last'确保在采样时只使用给定时间点之前的交互数据,避免未来信息泄露。
4. 模型训练与评估
训练推荐模型与训练普通GNN模型类似,使用二元交叉熵损失函数(BCEWithLogitsLoss)优化模型参数:
def train():
model.train()
total_loss = total_examples = 0
for batch in tqdm(train_loader):
batch = batch.to(device)
optimizer.zero_grad()
out = model(batch.x_dict, batch.edge_index_dict, batch['user', 'movie'].edge_label_index)
y = batch['user', 'movie'].edge_label
loss = F.binary_cross_entropy_with_logits(out, y)
loss.backward()
optimizer.step()
total_loss += float(loss) * y.numel()
total_examples += y.numel()
return total_loss / total_examples
评估推荐系统性能时,我们通常关注准确率(Precision)、召回率(Recall)和平均精度均值(MAP)等指标。PyG提供了LinkPredPrecision、LinkPredRecall和LinkPredMAP等评估指标的实现:
@torch.no_grad()
def test(edge_label_index, exclude_links):
model.eval()
# 收集商品嵌入
dst_embs = []
for batch in dst_loader:
batch = batch.to(device)
emb = model.encoder(batch.x_dict, batch.edge_index_dict)['movie']
dst_embs.append(emb[:batch['movie'].batch_size])
dst_emb = torch.cat(dst_embs, dim=0)
# 构建MIPS k-NN索引
mips = MIPSKNNIndex(dst_emb)
# 初始化评估指标
map_metric = LinkPredMAP(k=args.k).to(device)
precision_metric = LinkPredPrecision(k=args.k).to(device)
recall_metric = LinkPredRecall(k=args.k).to(device)
# 计算用户嵌入并评估
for batch in src_loader:
batch = batch.to(device)
emb = model.encoder(batch.x_dict, batch.edge_index_dict)['user']
emb = emb[:batch['user'].batch_size]
# k-NN搜索与指标更新
_, pred_index_mat = mips.search(emb, args.k, _exclude_links)
map_metric.update(pred_index_mat, _edge_label_index)
precision_metric.update(pred_index_mat, _edge_label_index)
recall_metric.update(pred_index_mat, _edge_label_index)
return float(map_metric.compute()), float(precision_metric.compute()), float(recall_metric.compute())
系统优化与最佳实践
1. 采样策略优化
PyG提供了多种采样策略来处理大规模图数据。在推荐系统中,常用的采样策略包括:
- 邻居采样:通过
NeighborLoader或LinkNeighborLoader采样邻居节点,控制子图大小 - 时间感知采样:使用
temporal_strategy参数确保推荐系统考虑时间因素 - 负采样:通过
neg_sampling参数生成负样本,平衡正负样本比例
合理的采样策略可以在保证模型性能的同时,显著提高训练效率。
2. 多GPU训练
对于大规模电商数据集,单GPU训练可能无法满足需求。PyG提供了多种分布式训练方案,包括数据并行和模型并行。以下是使用数据并行的示例:
# 数据并行示例
model = torch.nn.DataParallel(model)
更高级的分布式训练可以参考examples/multi_gpu/目录下的示例代码,包括分布式采样、多节点训练等高级用法。
3. 评估指标选择
推荐系统的评估指标选择应根据具体业务场景而定:
- Precision@k:前k个推荐中有多少是用户真正感兴趣的,适用于关注推荐精准度的场景
- Recall@k:用户感兴趣的商品中有多少被推荐系统捕捉到,适用于关注覆盖率的场景
- MAP@k:平均精度均值,综合考虑排序质量,适用于需要精准排序的场景
在实际应用中,通常需要综合多个指标来全面评估推荐系统性能。
总结与展望
本文详细介绍了如何使用PyTorch Geometric构建电商个性化推荐系统,包括数据建模、模型构建、训练评估和系统优化等关键步骤。通过将电商数据建模为异构图,并使用异构图神经网络捕捉实体间的复杂关系,我们可以显著提升推荐系统的准确性和用户满意度。
PyG提供了丰富的工具和示例代码来支持推荐系统开发,关键资源包括:
- 官方文档:docs/source/index.rst
- 推荐系统示例:examples/hetero/recommender_system.py
- 异构图处理:torch_geometric/data/hetero_data.py
- 评估指标:torch_geometric/metrics/
未来,随着图神经网络技术的不断发展,我们可以期待更先进的模型(如GAT、PNA等)在推荐系统中的应用,以及更高效的训练方法和更丰富的评估指标。如果你对构建个性化推荐系统感兴趣,不妨从PyG的examples/hetero/recommender_system.py示例开始,探索图神经网络在推荐系统中的无限可能!
希望本文对你构建电商推荐系统有所帮助!如果你有任何问题或建议,欢迎在评论区留言。别忘了点赞、收藏本文,关注我们获取更多PyG实战教程!下一篇,我们将探讨如何将知识图谱融入推荐系统,进一步提升推荐质量。
【免费下载链接】pytorch_geometric 项目地址: https://gitcode.com/gh_mirrors/pyt/pytorch_geometric
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考



