HCGR —— Hyperbolic Contrastive Graph Representation Learning for Session-based Recommendation

会话推荐里的"兴趣结构"几乎天然是分层的:用户先点开一个大类(“跑鞋”),然后筛品牌,再筛尺码、价位,最后落到一个 SKU。这条轨迹其实是一棵树——每多一次点击,候选集就大致按倍数收窄。问题在于:在欧氏空间里把这种树状结构放进去,需要堆很多维度才能让叶子节点不互相挤压,因为欧氏空间的"体积"只随半径多项式增长;而双曲空间的体积随半径指数级增长,正好和树的分支增长是同一个量级,几维就够把整条长尾摊开。

HCGR (Guo et al., 2021)正是把这层直觉做严肃了的工作:它把会话图的节点嵌入到洛伦兹双曲流形上,在切空间里跑带注意力的 GNN 聚合,再加一个 InfoNCE 形式的对比损失,把同一个会话的两种增强视图拉近、把其他会话推远。最后的效果在 Diginetica、Yoochoose、Last.FM 等公开数据集上稳定打过 SR-GNN、GCE-GNN 这些强基线,而且增益最大的位置恰好是双曲几何应该擅长的地方——长尾物品多、层级深的数据集。

下面这篇笔记会重点讲清楚四件事:会话兴趣到底在什么意义上是"层级的",洛伦兹模型里距离/注意力具体怎么算,对比学习为什么是个便宜又有效的辅助信号,以及如何有判断力地读这类论文的消融实验,分清"几何确实有用"和"不过是参数更多"。

你将看到什么

  • 会话推荐数据为什么具备"双曲几何愿意吃"的结构
  • 洛伦兹模型的距离、切空间、指数/对数映射——按可实现的方式讲,不抠数学严格性
  • HCGR 如何在不离开流形的前提下完成 GNN 聚合与注意力
  • 双视图对比目标和双曲距离怎么配合
  • 怎么读 HCGR 消融——欧氏 vs 双曲在同等容量下比,对比损失加 vs 不加分别贡献多少
  • 什么场景下值得为这套机制付复杂度的代价,什么场景下老老实实用 SR-GNN 就够了

前置知识

  • 会话推荐基础(最好读过 SR-GNN 或 GCE-GNN)
  • 标准 GNN 的消息传递
  • 一点微分几何的直觉就够,不需要严格的黎曼几何背景

1. 为什么会话兴趣天然适合双曲几何

会话推荐的数据通常具有这三个特征,反复出现到几乎可以当成"行业常识":

  1. 幂律分布的热度:少数头部物品吸走绝大多数点击,长尾物品又多又稀疏。
  2. 沿分类树收窄:一个典型会话就是在"大类 → 子类 → 属性 → SKU"这条路径上一步步往下走。
  3. 指数级分支:从一个粗概念往下展开,细粒度选项的数量基本是按倍数爆炸的。

这三条,恰好就是的定义性特征。而树在欧氏空间里嵌入会很难看。一棵深度 $L$ 的二叉树有 $2^L$ 个叶子,但只有 $L$ 层"半径"。在 2D 欧氏平面上,半径 $r$ 的圆周长是 $2\pi r$,能放下的间距 $\delta$ 的点数是 $O(r/\delta)$,是线性的;而在双曲圆盘上,半径 $r$ 的边界长度是 $\sinh(r) \sim e^r$,能放下的点数是 $O(e^r/\delta)$,是指数的。树正好塞得下,谁也不需要被挤变形。

{% asset_img fig1_poincare_vs_euclidean.png “把同一棵 4 层二叉树分别嵌入欧氏平面(左)和庞加莱圆盘(右)。在欧氏平面里,叶子已经开始挤在一起;在庞加莱圆盘里,由于边界长度按指数增长,每一片叶子都还有充裕的空间。” %}

上面这张图基本就是双曲嵌入的 Elevator Pitch。左边到第 4 层叶子已经互相打架,要继续展开只能升维或者扩半径;右边把叶子推到接近边界的位置,指数级的边界长度自动把它们均匀地摊开。

2. 会话图:HCGR 在哪一层动手术

HCGR 是个图模型。给定一个会话 $s = [v_1, v_2, \dots, v_n]$,它先构造有向会话图 $G_s = (V_s, E_s)$:

  • 节点:会话里出现过的 unique 物品;
  • 边:观察到的转移 $v_i \to v_{i+1}$,可以按频次加权。

这就是 SR-GNN 一脉的标准设定。HCGR 把这部分完整保留——局部转移结构由 $G_s$ 上的消息传递来捕捉,没有改动。它真正动刀子的只有两处:嵌入空间的几何训练信号。这两个改动加起来正好回应前面提到的两个老大难——欧氏空间装不下层级,监督信号容易过拟合到噪声轨迹。

