Skip to content

HaochengY/RecommendSystem

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

63 Commits
 
 
 
 
 
 
 
 

Repository files navigation

RecommendSystem

本文档描述了广告/推荐系统的完整链路分析:

  1. 推荐系统的链路:主要介绍双塔模型,粗排模型,精排模型在第三部分详细介绍
  2. 工业界部署的实操:包括从web端发起请求后,客户端从Kafka来的数据在Flink平台的处理,以及HDFS方向来的CTR,标签模型在redis内存数据库里的交互(召回),以及后续排序模型的部署,从而返回客户端推荐结果的全链路,以及相应的大数据技术。
  3. 精排模型,基于Huawei贡献的开源推荐系统包FuxiCTR https://github.com/reczoo/FuxiCTR) 。在此基础上,我使用开源数据Criteo_x1(https://huggingface.co/datasets/reczoo/Criteo_x1/blob/main/README.md) 作为训练,测试数据。按时间顺序和分支归纳并比较了经典推荐系统的算法:
# Model Name Original Paper Link Code Location
0 双塔模型 YouTube对热门物品打压的双塔模型:Sampling-Bias-Corrected Neural Modeling for Large Corpus Item Recommendations -
0 双塔模型 基于自监督学习的对冷门物品的标注: Self-supervised Learning for Large-scale Item Recommendations -
1 协同过滤 - -
2 MF - -
3 LR Predicting Clicks: Estimating the Click-Through Rate for New Ads LR
4 FM Factorization Machines FM
5 FFM Field-aware Factorization Machines for CTR Prediction FFM
6 DNN Deep Neural Networks for YouTube Recommendations DNN
7 Deep Crossing Deep Crossing: Web-Scale Modeling without Manually Crafted Combinatorial Features Deep Crossing
8 PNN Product-based Neural Networks for User Response Prediction PNN
9 Wide&Deep Wide & Deep Learning for Recommender Systems -
10 DeepFM DeepFM: A Factorization-Machine based Neural Network for CTR Prediction DeepFM
11 NFM Neural Factorization Machines for Sparse Predictive Analytics NFM
12 AFM Attentional Factorization Machines: Learning the Weight of Feature Interactions via Attention Networks AFM
13 DIN Deep Interest Network for Click-Through Rate Prediction DIN
14 DIEN Deep Interest Evolution Network for Click-Through Rate Prediction DIEN
15 ESMM (Shared Bottom) Entire Space Multi-Task Model: An Effective Approach for Estimating Post-Click Conversion Rate -
16 MMoE Modeling Task Relationships in Multi-task Learning with Multi-gate Mixture-of-Experts -
17 PLE Progressive Layered Extraction (PLE): A Novel Multi-Task Learning (MTL) Model for Personalized Recommendations -

1. 推荐系统基本链路

召回 -> 粗排 -> 精排 -> 重排

1. 召回模型

召回阶段要从几亿个物品库里返回几万个待选物品。最经典的模型就是双塔模型,YouTube发布的《Sampling-Bias-Corrected Neural Modeling for Large Corpus Item Recommendations》详细的描述了双塔模型以及其最关键的负样本选取策略。

