RippleNet: Propagating User Preferences on the Knowledge Graph for Recommender Systems

1.知识图谱嵌入的基本过程,为什么难以直观有效表达项目间的关系

1.1基本过程(知识图谱嵌入)

  • 构建三元组: 将知识图谱表示为(头实体h, 关系r, 尾实体t)集合。

  • 向量化建模: 为每个实体、关系分配可学习的向量/矩阵,常见范式如TransE(h+r≈t)、DistMult、ComplEx、RotatE等。

  • 打分函数: 通过模型特定的打分f(h,r,t)衡量三元组合理性(越高越可信)。

  • 负采样训练: 用真实三元组配合构造的假三元组优化排名/交叉熵损失,联合正则化(范数约束、关系正交等)。

  • 推断与下游: 训练好后用打分函数进行链路预测;在推荐中可将实体/关系嵌入与用户行为聚合(或图神经网络)结合,得到可用于召回/排序的表示。

1.2为何难以直观有效表达“项目间关系”

  • 多关系压缩: 一个物品与其他实体通过多种关系相连(类别、品牌、属性、制作人…),嵌入把多语义压缩到固定维度,很难保留清晰、可分解的“哪一种关系导致相似”的解释。

  • 路径可组合性弱: 多跳路径蕴含的组合语义(如“同导演→同题材→同受众”)在简单向量运算中难以保真,导致复杂关联被“糊成”相近但不可解释的距离。

  • 语境依赖丢失: 项目相关性常常依用户/场景而变(同一两物品对不同用户意义不同)。静态嵌入用统一相似度度量(点积/余弦)难以表达这种条件化关系。

  • 目标不一致: KG嵌入多以链路预测为目标,优化“真假三元组可分性”,而推荐需要用户偏好排序与业务可解释性,二者并不等价。

  • 长尾与稀疏: 关系少或冷门物品学到的向量不稳定,近邻关系受噪声主导,难以形成可靠的“项目-项目”语义。

  • 可解释性受限: 高维向量接近并不直接对应可读的关系句子或具体路径,难以给出“为什么这两个项目相关”的直观依据。

2.知识图谱的元路径是什么意思,具体如何通过路径实现推荐

2.1元路径(Meta-path)

在异构信息网络/知识图谱中,用“节点类型→关系类型”的序列定义的一种语义路径模板,描述两类实体之间的关系模式,而非具体数据上的一条边。例如:用户-评分->电影-由->导演-执导->电影(记作 U-R-M-D-M),表示“用户通过共同导演关联到另一部电影”的语义。

2.2如何用路径做推荐

  • 选路径: 依据业务先验或自动搜索,挑选能表达偏好的元路径(如 U-M-U 共同喜好、U-M-A-M 同演员、U-M-T-M 同标签)。

  • 算关联分数: 对每个用户-物品对,在每条元路径下计算“可达性/相似性”作为特征 f_k(u,i)。常见做法:

    • 路径计数: 统计从 u 到 i 的元路径实例条数(可加衰减或去重)。

    • 路径约束随机游走(PCRW): 只沿元路径类型行走,取从 u 抵达 i 的概率。

    • PathSim/HeteSim: 对称路径用 PathSim 比同类节点相似度,异类对(如用户-物品)用 HeteSim 的归一化可达性。

  • 矩阵乘法实现: 为每种关系建邻接矩阵 AR;某元路径 R1→R2→…→RL 的连通强度可由 M = AR1 · AR2 · … · ARL 得到,M[u,i] 即 fk(u,i) 的原始值(再做归一化/平滑)。

  • 融合与排序:

    • 无监督: 设权重 wk,得分 s(u,i) = Σ kwkfk(u,i),wk 可靠验证集调参或启发式设定。

    • 监督学习: 把各 fk 作为特征,喂给 LR/FM/GBDT/神经网络,直接学习点击/评分/转化;或做 pairwise 排序优化 NDCG/HR。

  • 生成Top-N: 对每个用户按 s(u,i) 排序,输出前N个物品,并可附上触发的元路径实例做可解释性说明。

2.3那么为什要选择高质量的元路径,对结果有什么影响吗

  • 好路径:User–Item–Actor–Item(同演员常反映真实偏好传递)

  • 弱路径:User–Item–Publisher–Item(若“出版社”与用户兴趣弱相关,噪声更大)

3.“端到端训练”是什么

端到端训练指用一个统一的可微模型,将从输入到输出的所有步骤放在同一目标函数下,借助反向传播同时学习全部参数。

4.Bag-of-Words(词袋模型)

把文本看作“词的多重集”,忽略语序与语法,仅统计每个词在文本中出现的次数,用一个固定长度向量表示文本。

5.请问第5个公式和第6个公式表示的一阶响应、二阶响应……什么意思

一阶/二阶“响应”:指用户对候选物品在知识图谱上第k跳邻域产生的偏好信号。第1跳为一阶响应,第2跳为二阶响应,依此类推。

6.似然函数的目的

G理解为知识图谱(实体–关系–实体的三元组集合);其“似然函数”是在目标里鼓励模型对真实三元组赋高概率、对采样的负例赋低概率的项。