3. 洛伦兹模型的"操作版"

双曲几何有几个等价模型:庞加莱球、克莱因模型、洛伦兹(也叫双曲面)模型。HCGR 选洛伦兹,原因是公式比庞加莱球数值上稳定,靠近边界时梯度行为也更好。

3.1 双曲面流形

在 $\mathbb{R}^{d+1}$ 上定义洛伦兹内积:

$$ \langle \mathbf{x}, \mathbf{y} \rangle_{\mathcal{L}} \;=\; -x_0 y_0 + \sum_{i=1}^{d} x_i y_i. $$

取曲率 $c = -1$,双曲面(取上半叶)就是

$$ \mathbb{H}^d \;=\; \bigl\{\, \mathbf{x} \in \mathbb{R}^{d+1} \;:\; \langle \mathbf{x}, \mathbf{x} \rangle_{\mathcal{L}} = -1,\; x_0 > 0 \,\bigr\}. $$

直白说:嵌入是个 $(d+1)$ 维向量,被强制贴在一张弯曲的曲面上。多出来那一维是代价——为了让双曲操作能在外围欧氏空间里写成干净的线性代数,必须把维度加一维。

3.2 距离

洛伦兹距离写起来非常清爽:

$$ d_{\mathcal{L}}(\mathbf{x}, \mathbf{y}) \;=\; \mathrm{arcosh}\!\bigl( -\langle \mathbf{x}, \mathbf{y} \rangle_{\mathcal{L}} \bigr). $$

定性上要记的就一句:随着两个点沿着双曲面"上推",洛伦兹内积按指数量级变大,外面套一个 arcosh,距离照样指数般地张开——这正是把指数分支的树撑开所需要的几何性质。

3.3 切空间、exp、log

弯曲流形上不能直接做梯度下降,否则更新一步就掉出流形了。标准做法是借助切空间:选一个基点(一般取原点 $\mathbf{o} = (1, 0, \dots, 0)$),它的切空间是局部欧氏的,把所有"线性"操作都搬到切空间做完,再映射回流形。

  • 对数映射 $\log_{\mathbf{o}}: \mathbb{H}^d \to T_{\mathbf{o}}\mathbb{H}^d$:把流形上的点投到切平面;
  • 指数映射 $\exp_{\mathbf{o}}: T_{\mathbf{o}}\mathbb{H}^d \to \mathbb{H}^d$:对数映射的逆,把切向量抬回流形。

闭式公式不必死记,关键是这个模式:欧氏 GNN 里你想做的任何一种操作——求和、注意力、MLP——通通搬到切空间做,做完 exp_map 回去。这是双曲面上"加法"唯一能合理定义的方式。

4. HCGR 的端到端结构

先把整张图摆出来,再分块讲:

{% asset_img fig2_hcgr_architecture.png “HCGR 端到端结构:会话序列 → 会话图 → 洛伦兹嵌入 → 切空间注意力聚合 → 会话表示 → 下一物品打分(CE 损失)+ 双视图对比辅助损失。” %}

并行进行的有三件事:

  1. 几何骨架:所有物品和会话表示都活在 $\mathbb{H}^d$ 上,每次更新先 log 进切空间、聚合、再 exp 回去。
  2. 推荐头:从节点表示读出整段会话向量 $\mathbf{s}$,对每个候选物品打分时用负洛伦兹距离作为相似度,用交叉熵监督真实的下一物品。
  3. 对比头:对会话图 $G_s$ 做两次独立的随机增强,得到两个视图,分别编码成 $\mathbf{s}^a, \mathbf{s}^b$,跑 InfoNCE。

4.1 双曲 GNN 聚合

普通 GAT 风格的聚合是 $\mathbf{h}_i = \sigma\!\bigl(\sum_{j \in \mathcal{N}(i)} \alpha_{ij} W \mathbf{h}_j\bigr)$。但是双曲面上不能直接对点求和——加完之后多半已经飞出流形了。HCGR 的处理方式是顺理成章的:

$$ \mathbf{h}_i^{(l+1)} \;=\; \exp_{\mathbf{o}}\!\Biggl( \sum_{j \in \mathcal{N}(i)} \alpha_{ij}^{(l)} \, \log_{\mathbf{o}}\!\bigl(\mathbf{h}_j^{(l)}\bigr) \Biggr). $$

从内往外读:把邻居都拉到切空间,在切空间里做注意力加权求和,再 exp 回流形。注意力权重 $\alpha_{ij}$ 还是 GAT 那一套——对切空间向量做线性层 + 拼接 + softmax。

