文章目录
- 召回
- 内容召回
- 行为召回
- ItemCF
- UserCF
- Swing
- 关联规则
- 聚类协同
- 矩阵分解
- 图召回
- 图嵌入
- item2vec(embedding)
- FM模型召回
- 双塔模型
- aribnb的embedding策略
- 用户行为序列召回
- 多兴趣拆分
- 知识图谱融合
- 深度树TDM
- 因子分解排序
- 树模型排序
- 深度模型排序
- FNN
- Wide Deep
- Deepfm
- PNN
- NFM
- AFM
- DCN
- MLR
- DIN
- DIEN
- DSIN
- MIND
- MIMN
- DMR
- 工程经验
- 负采样
- 在线学习算法FTRL
- 模型的实效性问题和更新策略
- 线上评估方法
本篇文章会一直更新,主要是记录常见的一些推荐算法。
知识框架如下
召回
内容召回
word2vec
- 了解skip-gram和cbow两种网络的结构
- 了解优化方法:Hierarchical Softmax和Negative Sampling
(1)Hierarchical Softmax
霍夫曼树,频度高的词越靠近根节点,复杂度从n降到log2n
(2)负采样
每次都只是通每次都只是通过采样neg个不同的中心词做负例,就可以训练模型过采样neg个不同的中心词做负例,转化为二分类问题。
采样的词尽量是热门词
LDA
我们认为一篇文章的每个词都是通过“以一定概率选择了某个主题,并从这个主题中以一定概率选择某个词语”这样一个过程得到。
文档到主题服从多项式分布,主题到词服从多项式分布。
核心思想:LDA的目的就是要识别主题,即把文档—词汇矩阵变成文档—主题矩阵(分布)和主题—词汇矩阵(分布)
对于语料库中的每篇文档,LDA定义了如下生成过程:
1.对每一篇文档,从主题分布中抽取一个主题;
2.从上述被抽到的主题所对应的单词分布中抽取一个单词;
3.重复上述过程直至遍历文档中的每一个单词。
博客
行为召回
ItemCF
- 对活跃用户进行惩罚。
- UserCF的推荐结果着重于反映和用户兴趣相似的小群体的热点,而ItemCF的推荐结果着重于维系用户的历史兴趣
- UserCF比较适合用于新闻推荐等热门程度和实时性较强的场景,ItemCF则适用于图书、电商、电影等场景
UserCF
- 对热门物品进行惩罚
- 在计算用户行为之间的相似度时,建立Item-User的倒排表,这样在同一个Item下面的User两两之间一定是在这个Item上有交集的,所以只需要遍历所有的Item,对其下所有的User两两进行统计即可,这样可以极大降低时间复杂度。
CF实效成本低,全量发现能力弱,基于历史相似扩展;存在冷启动问题
Swing
阿里原创算法-swing,基于图结构做match,计算商品间的相似度
如果多个user在点击了s的同时,都只共同点了某一个其他的item,那么这个item和s一定是强关联的
关联规则
找出用户购买的所有物品数据里频繁出现的项集活序列,来做频繁集挖掘,找到满足支持度阈值的关联物品的频繁N项集或者序列。如果用户购买了频繁N项集或者序列里的部分物品,那么我们可以将频繁项集或序列里的其他物品按一定的评分准则推荐给用户,这个评分准则可以包括支持度,置信度和提升度等
常用的关联推荐算法有Apriori,FP Tree和PrefixSpan。如果大家不熟悉这些算法,可以参考我的另外几篇文章:
Apriori算法
FpGrowth算法
序列模式挖掘PrefixSpan算法
聚类协同
常用的聚类推荐算法有K-Means, BIRCH, DBSCAN和谱聚类
介绍下DBSCAN
- DBSCAN的主要优点有:
(1) 可以对任意形状的稠密数据集进行聚类,相对的,K-Means之类的聚类算法一般只适用于凸数据集。
(2) 可以在聚类的同时发现异常点,对数据集中的异常点不敏感。
(3) 聚类结果没有偏倚,相对的,K-Means之类的聚类算法初始值对聚类结果有很大影响。
- DBSCAN的主要缺点有:
(1)如果样本集的密度不均匀、聚类间距差相差很大时,聚类质量较差,这时用DBSCAN聚类一般不适合。
(2) 如果样本集较大时,聚类收敛时间较长,此时可以对搜索最近邻时建立的KD树或者球树进行规模限制来改进。
(3) 调参相对于传统的K-Means之类的聚类算法稍复杂,主要需要对距离阈值ϵ,邻域样本数阈值MinPts联合调参,不同的参数组合对最后的聚类效果有较大影响
矩阵分解
隐语义LFM
- 用两个低阶向量相乘来模拟实际的User-Item矩阵
- label要怎么标注?
一般数据集里面的都是只有正向反馈,即只有标签1,这时就需要进行负采样,即采出标签0来。采样是针对每个用户来进行的,对于每个用户,负采样的Item要遵循如下原则:
(1)对每个用户,要保证正负样本的平衡(数目相似)。
(2)对每个用户采样负样本时,要选取那些很热门,而用户却没有行为的物品。
- 离线计算的空间复杂度:基于邻域的方法需要维护一张离线的相关表。假设有M个用户和N个物品,UserCF需要 O ( M ∗ M ) O(M∗M) O(M∗M)的空间,ItemCF需要 O ( N ∗ N ) O(N∗N) O(N∗N)的空间,而对于LFM,有F个隐类的话,需要 O ( F ∗ ( M + N ) ) O(F∗(M+N)) O(F∗(M+N))的空间
- LFM不太适合用于物品数非常庞大的系统,如果要用,我们也需要一个比较快的算法给用户先计算一个比较小的候选列表,然后再用LFM重新排名。另一方面,LFM在生成一个用户推荐列表时速度太慢,因此不能在线实时计算,而需要离线将所有用户的推荐结果事先计算好存储在数据库中。因此,LFM不能进行在线实时推荐,也就是说,当用户有了新的行为后,他的推荐列表不会发生变化。
图召回
PersonalRank
图嵌入
- deepwalk
- line
相比DeepWalk纯粹随机游走的序列生成方式,LINE可以应用于有向图、无向图以及边有权重的网络,并通过将一阶、二阶的邻近关系引入目标函数,能够使最终学出的node embedding的分布更为均衡平滑,避免DeepWalk容易使node embedding聚集的情况发生。
- node2vec
- SDNE
相比于node2vec对游走方式的改进,SDNE模型主要从目标函数的设计上解决embedding网络的局部结构和全局结构的问题。而相比LINE分开学习局部结构和全局结构的做法,SDNE一次性的进行了整体的优化,更有利于获取整体最优的embedding。
- 阿里EGES
阿里通过引入side information解决embedding问题非常棘手的冷启动问题,不同的side information有权重。
图神经网络模型召回
知识图谱是图神经网络的特例,但是,知识图谱编码的是静态知识,而不是用户直接的行为数据,和具体应用距离较远,这可能是导致两者在推荐领域表现差异的主要原因
知识图谱其实是图神经网络的一个比较特殊的具体实例,但是,知识图谱因为编码的是静态知识,而不是用户比较直接的行为数据,和具体应用距离比较远,这可能是导致两者在推荐领域表现差异的主要原因。信息在图中的传播性,所以对于推荐的冷启动以及数据稀疏场景应该特别有用。
图神经网络做推荐,因为需要全局信息,所以计算速度是个问题
GraphSAGE 则通过一些手段比如从临近节点进行采样等减少计算规模,加快计算速度,很多后期改进计算效率的方法都是从这个工作衍生的;而 PinSage 在 GraphSAGE 基础上 ( 这是同一拨人做的 ),进一步采取大规模分布式计算,拓展了图计算的实用性,可以计算 Pinterest 的30亿规模节点、180亿规模边的巨型图,并产生了较好的落地效果。
item2vec(embedding)
思想:用户、物品分别embedding
好处:多路召回每路截断条数的超参个性化问题等会自然被消解掉
坏处:召回内容头部问题(训练数据对头部领域的降采样,减少某些领域主导,以及在模型角度鼓励多样性等不同的方法)
注意:召回阶段使用模型召回,也应该同步采用和排序模型相同的优化目标,尤其是如果排序阶段采用多目标优化的情况下,召回模型也应该对应采取相同的多目标优化。
FM模型召回
FM模型召回
- 离线训练
我们想要的其实是:每个特征和这个特征对应的训练好的embedding向量
- 映射函数
用户特征,物品特征以及上下文特征。
用户向量存入在线数据库中比如Redis,物品向量存入Faiss(Facebook开源的embedding高效匹配库)数据库中
双塔模型
aribnb的embedding策略
- click session:切片点击序列,然后每个序列用w2v来embedding。序列要求(停留时间超过30s才是有效物品;超过30分钟没有动作就切片)。
- book session:购买行为很稀疏(总量小,单一用户行为少),所以不能用w2v那一套,只能基于某些属性规则做相似user和相似listing的聚合。
用户行为序列召回
输入是用户行为过的物品序列,可以只用物品 ID 表征,也可以融入物品的 Side Information,需要通过一定的方法把这些进行糅合到一个 embedding 里,代表了用户兴趣。
GRU ( RNN 的变体模型 ) 可能是聚合用户行为序列效果最好又比较简单的模型
用户往往是多兴趣的,所以又引申出了多兴趣拆分。
多兴趣拆分
用户多兴趣拆分与用户行为序列召回相比,输入是一样的,输出不同,由输出单独一个用户 embedding,换成输出多个用户兴趣 embedding
把不同的 Item,聚类到不同的兴趣类别里去,聚类方法常用胶囊网络和 Memory Network
知识图谱融合
用于做推荐,一般有两大类知识图谱融合模式:知识图谱 Embedding 模式 ( KGE ) 及图路径模式
- 知识图谱 Embedding 模式:用 TransE 将节点和边转换成 Embedding ,计算距离扩展物品的信息含量。(可解释性不佳)
- 图路径模式:人工定义的知识图谱中知识的关联和传播模式,通过中间属性来对知识传播进行路径搭建(效果不好)
深度树TDM
- 检索方法是自顶向下Beam Search
- 如何对每层选取Top-K节点,具体做法就如上图中的红色框的部分,该部分的输入包括用户的历史行为特征以及节点的Embedding特征,在对每一层选取Top-K的时候,需要将这一层的每一个节点输入左侧模型中得到相应的预测分数,最终根据分数来取Top。(涉及到对负样本的采样操作)
- 在初始化树结构的时候,首先借助商品的类别信息进行排序,将相同类别的商品放到一起,然后递归的将同类别中的商品等量的分到两个子类中,直到集合中只包含一项,利用这种自顶向下的方式来初始化一棵树。基于该树采样生成深度模型训练所需的样本,然后进一步训练模型,训练结束之后可以得到每个树节点对应的Embedding向量,利用节点的Embedding向量,采用K-Means聚类方法来重新构建一颗树,最后基于这颗新生成的树,重新训练深层网络
因子分解排序
FM
FM和树模型都能够自动学习特征交叉组合,但树的模型只适合连续型或值空间较小的稀疏数据;另一方面树模型也不能学习到训练数据中很少或没有出现的特征组合,因为树模型只是对历史的一个记忆,泛化能力较弱。相反,FM模型因为通过隐向量的内积来提取特征组合,对于训练数据中很少或没有出现的特征组合也能够学习到
FM可以解决特征组合以及高维稀疏矩阵问题
FFM
FM模型中,每一个特征对应一个向量;FFM中认为每一个特征对于每一个域field对应一个向量。
FFM的组合特征有10项,如下图所示
其中,红色是field编号,蓝色是特征编号
树模型排序
GBDT+LR
facebook采用了这个模型,树的数量《=500,每棵树的节点《=12,大致有三种组合方案
- 离散特征onehot + 连续特征gbdt
- 低频离散特征onehot + 连续特征/高频离散特征 gbdt
- 原始特征onehot + ID类gbdt + 非id类gbdt
【LR特征如何处理】为了让线性模型能够学习到原始特征与拟合目标之间的非线性关系,通常需要对原始特征做一些非线性转换。常用的转换方法包括:特征聚类、连续特征离散化(包括等频离散、等间距离散,或者采用树模型通过gain来找到最优分裂点进行划分)、特征交叉(数值累加、累乘,类目组合等)等
【为什么建树采用GBDT而非RF】:很多实践证明GBDT的效果要优于RF,且GBDT前面的树,特征分裂主要体现对多数样本有区分度的特征;后面的树,主要体现的是经过前N颗树,残差仍然较大的少数样本。优先选用在整体上有区分度的特征,再选用针对少数样本有区分度的特征,思路更加合理,这应该也是用GBDT的原因
深度模型排序
发展历程可以参考我的文章推荐算法—ctr预估
这里只画出结构,写一些面试注意点
- LR模型采用原始人工特征交叉
- FM自动学习xi和xj的二阶交叉特征
- PNN用内积、外积做二阶交叉
- NFM、AFM采用BI-Interaction方式学习二阶交叉
- 更高阶:DCN,任意进行特征交叉,且不增加网络参数
- DIN在embeeding层后做了一个action unit操作,对用户的兴趣分布进行学习后再输入DNN
FNN
- 利用DNN优化高阶特征
- wide deep的深度部分就是这样的结构
Wide Deep
特征工程后的离散特征:线性模型
离散+连续:DNN
Deepfm
离散+连续:线性模型
离散:FM
离散+连续:DNN
PNN
- z是embedding层的复制,p有IPNN和OPNN两种
- embbeding大小:M,filed大小:N
- IPNN是内积,OPNN是矩阵
NFM
- Bi-Interaction Layer名字挺高大上的,其实它就是计算FM中的二次项的过程
AFM
- attention相等于加权的过程,因此我们的预测公式变为
圆圈中有个点的符号代表的含义是element-wise product
- 后面两部分,则是AFM的创新所在,也就是我们的Attention net
- 没经过DNN
DCN
- 提出了一种新的交叉网络,在每个层上明确地应用特征交叉,有效地学习有界度的预测交叉特征,并且不需要手工特征工程或穷举搜索
交叉层:
交叉维度为L层交叉网络层数L + 1
MLR
用分片线性的模式来拟合高维空间的非线性分类面
- MLR在建模时引入了L1和L2,模型具有较高的稀疏度, 模型的学习和在线预测性能更好
DIN
- 用户特征、用户行为特征、广告特征、上下文特征
- embedding之后,使用weighted-sum,即attention
- 评价指标是GAUC
根据用户的展示数或者点击数来对每个用户的AUC进行加权处理
- Dice激活函数。
PRelu、Relu 认为分割点都是0,Dice每一个yi对应了一个概率值pi,pi的计算主要分为两步:将yi进行标准化和进行sigmoid变换
- 自适应正则。针对feature id出现的频率,来自适应的调整他们正则化的强度;对于出现频率高的,给与较小的正则化强度;对于出现频率低的,给予较大的正则化强度
DIEN
- DIN没有考虑用户历史之间的时序关系, DIEN则使用了GRU来建模用户历史的时间序列
- 用户历史肯定是一个时间序列,将其喂入RNN,则最后一个状态可以认为包含了所有历史信息。因此,作者用一个双层的GRU来建模用户兴趣。
- 将用户历史接触过的item embedding微量,喂进第一层GRU,输出的就是用户各时刻的兴趣。这一层被称为Interest Extraction Layer
- 将第一层的输出,喂进第二层GRU,并用attention score(基于第一层的输出向量与候选物料计算得出)来控制第二层的GRU的update gate。这一层叫做Interest Evolving Layer。
- Interest Evolving Layer的最后一个状态作为用户兴趣的向量表示,与ad, context的特征一同喂入MLP,预测点击率。
DSIN
DSIN
主要贡献在于对用户的历史点击行为划分为不同session,对每个session使用Transformer学习session embedding,最后使用BiLSTM对session序列建模
- Session Division Layer是对用户的历史行为划分到不同session
将间隔超过30分钟作为session的划分。
- Session Interest Interacting Layer是学习session之间的表征
相同session内的行为是高度相关的,在session内的一些随意行为会偏离整个session表达。为了刻画相同session内行为间的相关性,同时减小不相关行为的影响。
DSIN使用multi-head self-attention对每个session建模。为了刻画不同session间的顺序,DSIN使用了Bias Encoding
Bias Encoding:
multi-head self-attention:
将第k个session划分为H个head
- Session Interest Interacting Layer是学习session之间的演变
使用双向LSTM建模session之间的演变
- Session Interest Activating Layer是学习当前item和历史点击session的相关性
通过Attention机制刻画Item和session之间的相关性。用户的session与目标物品越相近,越应该赋予更大的权重
MIND
召回阶段建模表达用户的多样兴趣
既然使用一个向量表达用户多样兴趣有困难,那么为什么不使用一组向量呢?具体来说,如果我们可以对用户历史行为的embedding进行聚类,聚类后的每个簇代表用户的一组兴趣
胶囊网络(Capsule Network)
Capsule输入是一组向量,对这组向量进行仿射变换之后求加权和,把加权和输入非线性激活函数得到一个向量的输出
如果我们K个capsule,就会有K个输出向量
MIMN
- UIC的提出:( 背景)存储用户行为序列需要空间太大,且RNN类模型速度慢。(改进)于是构建了一个单独的模块UIC来完成用户行为序列的建模计算工作。UIC server负责存储每个用户最近的行为兴趣,而且UIC server的核心在于其更新策略,即用户行为序列的更新只依赖于具体的触发事件,而不依赖于请求。
- 一方面是NTM中基本的memory read和memory write操作;另一方面是为提取高阶信息而采用多通道GRU的memory induction unit。网络的右侧则为传统的embedding+MLP的经典结构
DMR
DMR(Deep Match to Rank)
通过User-to-Item子网络和Item-to-Item子网络来表征U2I相关性,进一步提升模型的表达能力
工程经验
负采样
负采样带来的问题是CTR预估值的漂移,,比如真实CTR是0.1%,进行0.01的负采样之后,CTR将会攀升到10%左右。而为了进行准确的竞价以及ROI预估等,CTR预估模型是要提供准确的有物理意义的CTR值的。
其中q是校正后的CTR,p是模型的预估CTR,w是负采样频率。大家可以利用简单的转换关系就可以得出上述公式,有兴趣的同学可以手动推导一下。
在线学习算法FTRL
FTRL是对w每一维分开训练更新的,每一维使用的是不同的学习速率,这种方法考虑了训练样本本身在不同特征上分布的不均匀性。(对于稀疏特征很好)。
- predict:L1范数加策略,训练结果w很稀疏,在用w做predict的时候节省了内存(w很小的时候就为0)
- training:先采样减少负样本数目,在训练的时候再用权重弥补负样本;在线丢弃训练数据中很少出现的特征
模型的实效性问题和更新策略
- gbdt为例,GBDT的部分几天更新一次,而LR的部分进行准实时的更新。
- 双塔模型,embedding离线训练存储好,线上实现LR或浅层NN
- PMML。达到End2End训练+End2End部署,PMML的全称是“预测模型标记语言”,是一种通用的以XML的形式表示不同模型结构参数的标记语言。
- TensorFlow Serving。利用TensorFlow自带的模型序列化函数可将训练好的模型参数和结构保存至某文件路径。最便捷的serving方式是使用Docker建立模型Serving API
线上评估方法
必须要考虑位置偏差的存在,避免来自算法A的视频总排在第一位。因此需要以相等的概率让算法A和算法B交替领先