7.关于代码model.py的疑问

7.1该文件的主要内容

这个 py 文件主要实现了一个基于知识图谱的推荐模型(RippleNet)的 TensorFlow 1.x 版本。核心内容与结构如下:

  • 目标与思路:

    • 用用户在知识图谱上的“涟漪集”(Ripple set,按多跳采样的三元组记忆)增强对候选物品的打分。

    • 通过多跳记忆注意力,把每一跳的头实体 h 经关系 R 映射,与当前物品向量匹配得到注意力,再聚合尾实体 t,逐跳更新物品表示,最终做点积打分并用 sigmoid 得到点击概率。

  • 类结构:

    • __init__ 中依次调用 _parse_args_build_inputs_build_embeddings_build_model_build_loss_build_train,完成参数解析、图构建、损失与训练器设置。

    • 提供 eval 方法计算 AUC 和准确率,get_feed_dict 方法组织喂入数据。

  • 参数解析(_parse_args):

    • 读取维度 dim、跳数 n_hop、每跳记忆数 n_memory、学习率 lr、正则权重 kge_weight/l2_weight、物品更新模式 item_update_mode、是否使用所有跳 using_all_hops,以及实体/关系总数。

  • 输入占位符(_build_inputs):

    • items(候选物品 ID),labels(二分类标签)。

    • 每一跳的 memories_h/r/t(形状 [batch, n_memory]),表示该用户的知识图谱三元组集合。

  • 嵌入(_build_embeddings):

    • entity_emb_matrix:实体嵌入,形状 [n_entity, dim]

    • relation_emb_matrix:关系矩阵,形状 [n_relation, dim, dim](双线性变换)。

    • Xavier 初始化(TF1 的 tf.contrib.layers.xavier_initializer())。

  • 前向计算(_build_model + _key_addressing):

    • 初始物品向量:从实体嵌入查 items 得到 [batch, dim]

    • 对每一跳:

      • 查表得到当前批次的 h、r、t 嵌入。

      • 计算 Rh = R * h,与物品向量做注意力打分并 softmax。

      • 用注意力加权聚合尾实体得到本跳输出 o

      • item_update_mode 更新物品向量(replace/plus/…transform)。

    • 预测向量:使用最后一跳的 o,可选把所有跳的 o 累加。

    • 最终打分:与当前物品向量点积,sigmoid 得到概率。

  • 损失函数(_build_loss):

    • 主任务:二分类交叉熵。

    • KGE 辅助项:对每跳记忆的三元组计算 h^T R t 的 sigmoid,并取负均值乘权重(鼓励真实三元组得分高)。

    • L2 正则:对当前 batch 的 h/t/r 嵌入做 L2;(代码中对变换矩阵的 L2 条件存在不一致,需修正)。

  • 训练与评估(_build_train, eval):

    • 用 Adam 优化器最小化总损失(注释里有可选梯度裁剪)。

    • 评估返回 AUC 和准确率(阈值 0.5)。

  • 数据与形状约定:

    • 所有记忆占位符为 [batch, n_memory] 的 ID,嵌入为 [dim][dim, dim]

    • 代码使用 float64 与 TF1 风格 API(需要在 TF2 中用 tf.compat.v1 和禁用 eager 才能运行)。

简而言之,这个文件定义了一个“多跳知识图谱注意力 + 推荐打分”的模型类:读入参数与数据,构建嵌入与多跳注意力前向,计算交叉熵 + KGE + L2 的损失,用 Adam 训练,并提供评估接口。

7.2“[batch_size, n_memory]”这两个元素分别什么含义

“[batch_size, n_memory]”是张量的两个维度,分别表示:

  • batch_size:本次前向/训练中并行处理的样本数。每一行对应一个样本(例如一个用户-候选物品对)。

  • n_memory:对该样本在“当前 hop(层)”上保留的三元组记忆数量。每一列对应一个记忆槽位;在同一列上,memories_h、memories_r、memories_t 的值共同组成一条三元组 (h, r, t)。

补充说明:

  • 这些占位符里的元素是整数ID:memories_h 是头实体ID,memories_r 是关系ID,memories_t 是尾实体ID。

  • 不要把 n_memory 和 n_hop 混淆:n_hop 是层数(会有多个这样的占位符组),n_memory 是每层为每个样本放入的三元组条数。

  • 实际数据中每个样本的可用三元组数可能不等;为了固定形状,一般会对每层的记忆做采样或截断到 n_memory,或用填充补齐。

举例:

  • 若 n_hop=2、n_memory=3、batch_size=2,则会有 6 个占位符:

    • memories_h_0/r_0/t_0: [2,3],对应第 0 跳的三元组ID

    • memories_h_1/r_1/t_1: [2,3],对应第 1 跳的三元组ID

  • 喂数据时,你会给每个占位符传一个 [batch_size, n_memory] 的整型矩阵,模型再据此取嵌入并计算注意力与聚合。

posted @ 2025-10-04 20:02  ゆきキラ  阅读(12)  评论(0)    收藏  举报