# Contrastive 算法原理详解(面向本项目) 本文档聚焦本项目中的 `contrastive` 方法,强调“**为什么这样做**”以及“**数学上在优化什么**”,并给出与代码实现的一一映射。 --- ## 1. 问题定义:我们到底要学什么? 在 co-location 推荐场景中,系统每轮会产生候选模式集合: - 模式 \(p\):如 `["Restaurant", "Cafe"]`,可被编码为向量 \(\mathbf{p}\) - 用户偏好:来自   - Stage0 意图向量(冷启动)\(\mathbf{u}_{llm}\)   - 历史反馈向量(正负样本)\(\mathbf{u}_{fb}\) 目标不是“只看统计置信度”,而是学习一个排序函数 \(s(p,u)\),让: - 用户喜欢(positive)的模式得分更高 - 用户不喜欢(negative)的模式得分更低 这本质是一个**偏好排序学习问题**,而不仅是分类问题。 --- ## 2. 为什么用 Contrastive(对比学习)? ### 2.1 Baseline 的局限 Baseline 常见做法是直接在原始嵌入空间算余弦相似度: \[ s_{base}(p,u)=\cos(\mathbf{p},\mathbf{u}) \] 问题在于:原始语义空间未必“对齐用户主观偏好”。   也就是说,两个语义上接近的模式,未必都符合该用户偏好。 ### 2.2 Contrastive 的核心思想 Contrastive 学习一个可训练映射 \(f_\theta(\cdot)\)(本项目中是 `PreferenceEncoder`),把模式与用户向量映射到“偏好判别更友好”的空间: \[ \tilde{\mathbf{p}} = f_\theta(\mathbf{p}),\quad \tilde{\mathbf{u}} = f_\theta(\mathbf{u}) \] 再在该空间计算相似度: \[ s_{ctr}(p,u)=\cos(\tilde{\mathbf{p}},\tilde{\mathbf{u}}) \] 训练目标:让 positive 更靠近 anchor,让 negative 更远离 anchor。 --- ## 3. 数学目标函数:Triplet 约束在做什么? 本项目实现了两种 triplet 损失。 ## 3.1 Euclidean Triplet Loss 设一组三元组为 \((a,p,n)\): - \(a\):anchor(锚点,偏好参考) - \(p\):positive(用户喜欢) - \(n\):negative(用户不喜欢) 映射后向量分别为 \(f_\theta(a), f_\theta(p), f_\theta(n)\),损失: \[ \mathcal{L}_{triplet} =\max\big(0,\ d(a,p)-d(a,n)+m\big) \] 其中 \(d\) 为欧式距离,\(m\) 为 margin。   含义:要求 \(a\) 到 \(n\) 的距离,至少比到 \(p\) 的距离大 \(m\)。 ## 3.2 Cosine Triplet Loss(本项目默认) 本项目配置常用 `use_cosine_loss: true`,对应: \[ \mathcal{L}_{cos} =\max\big(0,\ -\cos(a,p)+\cos(a,n)+m\big) \] 等价目标是: \[ \cos(a,p)\ge \cos(a,n)+m \] 即正样本相似度至少高于负样本相似度一个 margin。 --- ## 4. 几何解释:模型在嵌入空间“搬运”了什么? 训练过程会逐步形成如下几何结构: - 用户偏好相关模式向同一局部簇收拢 - 用户不偏好模式被推离该簇边界 - 难负样本(与正样本很像但用户不喜欢)会强迫模型学习更细粒度判别边界 这意味着 Contrastive 不是“记忆某个标签”,而是在学“相对次序关系”。 --- ## 5. 本项目中的用户向量与 Contrastive 的耦合 本项目并非只用反馈向量,而是融合 Stage0 与反馈信息: \[ \mathbf{u}_t=\alpha_t\mathbf{u}_{llm}+(1-\alpha_t)\mathbf{u}_{fb},\quad \alpha_t=e^{-\lambda t} \] 解释: - 早期(\(t\) 小):更依赖 LLM 意图,解决冷启动 - 后期(\(t\) 大):更依赖真实反馈,增强个性化 Contrastive 在这个框架中学习的是:   “如何在投影空间中让当前 \(\mathbf{u}_t\) 与用户真正喜欢的模式更近”。 --- ## 6. 排序分数不是只看对比分:还有置信度融合 本项目最终排序分数是: \[ score=\alpha\cdot score_{pref} + (1-\alpha)\cdot confidence \] 其中: - \(score_{pref}\):Contrastive 空间相似度(或 baseline 相似度) - `confidence`:模式挖掘统计置信度 - \(\alpha\):配置 `stage3.alpha`(如 0.7) 这相当于将“用户个性化偏好”与“数据统计可靠性”联合建模,避免纯个性化导致不稳定推荐。 --- ## 7. 训练与推断的一致性 Contrastive 生效要满足两件事: 1. 训练阶段确实更新了 `PreferenceEncoder` 参数 2. 推断阶段打分调用的是“带 model 的 scorer” 本项目里对应: - 训练器:`src/learning/trainer.py`(`PreferenceTrainer.train`) - 推断打分:`src/preference/scorer.py` 的 `score_with_model` / `score_patterns(..., model=...)` 若没有可用 model,会回退到 baseline 相似度。 --- ## 8. 与 Baseline、Preference-Weighted 的原理差异 | 维度 | Baseline | Contrastive | Preference-Weighted | |------|----------|-------------|---------------------| | 核心思想 | 原空间余弦相似度 | 学习投影空间的相对偏好约束 | 在相似度上乘特征级权重 | | 是否训练神经网络 | 否 | 是(Triplet) | 否(本配置) | | 主要优势 | 简单稳定 | 判别能力强,能学“细偏好” | 对显式 liked/disliked 特征敏感 | | 潜在风险 | 容易语义过泛化 | 反馈不足时可能欠拟合 | 权重设计依赖规则参数 | --- ## 9. 为什么 Contrastive 往往更好(理论直觉) 在排序任务中,模型不需要绝对分数正确,只需保证: \[ s(p^+,u) > s(p^-,u) \] Triplet Loss直接优化这个“相对顺序约束”,因此更贴合推荐/重排任务目标。   相比点式回归损失,pair/triplet 目标通常对个体偏好更鲁棒。 --- ## 10. 在本项目中的关键超参数及影响 | 参数 | 位置 | 含义 | 调大影响 | 调小影响 | |------|------|------|----------|----------| | `margin` | `stage3.margin` | 正负样本拉开间隔 | 判别边界更硬,可能更难收敛 | 约束变软,区分度可能不足 | | `learning_rate` | `stage3.learning_rate` | 学习率 | 收敛快但可能震荡 | 稳定但收敛慢 | | `epochs` | `stage3.epochs` | 训练轮数 | 拟合更充分,过拟合风险增 | 欠拟合风险增 | | `hidden_dim` | `stage3.hidden_dim` | 投影网络容量 | 表达力更强,需更多数据 | 容量不足,判别受限 | | `alpha` | `stage3.alpha` | 偏好分与置信度融合权重 | 更个性化 | 更偏统计可靠性 | --- ## 11. 实践建议(实验复现角度) 1. 确保正负反馈都存在(仅单边反馈 triplet 质量差)。 2. 先看 `pre_interaction` 指标,再看每轮提升幅度,判断是否“学到了”。 3. 若 Contrastive 优势不明显,优先检查:    - 反馈样本规模和多样性    - `margin` 是否过大    - 推断是否真的使用了训练后模型 4. 与第三方法对比时,注意区分:    - Contrastive:学习参数化表示    - Preference-Weighted:规则型显式偏好重加权 --- ## 12. 代码映射(便于查阅) | 功能 | 代码位置 | |------|----------| | 对比损失定义 | `src/learning/trainer.py` (`TripletLoss`, `CosineTripletLoss`) | | 模型训练入口 | `src/learning/trainer.py` (`PreferenceTrainer.train`) | | 偏好编码器 | `src/embedding/encoder.py` (`PreferenceEncoder`) | | 打分(含 model 与回退) | `src/preference/scorer.py` | | 实验调用链 | `src/experiment/runner.py` + `src/experiment/evaluator.py` | | Stage3 配置 | `config/config_contrastive.yaml` | --- ## 13. 一段论文可用描述(中文) 本研究在模式重排序阶段引入基于 Triplet 的对比学习框架。具体而言,我们以用户偏好为监督信号构造 \((anchor, positive, negative)\) 三元组,通过 `PreferenceEncoder` 将原始模式嵌入映射到偏好判别空间,并优化正负样本间隔约束,使得用户偏好模式与锚点在投影空间中更接近、非偏好模式更远。推断阶段以投影后余弦相似度作为偏好分,并与模式统计置信度线性融合得到最终排序分数,从而兼顾个性化偏好与统计可靠性。