如果要在不同基点的切空间之间搬运向量,还需要平行移动(parallel transport)保持向量的"内在"特征不变。HCGR 在多层聚合里用到了它,但只是在工程上让多层堆得正确,思想上没有多余的复杂度。

4.2 尊重曲率的非线性

直接对一个双曲面上的坐标向量做 ReLU 是没意义的,因为 ReLU 不知道曲率。HCGR 把激活塞在两层不同曲率的映射之间:

$$ \sigma_{\mathbb{H}}^{l \to l+1}(\mathbf{x}) \;=\; \exp_{\mathbf{o}}^{c_{l+1}}\!\Bigl(\, \sigma\!\bigl(\, \log_{\mathbf{o}}^{c_l}(\mathbf{x})\,\bigr)\, \Bigr). $$

这是双曲神经网络里的"切空间激活"标准模板。它允许不同层使用不同的曲率,同时保证每一层的中间状态都还在合法的流形上。

5. 对比辅助损失

会话图本身就是吵的:误点、重复点击、试探性浏览、回退……都混在一段会话里。如果只用交叉熵监督下一个物品,模型会把任何"碰巧能预测到点击目标"的特征都强化,哪怕这种特征让会话表示本身变得脆弱。对比学习正是用一种结构性的约束反过来要求编码器:“同一会话的两次扰动应该落在同一个地方;不同会话不能落在同一个地方。”

{% asset_img fig3_contrastive_views.png “双视图对比方案:边丢弃和节点丢弃各产出一个增强视图,两个视图都过同一个 HCGR 编码器,InfoNCE 在双曲空间里把正对拉近、把负对推远,距离用洛伦兹距离衡量。” %}

5.1 数据增强

HCGR 在会话图 $G_s$ 上做图级别的增强:

  • 边丢弃(edge dropout):随机丢一部分转移边;
  • 节点丢弃(node dropout):随机去掉少数节点,必要时把入边/出边重新连接。

对 $G_s$ 做两次独立的增强,得到 $G_s^a$ 和 $G_s^b$。两个视图共享同一个 HCGR 编码器,得到 $\mathbf{s}^a, \mathbf{s}^b \in \mathbb{H}^d$。

5.2 双曲空间里的 InfoNCE

对比损失就是标准的 InfoNCE,只是相似度用双曲距离来定义:

$$ \mathcal{L}_{\mathrm{cl}} \;=\; -\, \log \frac{\exp\!\bigl( \mathrm{sim}(\mathbf{s}^a, \mathbf{s}^b) / \tau \bigr)}{\sum_{k} \exp\!\bigl( \mathrm{sim}(\mathbf{s}^a, \mathbf{s}^b_k) / \tau \bigr)}, $$

其中 $\mathrm{sim}(\mathbf{u}, \mathbf{v}) = -\, d_{\mathcal{L}}(\mathbf{u}, \mathbf{v})$(实际实现里为了数值稳定,往往是在原点的切空间上做内积),$\tau$ 是 InfoNCE 温度。分母遍历当前 mini-batch 里的所有会话,把其它会话当作负样本。

5.3 总损失

最终把两部分加起来:

$$ \mathcal{L} \;=\; \mathcal{L}_{\mathrm{rec}} \;+\; \lambda \, \mathcal{L}_{\mathrm{cl}}. $$

通常 $\lambda$ 取 0.05–0.2 之间。这里要强调一句:对比损失是个正则项,不是替代监督。$\lambda$ 取得太大会反过来伤排序精度,因为编码器开始过分关心"我和我自己像不像",而不是"我能不能预测到下一物品"。

6. 距离与维度:判断"几何是否真用上"的核心论据

判断 HCGR 是不是真的因为双曲几何而赢,最干净的角度是容量问题:同一棵层级树,是否能在更少维度里塞下来?

{% asset_img fig4_distance_growth.png “左图:欧氏空间里成对距离随半径线性增长(蓝),双曲空间里随半径指数增长(紫)。右图:随着嵌入维度增加,双曲空间能承载的层级容量比欧氏空间快得多。” %}

左图就是几何本身:$\sinh(r)$ 对 $r$,$r > 1.5$ 之后两条曲线急剧分叉,所以位于流形外围的两个物品之间被几乎免费地推开了。右图是这件事在推荐里的实际后果:$d = 16$ 的欧氏嵌入对深层级类目仍然吃力,但同样 16 维的双曲嵌入还有相当余地。这也解释了 HCGR 为什么在长尾占比更高的 Last.FM 上赢得更多,而在会话短、头部权重大的 Yoochoose 上优势没那么夸张——几何带来的边际收益和数据本身的层级深度是耦合的。