(https://dl.acm.org/doi/pdf/10.1145/3298689.3346996)

首先将用户信息和物品信息分别训练成两个塔,将其特征embedding后输入两个DNN层后获取两个代表该用户或该物品的抽象的向量。然后计算这两个向量的余弦相似度,来作为两者的关系,关系越大就认为用户更有可能喜欢这一物品。我们将输出的结果视为一个二分类问题(注意排序模型和召回模型的区别,我们这里只需要判断用户喜不喜欢就行了,多喜欢不是我们考虑的内容,所以用户点击了就视为喜欢)。根据这一label,反向更新两个塔里面embedding层和DNN层的参数。

召回模型的架构简单,且不需要过度改进,与其改变架构,不如改标负样本的选取,负样本做好了,模型效果就好。我们可以进行多种方式的训练:

  1. pointwise,输入是一个二元组:(user,item)。我们将分类视为二分类,由于余弦相似度的范围在-1到1中间,我们就让用户与正样本接近1,与负样本接近-1,以这种思路构建损失函数即可,一般用交叉熵就好了。 经验来讲,大概控制正负样本的比例在1:2或1:3
  2. pairwise,输入是一个三元组:(user,positive_item,negative_item),两个item都是从物品塔的embedding层出来的。然后分别计算用户与正样本和负样本的余弦相似度,分别使其靠近1和-1,这样看来和上面的pointwise并无区别,但实际还要多加一条:需要让正样本的兴趣远大于对负样本的兴趣,即,如果cos(a,b+) > cos(a,b-) + m,才视为没有损失,类似SVM hingle loss。 Loss = max{0, cos(a,b-) + m - cos(a,b+)} 或 log(1 + exp(\sigma (cos(a,b-) - cos(a,b+))))
  3. listwise, 输入包括一个用户,一个正样本,和n个负样本。把他们都输入softmax层,我们希望正样本足够接近1,其他的负样本都接近0。之后进行交叉熵就可以了,虽然这样看起来是个n分类的交叉熵,但是计算起来非常简单,因为负样本的label是0,正样本是1,化简完就能发现负样本那n个都是0了,Loss = - log (s+), where s+ 是正样本余弦相似度经过softmax后的得分,也就是直观的看起来,他越靠近1越好。

注:Youtube发现物品呈幂律分布,即少部分热门物品占据了大量的点击,就会导致热门物品总能成为正类,导致正样本的得分非常接近1,其他物品非常接近0,这会让热门更热,冷门更冷。解决办法就是对热门物品进行打压,或对冷门物品进行过采样。 打压的方法:将余弦相似度的得分监区一个概率因子,即点击率越高,对其施加一定的惩罚, cos(a,b_i) => cos(a,b_i) - log(p_i)

此外,处理这样打压,还可以用自监督学习的方法:《Self-supervised Learning for Large-scale Item Recommendations》 (https://dl.acm.org/doi/10.1145/3459637.3481952) 用自监督学习,具体来说是对比学习,训练物品塔

具体操作是,通过数据增强,对每一个物品bi都生成两个向量bi‘和bi’‘,因为他们都是基于bi生成的,所以bi’和bi‘’应该足够相似,反之bi‘和bj’‘应该都不相似,通过这种方法接入softmax进行训练,同理最后负样本标签是0使得其他项也都消掉了,就变成-log(si,i)。实际效果非常好,落地就有效果,尤其是冷门物品。具体工程上实现是抽取n个真实的有点击的物品,再抽m个随机物品,计算n个物品的双塔模型loss,再加上m做的自监督模型的损失,就是整体损失。

现在,训练框架和损失函数都有了,接下来就介绍最重要的负样本选取部分了。根据推荐系统的链路,我们可以从下面几个角度寻找负样本:

  1. 简单负样本:未被召回的数据作为负样本,由于召回是从几亿里面返回几万个,所以召回的样本比例极小,(0.01%)。因此,从没被召回的笔记里(99.99%)抽样作为负样本和直接从所有物品里抽样几乎没有任何区别,因此可以直接从库里抽样作为负样本。这样有一点问题:由于极少数热门物品占据了主要市场,除了热门的那几个剩下的都是冷门物品,此时随机抽样,几乎抽到的都是冷门物品。现在热的本来就容易成为正样本,一抽样抽出来的还都是冷门物品来作为负样本,这太不公平了,更加加深了头部效应。因此,我们在抽样的时候不可以均匀抽样,而应该非均匀的,负样本抽取的概率应该与点击次数正相关 常见的方法是 抽样概率 正比于 点击次数的0.75次幂。
  2. 困难负样本:召回但被粗排淘汰的,此时只能说明用户不够喜欢,但不能说不喜欢,同理,被精排淘汰的更难分辨。 因此,使用简单负样本会导致模型训练起来准确度极高,但是也不能完全不考虑困难负样本,不能难分辨就不分辩了,常见的做法是把简单的和困难各占50%的混合了,让简单负样本带着困难负样本玩。

工程上实现:物品的属性基本不变,所以完全可以离线计算,然后放在向量数据库里。但是用户就不行,用户兴趣变化太快了,要线上实时计算,然后用这个向量去物品数据库里逐个相乘,找到相似度最高的K个物品向量。但是这个缺陷显而易见,由几亿个物品,那你要计算几亿次才能排序出来,根本做不到实时计算。我们需要算法来加速这一过程,比如 最近邻查找。我们用余弦相似度来衡量距离。 具体步骤:将数据预处理,提前划分好区域,每个区域用一个向量来表示,可以是均值,也可以是其他的规定。现在简历key-value map。将这个区域向量作为key,该区域内所有点作为value。这样就可以通过key映射到value上

IMG_28BECD0AD0FD-1

还可以进行增量更新来捕捉实时兴趣,只更新embedding层,而不更新DNN,DNN只有在离线全量更新时才更新参数。

2. 粗排模型

粗排模型的复杂度介于召回和精排之间,比较常见的就是三塔模型

截屏2024-09-29 16 56 52

三塔模型从本质上来看很像Deepcross模型,其实粗排模型只要用简单的精排模型一样可以实现,例如MF,FM,LR都可以。

3. 重排

在每次精排和粗排后都会进行一次重排,来保障两个优化目标:得分的和最高,以及多样性足够多。

这里比较直观的生成多样性的方法就是通过为item生成不同的标签,通过标签可以显著地区分开样本。然而标注标签其实需要比较多的操作,对于视频或笔记类item,比较直观的是通过其图文来进行生成label。

2. 推荐系统与大数据工具部署的结合

本节将推荐系统按照实时性要求的区别分为

  1. 高实时性:例如视频,电商推荐系统,这里一般用是否点击来作为label
  2. 低实时性:广告推荐系统,这里通常使用eCPM计算来作为label

image

主要步骤分为:

  1. 将数据通过埋点处获得的数据通过kafka获取,在Flink处进行系列操作生成实时的用户向量。接下来一支落入HDFS系统,另一支进入redis,这里获得的事实时向量,可能包括实时兴趣,上下文信息,等等;另一支从hdfs中提前输入到redis,然后将二者拼接后输入用户塔模型生成用户向量。redis里储存了item向量,这样就可以进行最近邻匹配去寻找比较相似的物品,这样得到的就是召回模型。
  2. 对召回的结果进行排序,即可获得排序后的模型
  3. 重排:推荐系统中可能会使用多样性来再加工一下,在广告系统中,有些广告商指明要只投一些广告,或根据产品业务线规定,只能投指定的内容。
  4. 返回给客户端。

序1 FuxiCTR

FuxiCTR 内部的函数封装的非常好,在使用其推荐函数前,我们必须对其封装的逻辑进行理解,这样才能更好地分析算法的底层逻辑,以用于后续的调优和架构改进。

Step1:导入参数

由于推荐系统中的超参数非常多,FuxiCTR支持通过yaml文件导入模型参数,具体分为dataset parameter list 和 model parameter list.

  1. dataset 中的参数包括训练集,测试集和验证集的文件路径,所选列的类型等信息。
  2. 模型参数,包括隐藏层,早停,训练次数等等所有参数,只需在这里调整yaml文件即可实现对模型架构的直接调整。

Step2:数据预处理

使用FeatureProcessor对数据进行预处理,包括设置NA的填充值,padding用的值,此外还支持高级选项,同样可以在yaml里通过设置参数来进行修改。

Step3:DataLaoder的创建

无论输入的类型是csv,npz或是分布式文档,输入之前都会被转化成parquetLoader,这一结构支持列储存,极大的增加了读写对内存的需求(都被存储成了npz文档备份) 文章中贯穿全文的就是FeatureMap类,这一类记录了特征的所有信息,包括内容,类型,转化方式,所有信息都会储存在这里。对于str或categorical类对象,他会先对数据进行tokenize,将字符映射为字母表,再进行embedding操作。这一过程也可以进行高级设置,可以通过设置阈值来过滤掉出现频率过低的词。

Step4:模型训练

训练,验证,测试,早停。

序2 推荐系统背景

随着Google和Amazon的兴盛,无论是搜索引擎的广告亦或是电商平台的推荐都对算法工程师提出了挑战,如果能够准确的预测出用户的喜好,那么广告和物品都将更受用户喜欢,可以提高用户满意度和收入

1. 协同过滤

在推荐系统算法出现以前,比较流行的是基于物品或用户的协同过滤,通过计用户-物品矩阵来获取用户对物品的潜在喜好。 然而

  1. 若有n个用户和m个物品,那么矩阵的维度将会变为n*m维,随着大数据的发展,这一量级将会变得无法接受,计算和储存效率会大大降低。
  2. 该矩阵本质上类似相关性矩阵分析,只考虑了物品和用户之间的联系,认为矩阵的余弦相似值较近的物品、用户是相近的,进而为其推送。这一方法不仅没有考虑特征交叉问题,同时,这一矩阵会非常稀疏,计算起来很困难。

2. MF (Matrix Factorization)

矩阵分解的提出解决了协同过滤中矩阵稀疏的问题,通过计算隐向量来解决稀疏性。通过将user-item matrix 拆解成 item matrix and user matrix 的乘积。这一方法在数学上可以使用SVD来求解,但是过于复杂,我们可以使用基于SGD的数值分析来近似两个矩阵,这一方法的作用不只是解决了稀疏性,hidden vector的产生类似于embedding技术的前身,他是基于全局信息的,每个vector中都还盖了全局信息,他比协同过滤中仅用相似度来作为衡量相似性来说,包含了更多的信息。

这一操作虽然将计算复杂度从n方降到了n(m+k), 在性能上有了很大的提升,且能包含更多的隐藏信息,但是他还是只基于用户和物品的,没法引入上下文,等其他关系

3. LR (Logistic Regression)

原文链接:(https://dl.acm.org/citation.cfm?id=1242643) 在此基础上,为了引入更多的特征,得到更为全面的推理,微软提出逻辑回归来综合考虑多个特征。

LR的内层很简单,先将输入的参数中cate类的embedding,再输入线性回归层,最后接入sigmoid得到结果。 代码实现见 /model_zoo/LR

逻辑回归的架构简单,且能考虑不同的特征,且逻辑回归本质上就是返回一个概率值,这在CTR问题中如出一辙,我们就是要预测用户是否会发生点击。且其训练速度快,导致在实际工程上,除非其他模型对他的提升非常大,我们都不会使用。然而,其架构简单的弊端就在于,他无法更深层次的学习到潜在的信息,且逻辑回归本身就是个linear regression plus sigmoid function, 没有考虑特征交叉,可在google和amazon的多篇文章都提到了特征之间的强相关性。因此,为了考虑特征交叉,FM被引入了。

4. FM (Factorization Machines)

FM 和LR 之间其实还有个过渡版本:poly2,poly2本质上还是线性模型,只不过给没个变量Xi都构建了 XiXj 二阶因子,比较暴力,而且这种显示的靠相乘来交叉,对于数值的还行,但是对于cate类的,你不论是embedding还是one-hot,处理完的数据只会更sparse,得不偿失。 而且这样一来参数上了一个数量级,所以几乎没人用。

因此,需要一种更好的特征交叉的方法,他不应该是暴力的,而是巧妙的。 天空一声巨响,FM系列老大哥FM本人闪亮登场!

我们在MF中提到,用hidden vecor 分解 user-item矩阵可以降低计算复杂度且捕捉潜在信息,但是它的缺点是矩阵里的信息只有用户和物品,如果我们转而分解多个特征构成的matrix,不就可以既使用hidden vector 来降低复杂度,同时还能考虑不同特征之间的关系了! 此外,这一思想在数学上是等价的,poly2为每个二阶项都计算wi,如果有n个特征,他们的交叉项个数就是n方个,我们不用计算出这种显式的特征间的权重,反而可以用 隐向量内积 来作为权重!这一操作直接将复杂度从n方降到了nk,当n非常大的时候 k会远小于n,这个降维是空前的。 此外,这一方法极好地解决了数据的sparse问题,这是因为,同一特征的隐向量是共享的,及大地降低了计算开销。

在FuxiCTR中,模型在FM层的基础上还加入了一层线性层,即将MF捕捉到的交叉关系和简单线性回归后的结果相加,从而保证一定程度的鲁棒性,这一层可以根据实际数据进行调节。 工程上实现FM层,数值之间的交叉很简单,我们主要介绍embedding向量之间的交叉,我们将平方和 和 和平方的差的和作为输出结果: 对于一个(128,26,4)的tensor,先将他们的26个特征用平方和 和 和平方 合并成一个符合特征,此时变为 (128,4),最后把embedding的每个元素相加,变成一个(128,1)的tensor,即输出结果,这一过程是从数学推导来的。最后将fmout和lrout相加,就得到了即考虑一阶项,也考虑了二阶项的结果。 代码实现见 /model_zoo/FM

5. FFM (Field-Aware FM)

原文链接:(https://dl.acm.org/doi/pdf/10.1145/2959100.2959134) 由于FM中所有的特征都共用一套隐向量,FFM在它的基础上引入了field的概念,使得模型在不同交叉的时候能够采用不同的隐向量。这一方法更好地优化了性能,但是也让模型复杂度变为了 nkf 通常域的个数就等于特征的个数,复杂度就变为了 n方k。 工程上实现方法,为不同的field之间生产多套隐向量,然后用vij和vji的逐元素乘的和作为最终输出。再和lr的输出相加。

上述五种系统都不涉及深度学习,随着时间来到2016年,深度学习引爆市场,市面上开始涌现出各种系统。

6. DNN

在介绍经典的深度模型Deep Crossing 前,我们先讲一下他的”青春版" DNN. 原文链接: (https://static.googleusercontent.com/media/research.google.com/zh-CN//pubs/archive/45530.pdf) image

DNN的架构非常简单,通过将数值直接输入,再将embedding后的向量暴力的水平拼接到一起,输入到MLP里,返回结果 这在工程上也非常容易实现,首先对于水平拼接,只需要设置参数为flatten=True, 对于MLP,就是简单的一层线性层,一层激活层...

7.Deep Crossing

DeepCrossing 作为DNN的升级版,无非就是一个地方:将MLP换成了ResNet

原文链接: (https://www.kdd.org/kdd2016/papers/files/adf0975-shanA.pdf)

image

这一结构看似简单,但是站在当年的角度,这是第一次完全没有进行任何特征处理的方法,从embedding层到MLP层,全部由DL完成,传统的FFM,FM,LR模型最多也就是二阶交叉,Deepcrossing可以做到深度交叉,这是革命意义的。

8. PNN

在DNN的基础上还能另一个分支改动,改变embedding层的交互方法,使其不再是简单的concat拼接,而是采用乘积

原文链接: (https://arxiv.org/pdf/1611.00144)

具体来说,这里还是用了一些一阶+二阶的思想的,输入一部分是直接进来的embeddingvector,另一部分那是他们的内积、外积(所以PNN分为IPNN和OPNN随着内积和外积的选择不同)。 这一模型使得人们开始关注特征向量之间在输入DNN之前的交叉行为。

综上所述,DNN,DeepCrossing,PNN都是使用了深度学习网络对特征进行深度交叉。这是传统模型无法达到的效果,然而,对所有特征进行无差别交叉一定程度上忽略了原始特征中包含的有价值的信息,如何权衡原始向量和交叉他们,是一个重要的研究方向。

image

9. Wide&Deep

这一模型是基于真实业务的灵感,谷歌商店中安装A应用的人更容易安装B,这一简单的逻辑当模型经历Deep层之后,就会被过分地泛化,导致这一明显的联系被忽略,这就是我们之前所提到的,对所有特征无差别交叉一定程度上忽略了原始特征中的信息。解决方法是,我们既使用深度网络,又使用简单的模型,从而同时获得记忆能力和泛化能力。这就是Wide and Deep的思路。

原文链接: (https://github.com/HaochengY/RecommendSystem?tab=readme-ov-file)

image

工程上实现起来也非常简单,只需要先将X接入一个线性回归层,再让Xembedding后接入一个DNN结构,最后二者的和就是输出值。

Wide&Deep模型的影响力是空前的,从提出到今天一直活跃在各大互联网公司的算法结构中,他的优点如下:

  1. 他的本身结构并不是特别复杂,工程上比较容易实现
  2. 其根本就是从业务出发的,WideandDeep模型融合了传统模型的"记忆能力"和深度学习模型的"泛化能力"。

事实上,DeepFM和NFM等FM家族后续的提出都是基于WideandDeep的变体。

10. DeepFM

原文链接:(https://arxiv.org/pdf/1703.04247)

截屏2024-09-28 10 41 49

先说DeepFM,Wide&Deep在推出后在业界引起了巨大的轰动,但是归根结底,其在google play中取得优异的成绩是因为google的业务人员在筛选wide的时候做出了足够精准的判断,如果对于普通人来说,如果wide层选择的特征或进行的特征工程不够好的话,效果未必会特别好,因此,DeepFM秉承着推荐系统一贯的宗旨:完全摆脱专家进行的人工特征工程,做一个end-to-end的完全由神经网络计算的模型。

只有Wide部分的选择是基于人工的,因此,将wide部分替换成了FM部分,就是DeepFM的核心思路了。 与WideDeep相比较,Wide中的input没有进入embedding层,二DeepFM中的所有input都通过embedding层生成hidden vector,再输入模型。 工程上实现起来也非常简单,全部接入embedding曾,然后再把FM层和DNN层的结果加和即可得到output。

这一模型的出现,使得使用者完全不需要进行任何基于业务的理解。

11. NFM

在基础模型中的FM中,无论FM还是FFM,归根结底都只是二阶交互的结果,二阶的复杂度已经大于等于n方,因此无法扩展到更高阶上,随着DL的发展,DNN可以无限逼近任何一个复杂的函数,因此,如果我们把FM中二街交叉的部分直接用f(x)来代替,即可实现与神经网络的结合。 此时NFM的计算为 一阶线性交叉和 + DNN得出的f(X), 不难看出,这和Wide&Deep的公式没有一点区别,这也是我们说NFM,DeepFM都是从WD衍生出来的。 但是,并不完全相同,NFM的DNN部分,在embedding和DNN之间还有一层 池化层,也叫特征交互池化层。Bi-interaction Pooling Layer。 这里的操作就是将不同特征逐元素乘再求和,工程上还可以用平方和 - 和平方 在除2的方法得到输出结果。

对FM的阶段性总结

首先最原始的FM模型是为了解决Poly2模型中构建的二阶特征交叉参数过多的问题而设计的,通过引入hidden vector, 将他们的内积作为wi,极大的降低了计算强度。然而FM能保持这样低的计算需求是因为他用同一个隐向量表征所有该特征下的元素,但是往往不同特征在交叉时的规则应该是不一样的,一味增加hidden vector的维度似乎可以挖掘出更多潜在信息,但这是不稳定的且不根本的。例如,媒体特征和性别,广告商交互时效果一定不同。这就导致了我们对field的思考。

FFM 通过考虑field的概念,使得特征不再是生成一个隐向量,而是生成一组隐向量,且在初始化的时候为每一个feature再额外标记一个field tag,在特征交互时会根据field的不同从而选择不同的vector来交互。但这样一来,通常在工业中,每个feat都会对应一个field,这就会导致复杂度变味了n * k * n, 复杂度甚至高出了MF的 n 方, 不过显而易见,这一方法确实能够捕捉到更好的效果,在实际生产中,要根据效果和计算成本来权衡。

然而,无论FM还是FFM,都只能在二阶上进行交叉,在拓展到更高阶时还是不可避免地会产生参数爆炸。随着深度学习的崛起,这一问题似乎得到了缓解,如果直接用一个深度网络来代替交叉部分,那么这样一来不仅可以规避繁杂的数学公式,还能进行更高阶的交叉,这就是NFM。

NFM可以拆成两部分,一阶的线性回归 + DNN,这种模型拆分的思路和wide and deep 不约而同,然而wide部分需要进行人工特征工程,对于不懂业务的人来说比较困难。在他的基础上,我们用FM层代替wide层,即可实现模型的自动特征工程。

至此,无论是双模型选取,还是改变DNN层数,或是特征工程的改变,似乎对模型的提升已经陷入了瓶颈,换句话说,人们对FM的开发已经到了极限,再进一步的提升只能从模型的根本架构入手。

12. AFM

https://www.ijcai.org/proceedings/2017/0435.pdf)

截屏2024-09-28 12 39 45

随着 Attention is All You Need 横空出世,注意力机制席卷整个深度学习领域,NFM在池化层只是简单的对所有交叉特征加和,值实际上就是一个平均的思想,即给所有交叉权重赋予平等的权重,而注意力的引入就允许模型能够根据数据自适应地为自己分配权重。

具体来说,对于26个特征,bs=128,emb=4 (128,26,4)例他们的交叉就有n*(n-1)/2 = 325 个交叉特征,每个交叉特征都是隐向量vivj xixj。我们要为他们分配权重。 在这里的注意力计算为,将交叉特征输入一个DNN,例如(128,325,4)-> (128,325,1) 得到了一个一维的,也就是每个向量的权重。把这个权重和交叉特征相乘,就相当于利用自己的数值给自己分配权重,从而放大或缩小自己的特征,实现self-attention。乘上weight后,仍为(128,325,4),此时再加和,就实现了和NFM一样的效果,只不过 NFM是平均和,而AFM是加权和。,输出结果是(128,4)此时的afmout就是经历了结合注意力后的DNN输出结果,与一阶结果相加就是最终结果了。

这是第一次引入Attention到推荐系统中,之后更多的模型如雨后春笋般涌现。至此,特征交叉类模型差不多到此为止了,接下来我们将介绍序列型变量是如何引入到推荐系统的。

13. DIN

https://dl.acm.org/doi/pdf/10.1145/3219819.3219823)

DIN模型源于阿里巴巴,是个纯业务驱动的模型,阿里的广告推荐认为,一个广告与用户的购买或浏览序列是相关的,买了鼠标的用户更有可能看键盘。阿里提出了一个base模型,该模型简单的将过去的序列(物品序列)以及待推荐的广告序列拼接在一起输入到MLP中。这一想法有个显著的缺陷:

  1. 简单的拼接使得物品和广告没有任何交叉
  2. 不是用户的所有浏览记录都有用的,即我们需要分配注意力来分配权重 这就是DIN的具体思想:
截屏2024-09-28 16 01 43

我们在工程上可以这样实现:首先计算出包括用户基本画像,购买的商品记录(sequence)以及广告记录,把他们都embedding后待用。现在,我们的embedding好的向量大致分为:

  1. 用户画像向量
  2. 广告的上下文向量
  3. 用户浏览记录的序列向量
  4. 广告的基础信息的向量

对于1,2,我们不需要处理,但是3与4需要交叉,且分配注意力。即为每个广告对用户过去的浏览记录都分配一个权重,100个数据,时间长度为5的话,就是500个权重。 FuxiCTR在处理权重的时候还是用了一个复合的方法:将embding维度用组合方法扩散了四倍,在用一个全连接层转化回一维,为计算注意力丰富了特征。 最后将注意力得分与原始embedding向量相乘,就得到了结合注意力的,交叉后的新embedding向量,对原有的embedding向量进行更新。值的一提的是,五个注意力计算后的tensor是(100,5,4),还介入了一个pooling层,变为(100,1)。这一机制使得所有时间窗口的信息被聚合,且允许序列输入不同长度的窗口,因为不管多长,最后都会被聚合为(bs,1)。

且所有din模型的激活函数都是用了dice,具体是将输入batch norma后,再介入prelu函数,这样可以有效避免ICS问题,加速收敛速度,提升性能。

然而,正如作者所言,我们也可以发现,对于点击序列,其实他的顺序是有时间性的,换句话说,用户的兴趣是会随着时间演化的,因此,对于DIN中的历史记录,即使使用了注意力,也没有很好地用到时间序列性质。作者尝试了加入LSTM,但是并没有明显的提升,但这已经为我们指明了未来的研究方向,Alibaba也没有停下脚步,一年后,DIN的升级版DIEN诞生了。

14. DIEN

https://arxiv.org/pdf/1809.03672)

截屏2024-09-28 21 15 09

DIEN模型真正做到了用时间序列模型对用户的兴趣演化进行建模,兴趣进化网络分为两步:兴趣抽取和兴趣进化。

  1. 兴趣抽取,和DIN一样,我们先对用户的historical behaviour进行embedding,将embedding作为时间序列输入GRU。这里为了节约计算开销,FuxiCTR还做了优化,由于用户的点击记录是稀疏的,很多用户都没有发生点击,他们的该特征都是0:【0,0,0,0,0】 这样的数据对我们的训练纯没作用,甚至还引入了噪声,因此我们只对有数据的记录进行了GRU训练,我们将GRU得到的每一次hidden state都记录下来备用。至此,我们已经将用户的兴趣抽象成了一个一个hidden state。

此外,DIEN的贡献不止于此,传统的GRU分类任务只用最后的ht结果作为loss函数的输入,然而,中间的隐状态根本没有被考虑,因此DIEN还是用了真实的下一次的数据来作为每个阶段预测值的评判标准,做到了对每一次隐状态的监控。还有!由于推荐,广告业务中存在严重的样本不平衡性,我们在训练数据中甚至引入了一列“未点击的广告”,作为负样本,并将loss函数多加了一项副样本的惩罚,转化为Auxiliary Loss。

2.兴趣进化层, 我们将广告特征与GRU输出的每个结果都计算注意力, 然后将注意力得分和原数据一同输入AUGRU中,AUGRU就是在GRU的基础上,再update gate上加入一个注意力得分,最后的输出就是兴趣层的输出,之后就和DIN一样了,将其他用户画像和上下文信息concat后接入MLP输出结果。

这一模型正式引入了序列模型,使得时间信息充分得到分析。

有了 DIN和DIEN这两篇开山之作,后续出现了更多的序列模型。

接下来,我将归纳另一个分支:多目标学习,该学习模型最早由谷歌提出--MMoE,后来又出现了鹅厂提出的PLE模型。

15.MMoE

2018年出现了两篇关于多任务学习的论文:MMoE和ESMM,分别由google和阿里巴巴提出。

他们的benchmark模型是简单的共享层模型,多个任务共用一套embedding layer,之后进入不同的tower,即不同的DNN里。对每个子任务分别计算损失函数Li,然后用L=wiLi 来作为整体的损失函数,饭回来更新所有参数,包括各个塔里面dnn的参数和embedding层里的参数。多任务学习利用了任务间的相似性和共享性,模型通过数据的共享和迁移可以学习到任务间的相关性。 这样一来,就有了很多优势:

  1. 多个任务只需要学习同一套embedding参数,可以减少大量的运算。
  2. 此外,如果A和B任务很相似,但A的数据特别少,直接学习A效果很差,但B的特别多,我们可以通过学习B任务来反向更新shared bottom,从而间接学习到A任务。
  3. 多个子任务的数据集合并到一起使用,这样可以丰富数据集
  4. 由于需要兼顾多个子任务,这样可以类似一种正则化,减少过拟合风险。
  5. 部署,维护起来也比较方便,只需要部署一个模型就可以了

其中2和3这就是ESMM的思路,ESMM模型是被设计为处理CTR和CVR问题的,电商转化链路为:曝光 -> 点击 -> 转化。 CTR的样本非常多,因为这一链路是按照漏斗逐渐递减的,曝光的样本非常多,因此使用点击和曝光数据训练CTR模型的数据很充足。反而,点击的样本就少了很多,那么转化的样本就更少。这样CVR训练起来就会很难。 但是这一业务存在明显的数学表达关系:CTCVR = CTR * CVR 转化率/点击率(CVR)*(点击率/曝光率)(CTR)=(转化率/曝光率)CTCVR 可以发现CTR和CTCVR的样本是非常多的,因为它可以在整个曝光数据集上采样,CTR中点击了的样本是1,没点击的是0 CTCVR中点击且转化的是1,没有的是0,通过CTCVR和CTR就可以间接计算出CVR。

截屏2024-09-29 10 25 37

因此,我们通过一套共用的embedding layer,分别给出两个任务,预测CTR和CVR,并将CTR*CVR得到的CTCVR和CTR这两个指标作为label,这样可以用最多的数据获取最大的训练效果。之后间接计算出CVR。这一问题只适用于曝光 -> 点击 -> 转化这一链路,并不泛化,但是在电商上效果良好,而且可以迁移到其他的推荐系统中,但似乎这一模型只能同时学习CT 和CVR,像观看率,点赞收藏等就没法进行了。

ESMM从本质上来讲像是一种特例化的shared bottom model--多任务学习的基础模型。这一模型最大的问题就是当上层的任务极不相关的时候对模型性能的影响非常大,但是ESMM里这两个任务的关联极强,所以效果很好。

工程上的实现:首先将所有的输入都embedding,然后输入shared bottom,这里的sb就是一个非常大的DNN,之后将输出分别输入各个tower,获得各个塔的loss,然后相加,反向更新参数。

和他同期的MMoE似乎从另一个更general的角度进行多任务分析。

截屏2024-09-29 10 03 25

MMoE和shared bottom之前还有一个OMoE版本,就是讲一个shared bottom,即一个专家扩展成3个专家,这3个专家回生成三个预测结果,接着为了自适应选取这三个专家,还为他们分配了权重,即注意力,然后再输出一个结果,传入tower里。

但是现在只是综合了各个专家的意见,但是并没有做到对各个子任务提出自己的特殊意见,专家只是对所有子任务提出一个同样的意见。对于不同的子任务,应该是用不同的权重结合专家们的意见,即,对每个子任务都用一个gate来生成权重。

工程上实现也很简单,就生成个softmax来给他们赋权重就好了。

16.PLE

PLE是在MMoE基础上由腾讯提出的升级模型,其大致思路沿用了MMoE中多专家的思想,但是该模型将专家分为了私人专家和共享专家,共享专家为每一个子任务给结果,私人专家只为自己的任务给结果。

截屏2024-09-29 11 57 52

这个就是CGC,多层CGC就是PLE

截屏2024-09-29 12 24 49

About

No description, website, or topics provided.

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published