以下整理的学习笔记内容均来源于 https://github.com/wangshusen/RecommenderSystem
推荐算法
- 一 推荐系统概要
- 二 召回
- 1 基于物品的协同过滤(ItemCF)
- 2 Swing召回通道
- 3 基于用户的协同过滤 (UserCF)
- 4 离散特征处理
- 5 矩阵补充
- 6 双塔模型:模型和训练
- (1)Pointwise训练
- (2)Pairwise训练
- (3)Listwise训练
- 7 双塔模型:正负样本
- 8 双塔模型: 线上召回和更新
- 9 双塔模型+自监督学习
- (1)特征变换:RandomMask
- (2)特征变换:Dropout
- (3)特征变换:互补特征
- (4)特征变换:Mask一组关联的特征
- 10 Deep Retrieval
- 11 其他召回通道
- 12 曝光过滤&BloomFilter
一 推荐系统概要
注意分层实验的正确理解:同时存在两套独立的分桶系统,就像每个学生有两个独立的学号(一个按身高编,一个按生日编)。
这种设计是大型互联网公司做 “分层实验” 或 “正交实验” 的基础,目的是为了能同时进行成百上千个A/B测试而不相互干扰。
反转实验:大部分人用新策略,小部分人故意用旧策略
二 召回
1 基于物品的协同过滤(ItemCF)
考虑了喜欢程度的公式:
2 Swing召回通道
这里的“小圈子”应该区分:
高质量小圈子:几个人共同喜欢很少的几样东西(overlap小但精准)
低质量小圈子:几个人共同喜欢很多东西(overlap大但宽泛)
Swing惩罚的是第2种——那些“什么都喜欢”的用户组成的圈子。
3 基于用户的协同过滤 (UserCF)
每个物品对用户相似度的贡献,与该物品的独特性(冷门程度)成正比。
4 离散特征处理
例如:
Embedding(嵌入):
5 矩阵补充
什么是双塔?
双塔模型有两个独立的神经网络:
用户塔:输入用户特征,输出用户向量
物品塔:输入物品特征,输出物品向量 相似度 = 用户向量 · 物品向量
因此双塔可以解决冷启动问题,就算是新用户和新物品都可以动态地表示它们的向量。
但是曝光无点击≠负样本,错误的负样本会带来什么?
模型过度惩罚好内容:把用户潜在感兴趣的内容也当成负样本,模型就不敢推荐了
流行度偏差加剧:只有最热门、最“安全”的内容会被推荐
长尾内容被埋没:新颖但需要被发现的内容永远没机会
6 双塔模型:模型和训练
双塔模型(Dual-Tower Model)的核心结构是:查询(Query) 和 物品(Item) 分别通过独立的神经网络(两个“塔”)得到向量表示,然后通过计算向量相似度(如点积、余弦相似度)来预估它们的匹配程度。
或者用余弦相似度
训练的目标是让匹配的(Query,Item)对的相似度尽可能高,不匹配的尽可能低
(1)Pointwise训练
Pointwise(逐点法)
思想:独立看待每一个“用户-对象”组合,将其视为一个独立的样本,并给它打上一个绝对的标签(例如:1 = 喜欢/匹配,0 = 不喜欢/不匹配)。
训练:模型的目标是直接预测这个二元分类的概率。它不关心这个组合与其他组合之间的相对关系,只关心自己预测的“匹配分数”是否接近真实标签。
“独立看待每个正样本、负样本,做简单的二元分类。” 正样本就是(用户,匹配的对象,标签1),负样本就是(用户,不匹配的对象,标签0)。模型的任务是学会区分这两种情况。
优缺点:
优点:简单,可以直接用成熟的分类算法(如逻辑回归、交叉熵损失)。
缺点:忽略了物品之间的相对顺序。比如,一个“有点喜欢”的对象和一个“非常喜欢”的对象,标签都是1,模型无法学习到它们之间的优劣差异。这不符合推荐/搜索追求排序的本质。
(2)Pairwise训练
Pairwise(配对法)
思想:同时考虑一个正样本和一个负样本,目标是让正样本的匹配分数高于负样本。
训练:模型不再预测绝对分数,而是学习一个相对的排序。常见的损失函数是 Triplet Loss 或 RankNet Loss。核心是拉大正样本和负样本之间的距离。
“每次取一个正样本、一个负样本”。对于同一个用户,模型会同时看到一个“匹配对象”(正样本)和一个“不匹配对象”(负样本)。损失函数会惩罚“正样本得分 < 负样本得分”的情况。
优缺点:
优点:更符合排序的直觉,模型直接学习“什么更好”。
缺点:每次只比较一对,忽略了全局信息。比如,一个“非常好”的负样本(差点就匹配了)和一个“非常差”的正样本(勉强匹配),这种复杂情况在Pairwise中难以精确建模。且训练样本对数量庞大(O(N²))。
(3)Listwise训练
思想:一次性考虑一个正样本和多个负样本(即一个列表),目标是优化整个列表的排序,使得正样本排在列表的最前面。
训练:这是最接近实际推荐/搜索场景(用户看到的是一个排序后的列表)的方法。损失函数直接衡量模型输出的列表排序与理想排序之间的差距。经典方法如 Softmax Cross-Entropy Loss(将排序问题转化为多分类问题)或 ListNet/ListMLE。
“每次取一个正样本、多个负样本”。对于同一个用户,模型会看到一个正样本和K个负样本。损失函数会让模型给正样本的打分,不仅高于每一个负样本,而且要显著地高,以至于在softmax后,正样本的概率接近1。
优缺点:
优点:最符合实际业务目标,直接优化整个列表的排序质量,能学习到更精细的全局排序关系。
缺点:计算复杂度高(特别是负样本很多时),工程实现更复杂,对负样本采样策略敏感。
总结对比:
这种模型的典型结构是:
输入侧:用户特征(ID、离散特征、连续特征)和物品特征(ID、离散特征、连续特征)不分开处理
处理方式:将所有特征拼接(Concatenate)在一起
网络结构:通过一个统一的深度神经网络进行特征变换
输出:直接预估用户对物品的兴趣分数(CTR/CVR等)
这就是典型的 DeepFM、DIN、DIEN 等排序模型的架构。
双塔产出的是用户向量和物品向量,可以用FAISS等引擎进行高效的相似度搜索
端到端模型产出的是标量分数,要找到Top-K只能全量计算排序,无法利用ANN(最近邻)加速
这就是为什么工业界的召回系统几乎都采用双塔架构(或类似的双编码器架构),而把复杂的端到端模型留给排序阶段。
这两种模型不是竞争关系,而是互补关系,共同构成推荐系统的完整流水线:
召回(双塔):大海捞针(海量→千级)
排序(端到端):精挑细选(千级→百级)
7 双塔模型:正负样本
"困难"指的是:在当前的模型看来,这些负样本和正样本的相似度很高,模型容易把它们误判为正样本。
8 双塔模型: 线上召回和更新
9 双塔模型+自监督学习
(1)特征变换:RandomMask
(2)特征变换:Dropout
(3)特征变换:互补特征
(4)特征变换:Mask一组关联的特征
、
10 Deep Retrieval
为什么要引入 Path?(核心逻辑)
如果直接从千万级的商品库里找 Item,计算压力很大。 path 通常代表一个层次化的索引结构(比如 TDM 树、类目树或某种聚类路径)。
例子: 假设路径是 [运动 -> 跑步 -> 跑鞋]。
Beam Search 的作用: 模型不是直接预测商品,而是先预测用户可能喜欢“运动”,再在“运动”下预测“跑步”,最后定位到“跑鞋”这个路径节点。这比直接从 100 万个商品里选 1 个人要快得多。
“一条路径上不能有过多的物品”。这是为了防止长尾效应。如果 90% 的物品都挤在一条路径下,第一步的 Beam Search 就失去了过滤意义(还是得处理海量物品)。
11 其他召回通道
GeoHash 是一种将地理位置(经纬度)编码成短字符串的方法。它不是召回算法本身,而是为基于位置的召回提供了一种高效的索引方式。
核心思想:将二维的经纬度转换为一维的字符串
编码原理:(简单理解)
将地球划分为网格
每个网格对应一个字符串编码
字符串越长,表示的网格越小(精度越高)