7. 实验结果该怎么读

{% asset_img fig5_performance.png “在三个标准会话推荐数据集上的 Recall@20 与 MRR@20:仅替换为双曲编码器(无对比)已经胜过欧氏基线,加上对比辅助后差距进一步拉开。” %}

论文自己的消融里有两个值得划重点的现象:

  • 几何本身就有效:把欧氏 GNN 单独换成洛伦兹聚合(加对比损失),Recall@20 已经有可见的提升。这条是判定"涨点是几何贡献"还是"只是参数更多"的关键证据。
  • 对比损失是稳定加成:在三个数据集上对比辅助都能再涨一截,且在会话噪声较大的数据集上涨幅最大——这正符合"对比 = 给编码器的鲁棒性正则"的预期。

8. 怎么有判断力地读 HCGR 类论文

如果你在审 HCGR 或类似的双曲推荐工作,下面这份清单基本能逼出真相:

  1. 同等容量比较:欧氏和双曲的嵌入维度、参数量必须对齐。常见情况是双曲在小维度上明显赢、在高维度上打平——结论的样子不一样,标题党就站不住。
  2. 增益落在哪一段:要求作者给出头部 vs 长尾的拆分。如果几乎所有提升都在头部,那真正起作用的多半不是几何。
  3. 每个组件单独看:纯双曲、纯对比、双曲+对比,三栏数据缺一不可。否则没法判断到底是几何还是对比在抬。
  4. 可复现性:双曲优化是出名的不稳。看是否固定随机种子、跑了多少次,是否提到稳定化技巧(梯度裁剪、靠近原点的初始化、流形投影)。
  5. 曲率敏感性:曲率 $c$ 是个超参。如果每个数据集都要单独调,说明这件事工程上很难落地。

9. 如果你想用在自己的系统里

几条经验法则:

  • 先把欧氏基线打到位。一个调好的 SR-GNN 或 GCE-GNN 已经很强。在拿到干净的欧氏数字之前不要付双曲的复杂度成本。
  • 数据真有层级时再上双曲:类目深、长尾多、多层意图——这种时候双曲是值得的。
  • 对比辅助几乎可以无脑加:哪怕是欧氏编码器,边丢弃 + InfoNCE 也常常带来稳定的小幅提升。
  • 从一开始就准备好"稳"的工程:流形投影、梯度裁剪、$\lambda$ 的 warmup——这些都不是 nice-to-have,是必备。双曲优化经常安静地发散。
  • 真正要花时间调的是三个旋钮:曲率 $c$、对比温度 $\tau$、对比权重 $\lambda$。其它的影响普遍小一个数量级。

10. 局限与未解决的问题

论文对自己的代价是诚实的,我们也不能回避:

  • 计算开销:每一层都要付 log_mapexp_map 的成本,物品集大、网络深的时候一点都不小。
  • 优化脆弱性:朴素 SGD 一不小心就把表示甩出流形外;用黎曼优化器能缓解,但又多出一层超参数和实现复杂度。
  • 工具链断层:PyTorch、TensorFlow 默认是欧氏的。Geoopt 这类库填了一部分空白,但你已经离开了主流路径。
  • 可解释性差:跟产品方解释"洛伦兹距离更近",比解释"余弦相似度大于阈值"难一个数量级。

把这些放在一起,对大多数团队来说,HCGR 的合理读法应该是——几何是它的核心贡献,对比学习是个可以单独搬走的便宜技巧。先把对比辅助加到你现有的欧氏推荐器里看是否涨点;只有当数据形状明显在召唤双曲几何时,再付那笔几何税。

参考文献

  • Guo, Tang, Yu, Xu, Yu, Yang, Lu. HCGR: Hyperbolic Contrastive Graph Representation Learning for Session-based Recommendation. 2021. arXiv:2107.05366
  • Wu et al. Session-based Recommendation with Graph Neural Networks (SR-GNN). AAAI 2019.
  • Wang et al. Global Context Enhanced Graph Neural Networks for Session-based Recommendation (GCE-GNN). SIGIR 2020.
  • Nickel and Kiela. Poincaré Embeddings for Learning Hierarchical Representations. NeurIPS 2017.
  • Ganea, Bécigneul, Hofmann. Hyperbolic Neural Networks. NeurIPS 2018.
  • Chen et al. A Simple Framework for Contrastive Learning of Visual Representations (SimCLR). ICML 2020.

Liked this piece?

Follow on GitHub for the next one — usually one a week.

GitHub