推荐系统-推荐模型总结

基础

推荐系统一般包含哪几个环节

工业推荐系统一般包含四个环节,分别是召回、粗排、精排和重排。

  • 召回阶段根据用户的兴趣和历史行为,从海量的物品库里,快速找回一小部分用户潜在感兴趣的物品,然后交给排序环节
  • 排序环节可以融入较多特征,使用复杂模型,来精准地做个性化推荐。有时候因为每个用户召回环节返回的物品数量还是太多,怕排序环节速度跟不上,所以可以在召回和精排之间加入一个粗排环节,通过少量用户和物品特征,简单模型,来对召回的结果进行粗略的排序,在保证一定精准的前提下,进一步减少往后传送的物品数量,粗排往往是可选的,可用可不同,跟场景有关。
  • 之后,是精排环节,使用你能想到的任何特征,可以上你能承受速度极限的复杂模型,尽量精准地对物品进行个性化排序。
  • 排序完成后,传给重排环节,重排环节往往会上各种技术及业务策略,比如去已读、去重、打散、多样性保证、固定类型物品插入等等,主要是技术产品策略主导或者为了改进用户体验的。

参考文章

CTR预估模型的数据特点

CTR预估模型数据特点

  • 输入中包含类别型和连续型数据。类别型数据需要one-hot,连续型数据可以先离散化再one-hot,也可以直接保留原值
  • 维度非常高
  • 数据非常稀疏
  • 特征按照Field分组

CTR预估重点在于学习组合特征。注意,组合特征包括二阶、三阶甚至更高阶的,阶数越高越复杂,越不容易学习。Google的论文研究得出结论:高阶和低阶的组合特征都非常重要,同时学习到这两种组合特征的性能要比只考虑其中一种的性能要好。

那么关键问题转化成:如何高效的提取这些组合特征。一种办法就是引入领域知识人工进行特征工程。这样做的弊端是高阶组合特征非常难提取,会耗费极大的人力。而且,有些组合特征是隐藏在数据中的,即使是专家也不一定能提取出来,比如著名的“尿布与啤酒”问题。

在DeepFM提出之前,已有LR,FM,FFM,FNN,PNN(以及三种变体:IPNN,OPNN,PNN*),Wide&Deep模型,这些模型在CTR或者是推荐系统中被广泛使用。

参考文章

召回

介绍下协同过滤

1. 概述

基于协同过滤的推荐算法可以划分为两部分:

  • 基于近邻的协同过滤
  • 基于模型的协同过滤

其中基于近邻的协同过滤又可以被划分为:

  • 基于用户的协同过滤(UserCF)
  • 基于物品的协同过滤(ItemCF)

基于近邻的协同过滤算法是指记住每个用户消费过什么东西,然后推荐给他相似的物品(ItemCF)或者推荐与他有相似喜好的人所喜欢的东西(UserCF)。基于模型的协同过滤算法则是从用户和物品的关系矩阵中学习一个可以泛化的模型,从而将那些矩阵空白处填满。

当一个推荐系统度过了最初期的冷启动阶段后,就能够拥有了一定可观的用户行为了。这些用户行为或明或暗地表达了他们对一些物品的喜欢程度,这些行为可以构成一个用户与物品的关系矩阵(Matrix)。这个关于用户和物品的关系矩阵中填充的就是用户对物品的态度,但不一定每个位置都有内容,而我们需要做的就是把那些还没有内容的空格填充上。需要注意的是,这个关系矩阵是协同过滤算法的”命根子“,一切工作都围绕着这个关系矩阵来进行

2. 基于近邻的协同过滤算法

所谓的协同过滤算法,顾名思义,就是协同大家一起来对海量的信息进行处理过滤,从中筛选出目标用户可能感兴趣的信息的推荐过程。

2.1 基于用户的协同过滤算法(UserCF)

UserCF其实就是一个给用户聚类的过程,把用户按照兴趣口味聚类成不同的群体,给用户的推荐就来自于这个群体。所以要做好这个推荐关键就在于如何量化”口味相似“这个看起来很简单直接的事情,这关系到用户对推荐系统体验好坏的问题。

从上面的例子来说,基于用户的协同过滤算法主要包括了两个步骤:

  1. 找到和目标用户兴趣相似的用户合集
  2. 找到这个集合中的用户喜欢的,且目标用户没有见过的物品推荐给目标用户

第一步:关键就是计算两个用户的兴趣相似度。为此,我们需要先准备用户向量(可以直接从关系矩阵中取),然后两两计算用户向量的相似度。同时,我们需要设定一个相似度阈值或者一个最大数量,为每个用户保留与其最相似的用户。

第二步:在经过第一步的计算之后,我们就得到了一个和目标用户兴趣相似的用户合集,接下来就是用户最爱的推荐环节…把和他”臭味相投“的用户喜欢的物品汇总起来,去掉用户已经消费过物品,剩下的排序就是推荐结果。这里说一下汇总的方式,我们用一个公式来表示:
P u , i = ∑ j n ( s i m u , j ∗ R j , i ) ∑ j n s i m u , j P_{u,i} = \frac{\sum_j^n(sim_{u,j} * R_{j,i})}{\sum_j^n sim_{u,j}} Pu,i=jnsimu,jjn(simu,jRj,i)

公式说明 u u u 表示用户 u u u i i i 表示物品 i i i j j j 表示用户 j j j n n n 表示总用户数, s i m u , j sim_{u,j} simu,j 表示用户 u u u j j j 的相似度, R j , i R_{j,i} Rj,i 表示用户 j j j 对物品 i i i 的评分, P u , i P_{u,i} Pu,i 表示预估用户 u u u 对物品 i i i 的评分。
公式解读: 这个公式等号的左边是计算一个物品 i i i 和一个用户 u u u 的匹配分数,等号右边是这个分数的计算过程。分母是把和用户 u u u 相似的 n n n 个用户的相似度累加起来,分子是把这 n n n 个用户各自对物品 i i i 的态度按照相似度加权求和,这里的态度最简单的就是”0“和”1“,”1“表示喜欢,”0“表示不喜欢,如果是评分的话,则可以是0~5之间的取值。整个公式的结果就是相似用户的态度加权平均值

最后,想说的是基于用户的协同过滤算法有以下两个产出:

  • 目标用户的topK相似用户
  • 目标用户的推荐物品结果

所以我们不但可以推荐物品,还可以推荐用户!比如在一个社交平台上看到的”相似粉丝”和你“和你口味相似的人”等等。

基于用户的协同过滤算法(UserCF)有其弊端:

  • 在互联网应用场景下,用户数量往往远大于物品数量,这就导致维护和存储这些相似度矩阵的开销非常大
  • 用户的历史数据向量往往非常稀疏,对只有几次购买或者点击的用户来说,找到相似的用户准确度是非常的低的
  • 用户的兴趣爱好是会变化的,不是静态的,所以兴趣改变问题很难被反映出来

2.2 基于物品的协同过滤算法(ItemCF)

由于UserCF存在上述三点缺陷,所以在业界更多还是采用ItemCF,比如Amazon、Netflix、Hulu等等。

ItemCF是通过计算用户关系矩阵中物品列向量的相似度得到物品之间的相似矩阵,再找到用户的历史正反馈物品的相似物品进行进一步排序和推荐,ItemCF的具体步骤如下:

  1. 基于用户历史数据,构建用户关系矩阵
  2. 计算用户关系矩阵两两列向量间的相似性(计算方式与用户相似度计算方式相同),构建 n ∗ n n * n nn 维的物品相似度矩阵
  3. 获得用户历史行为数据中的正反馈物品列表
  4. 利用物品相似度矩阵,针对目标用户历史行为中的正反馈物品,找出相似的Top k个物品,组成相似物品集合
  5. 对相似物品集合中的物品,利用相似度分值进行排序,生成最终的推荐列表

第5步中,如果一个物品与多个用户行为历史中的正反馈物品相似,那么该物品最终的相似度应该是多个相似度的累加,如下式所示:
R u , p = ∑ h ∈ H ( W p , h ∗ R u , h ) R_{u,p} = \sum_{h \in H} (W_{p,h} * R_{u,h}) Ru,p=hH(Wp,hRu,h)

其中, H H H目标用户的正反馈物品集合 W p , h W_{p,h} Wp,h 是物品 p p p 与物品 h h h 的物品相似度, R u , h R_{u,h} Ru,h 是用户 u u u 对物品 h h h 的已有评分。

在得到物品的相似度之后,接下来就是为用户推荐他可能感兴趣的物品,基于物品的协同过滤算法有两种应用场景:

  • 第一种Top k推荐,常常表现为类似“猜你喜欢”这样的形式。触发方式是当用户访问首页时,汇总和用户已经消费过的物品相似的物品,按照汇总后分数从高到低推出。汇总的公式是这样的:
    R ^ u , i = ∑ j = 1 m s i m ( i , j ) × R u , j ∑ j = 1 m s i m ( i , j ) \hat{R}_{u,i} = \frac{\sum_{j=1}^m sim(i,j) \times R_{u,j}}{\sum_{j=1}^m sim(i,j)} R^u,i=j=1msim(i,j)j=1msim(i,j)×Ru,j

要预测一个用户 u u u 对一个物品 i i i 的评分数,就要遍历用户 u u u 评分过的所有物品。假如一共有 m m m 个物品,用每一个物品和待计算物品 i i i 的相似度乘以用户的评分,加权求和后除以所有这些相似度的总和,就得到了一个加权平均评分,作为用户 u u u 对物品 i i i 的分数预测。

  • 第二种属于相关推荐,也就是本节开篇时提到的场景。当用户访问一个物品的详情页面时,后者完成一个物品消费的结果页面时,可以直接获取这个物品的相似物品推荐,也就是“看了又看”或者“买了又买”。

:之前的UserCF算法有改良版的算法,这里对于ItemCF也有对应改良版的——Slope One算法。

3. 相似度计算方法

在协同过滤算法中,用户相似度的计算是算法中最关键的一步。在图1中,关系矩阵的行向量代表相应用户的用户向量。那么计算用户 i i i 和用户 j j j 的相似度问题,就是计算用户向量 $i4 和用户向量 j j j 之间的相似度问题了。常用的两个向量的相似度计算方法有以下几种:

3.1 余弦相似度

余弦相似度衡量了用户 i i i j j j 向量之间的向量夹角大小。显然,向量夹角越小,证明余弦相似度越大,两个用户越相似。余弦相似度公式:
s i m ( i , j ) = c o s ( i , j ) = i ∗ j ∣ ∣ i ∣ ∣ ∗ ∣ ∣ j ∣ ∣ sim(i,j) = cos(i,j) = \frac{i * j}{||i|| * ||j||} sim(i,j)=cos(i,j)=ijij

∣ ∣ i ∣ ∣ ||i|| i 是对向量 i i i 中每个元素平方求和再开方。

余弦相似度对绝对值大小不敏感,所以在某些情况下是有问题的。例如:用户A对两部电影的评分分别为1分和2分,用户B对两部电影的评分分别为4分和5分,通过计算余弦相似度,两个用户相似度达到0.98,这显然是不合理的。

针对上面说的这个问题,对余弦相似度进行改进,改进后的叫做调整的余弦相似度。调整的方法很简单,就是先计算向量每个维度上的均值,然后每个向量在各个维度上都减去均值后再计算余弦相似度。前面的小例子,如果使用调整后的余弦相似度计算得到的相似度分数为-0.1,即表示两个用户的口味相反。

3.2 皮尔逊相关系数

相比余弦相似度,皮尔逊相关系数通过使用用户平均分对各独立评分进行修正,减小了用户评分偏置影响
s i m ( i , j ) = ∑ p ∈ P ( R i , p − R i ^ ) ( R j , p − R j ^ ) ∑ p ∈ P ( R i , p − R i ^ ) 2 ∑ p ∈ P ( R j , p − R j ^ ) 2 sim(i,j) = \frac{\sum_{p \in P} (R_{i,p} - \hat{R_i}) (R_{j,p} - \hat{R_j})} {\sqrt{\sum_{p \in P} (R_{i,p} - \hat{R_i})^2} \sqrt{\sum_{p \in P} (R_{j,p} - \hat{R_j})^2}} sim(i,j)=pP(Ri,pRi^)2 pP(Rj,pRj^)2 pP(Ri,pRi^)(Rj,pRj^)

其中, R i , p R_{i,p} Ri,p 代表用户 i i i 对物品 p p p 的评分。 R i ^ \hat{R_i} Ri^ 代表用户 i i i 对所有物品的平均评分, P P P 代表所有物品的集合。

3.3 改进的皮尔逊相关系数

思路:通过引入物品平均分的方式,减少物品评分偏置对结果的影响
s i m ( i , j ) = ∑ p ∈ P ( R i , p − R i ^ ) ( R j , p − R j ^ ) ∑ p ∈ P ( R i , p − R p ^ ) 2 ∑ p ∈ P ( R j , p − R p ^ ) 2 sim(i,j) = \frac{\sum_{p \in P} (R_{i,p} - \hat{R_i}) (R_{j,p} - \hat{R_j})} {\sqrt{\sum_{p \in P} (R_{i,p} - \hat{R_p})^2} \sqrt{\sum_{p \in P} (R_{j,p} - \hat{R_p})^2}} sim(i,j)=pP(Ri,pRp^)2 pP(Rj,pRp^)2 pP(Ri,pRi^)(Rj,pRj^)

其中, R p ^ \hat{R_p} Rp^ 代表物品 p p p 的所有评分的平均分。

3.4 欧氏距离

顾名思义,欧氏距离就是一个欧式空间下度量距离的方法。两个点 p p p q q q 在同一欧式空间下之间的距离计算方式为:
E ( p , q ) = ∑ i = 1 n ( p i − q i ) 2 E(p,q) = \sqrt{\sum_{i=1}^n (p_i - q_i)^2} E(p,q)=i=1n(piqi)2

公式中的 n n n 是空间维度,也可以理解为坐标轴的个数, p i p_i pi q i q_i qi 就是每一个坐标上的取值。显示,欧氏距离不适合布尔向量之间使用

欧式距离的值是一个非负数,最大值是正无穷。所以当我们期望的值得范围是[0,1]或者[-1,1]之间的话,我们需要经过二次转换,转换公式为:
1 1 + E ( p , q ) \frac{1}{1 + E(p,q)} 1+E(p,q)1

欧式距离测量的是空间中两个点的绝对差异适用于分析用户能力模型之间的差异,比如消费能力、贡献内容能力等。它的计算结果是一个绝对的客观值,而不是相对值,差异是多大就是多大。

3.5 Jaccard相似度

Jaccard相似度表示两个集合的交集元素个数占并集元素个数的比例。Jaccard相似度非常适用于布尔向量。假设 P P P Q Q Q 是两个集合,两集合元素去重后有 n n n 个,把两个集合表示为布尔向量 p p p q q q,如果第 i i i 个元素出现在集合 P P P 中,那么 p i = 1 p_i=1 pi=1,否则 p i = 0 p_i=0 pi=0。计算两个向量的Jaccard相似度的方式如下:
J ( p , q ) = ∣ P ∩ Q ∣ ∣ P ∪ Q ∣ = ∑ i = 0 n p i q i ∑ i = 0 n p i ∣ q i J(p,q) = \frac{|P \cap Q|} {|P \cup Q|} = \frac{\sum_{i=0}^n p_iq_i}{\sum_{i=0}^n p_i|q_i} J(p,q)=PQPQ=i=0npiqii=0npiqi

上式中分子为两个布尔向量做点积计算,得到的是交集元素的个数
分母为两个布尔向量做或运算,再求元素和,即并集元素个数

余弦相似度适用于评分数据Jaccard相似度适用于隐式反馈数据。例如用户的收藏行为计算用户之间的相似度就适合使用Jaccard相似度。

最后想说的是,在相似用户的计算过程中,理论上,任何合理的”向量相似度定义方式“都可以作为相似用户计算的标准。

另外, 关于协同过滤算法的进化—矩阵分解,可参考推荐系统学习笔记召回策略之基于协同过滤召回最后一小节的介绍。关于协同过滤的更多介绍,强烈推荐阅读刘老师的系列文章协同过滤推荐算法总结

参考文章

介绍下矩阵分解

1. 背景

在矩阵分解出现之前,推荐系统领域主要的应用为协同过滤。当然,当今协同过滤仍然是推荐系统中影响力最大和应用最广泛的模型。但是协同过滤有一个天然的缺陷,就是其对稀疏数据的处理比较弱,头部效应比较明显,泛化能力比较差

简单的来说,以Netflix为例,协同过滤就是尽可能的找到和你相似的用户,将他们喜欢的电影推荐给你。这里面的问题就是,如果一个电影虽然很符合你的兴趣,但是你的朋友却很少有评价或观看过,那么协同过滤就很难将这个电影推荐给你,因为没有评价就不确定这个电影与你看过的电影是否有很近的相似度。那么矩阵分解的出现,很好的解决了协同过滤存在的问题,同时也在近15年无论是工业还是学术上,都占据着举足轻重的地位。

矩阵分解的提出其实是数学上的发展,SVD分解法(奇异值分解)在很久之前就被广泛应用于数学领域,但是真正开始对于推荐系统推荐系统产生影响,源自于2006年Simon Funk的一篇博客,而他的方法也被Netflix Prize的冠军Koren称为Latent Factor Model 隐语义模型(LFM),也有很多人叫它为Funk-SVD。但是其实隐语义模型是个很大的领域,我们这里所讲到矩阵分解也只是隐语义模型比较重要的一部分。这篇文章还是能找到,我将它放在这里。有兴趣的朋友可以仔细的读一遍。Try This at Home

2. 矩阵分解的原理

首先来概括的说下矩阵分解的原理。 上图中每一行 u u u 代表每个用户,每一列 s s s 代表每个物品,矩阵中的数字代表着用户对物品的打分。?代表着用户没有给这个物品打过分。在实际数据中,我们通过数据构建的矩阵如上图一样并不是一个满秩的矩阵。在Netflix真实的数据集里,矩阵的稠密度仅有3%左右。那么就意味着,矩阵中有绝大部分的评分是空白的。如何得到这些空白的评分呢?矩阵分解的就是为了解决这个问题

矩阵分解算法将 m × n m \times n m×n 维的矩阵R分解为 m × k m \times k m×k 的用户矩阵 U U U k × n k \times n k×n 维的物品矩阵 S S S 相乘的形式。其中, m m m 为用户的数量, n n n 为物品的数量, k k k隐向量(Latent Factor)的维度。 k k k 的大小决定了隐向量表达能力的强弱,实际应用中,其取值要经过多次的实验来确定。在得到了 用户矩阵 U U U 和物品矩阵 S S S 后,将两个矩阵相乘,就可以得到一个满秩的矩阵。那么,我们就对未被评价过的物品,有了一个预测评分。接下来,可以将评分进行排序,推荐给用户。这就是矩阵分解对于推荐系统最基本的用途。

用大白话总结一下,矩阵分解的目的就是通过分解之后的两矩阵内积,来填补缺失的数据,用来做预测评分。矩阵分解的核心将矩阵分解为两个低秩的矩阵的乘积,分别以 k k k 维的隐因子向量表示,用户向量和物品向量的内积则是用户对物品的偏好度,即预测评分。值得注意的是k的选取是通过实验和经验而来的,因此矩阵分解的可解释性不强

3. 矩阵分解的求解方法

矩阵分解的求解方法分3种,特征值分解、奇异值分解和梯度下降。这里介绍下梯度下降求解的Funk - SVD算法。

Funk-SVD提出是因为SVD在分解成三个矩阵的时候非常的耗时同时空间复杂度也很高,在面对稀疏数据时,SVD无法进行分解。而Funk-SVD完美的解决了SVD的不足,它仅将原始矩阵 M 分解为两个矩阵 U 和 S分解的目标让分解后的两个矩阵乘积得到的评分矩阵和原始矩阵更拟合,也就是说与原始评分的残差最小,这样才能最大限度的保存共现矩阵 M 的原始信息。
请添加图片描述
细看这个矩阵 M M M,对于每个用户 i i i 和物品 j j j:这里用户用的是 i 而不是 u,物品用的是 j 而不是 i,和通常的表示方式有区别),我们都有一个评分 r i , j r_{i,j} ri,j,就是原始矩阵中有评分的位置。当我们进行分解后,对于每个评分 r r r 我们都可以用分解后的向量 r ^ = q j T p i \hat{r} = q_j^Tp_i r^=qjTpi 来近似。我们的目标就是 r ^ → r \hat{r} \rightarrow r r^r ,也就是让 r − r ^ = r i , j − q j T p i r-\hat{r} = r_{i,j} - q_j^Tp_i rr^=ri,jqjTpi 尽可能的小。在这里我们选择均方差作为损失函数:
请添加图片描述
为了防止过拟合,我们加入正则化项
请添加图片描述
最后可以用梯度下降法来拟合原始矩阵。

至此,这就是Funk-SVD的原理。其解决了SVD在稀疏数据下不能工作的缺点。同时有很高的精度,也可以离线进行计算,并且具有很好的扩展性,在其方法上衍生出了很多优秀的算法例如SVD++等等。那么Funk-SVD就没有劣势么?答案显然不是。Funk-SVD由于需要迭代优化损失函数,因此其训练过程比较耗时,同时推荐结果不具有很好的可解释性

小结:

FunkSVD(梯度下降求解) 和 PureSVD(奇异值求解)的不同之处在于,FunkSVD不在将矩阵分解为3个矩阵,而是分解为2个低秩的用户项目矩阵,同时降低了计算复杂度。

更多矩阵分解方法的求解可参考 推荐系统中的矩阵分解推荐系统之矩阵分解家族 这两篇文章。

参考文章

介绍下双塔模型

1. 双塔模型有着广泛的应用场景

双塔结构在推荐领域里已经是个常规方法了,在召回和粗排环节的模型选型中,被广泛采用。其实,不仅仅是在推荐领域,在其它领域,双塔结构也已经被越来越多得用起来了。比如,在当代搜索引擎的召回环节,除了常见的经典倒排索引来对Query和Document进行文本字面匹配外,经常也会增加一路基于Bert模型的双塔结构,将用户查询Query和搜索文档,各自通过一个塔形结构来打Embedding,以此增加Query和Document的深层语义匹配能力;再比如,在自然语言处理的QA领域,一般也会在第一步召回环节,上一个基于Bert模型的双塔结构,分别将问题Question和可能包含正确答案的Passage,通过双塔结构映射到同一个语义空间,并分别把Question和Passage打出各自的Embedding。

2. 双塔模型结构和离线训练过程

双塔模型结构非常简单,可对海量候选item进行召回:

1)user和item特征分别单独输入DNN,得到user embedding与item embedding;
2)将最后一层embedding计算cosine得到logit,其中logit代表user&item之间的匹配程度

上图中,左侧是用户塔,右侧是Item塔,可将特征拆分为两大类:用户相关特征(用户基本信息、群体统计属性以及行为过的Item序列等)与Item相关特征(Item基本信息、属性信息等),原则上,Context上下文特征可以放入用户侧塔。对于这两个塔本身,则是经典的DNN模型,从特征OneHot到特征Embedding,再经过几层MLP隐层,两个塔分别输出用户Embedding和Item Embedding编码。在训练过程中,User Embedding和Item Embedding做内积或者Cosine相似度计算(注:Cosine相当于对User Embedding和Item Embedding内积基础上,进行了两个向量模长归一化,只保留方向一致性不考虑长度),使得用户和正例Item在Embedding空间更接近,和负例Item在Embedding空间距离拉远。损失函数则可用标准交叉熵损失,将问题当作一个分类问题,或者类似DSSM采取BPR或者Hinge Loss,将问题当作一个表示学习问题。

虽说上图两个塔的DNN模块介绍说的是MLP结构,但是理论上这里可以替换成任意你想用的模型结构,比如Transformer或者其它模型,最简单的应该是FM模型,如果这里用FM模型做召回或者粗排,等于把上图的DNN模块替换成了对特征Embedding进行“Sum”求和操作,貌似应该是极简的双塔模型了。所以说,双塔结构不是一种具体的模型结构,而是一种抽象的模型框架

3. 双塔模型在线应用

一般在推荐的模型召回环节应用双塔结构的时候,分为离线训练和在线应用两个环节。上面基本已描述了离线训练过程,至于在线应用,一般是这么用的:

  • 首先,通过训练数据,训练好User侧和Item侧两个塔模型,我们要的是训练好后的这两个塔模型,让它们各自接受用户或者Item的特征输入,能够独立打出准确的User Embedding或者Item Embedding。

  • 之后,对于海量的候选Item集合,可以通过Item侧塔,离线将所有Item转化成Embedding,并存储进ANN检索系统,比如FAISS,以供查询。为什么双塔结构用起来速度快?主要是类似FAISS这种ANN检索系统对海量数据的查询效率高。

  • 再往后,某个用户的User Embedding,一般要求实时更新,以体现用户最新的兴趣。为了达成实时更新的目的,你有几种难度不同的做法,比如你可以通过在线模型来实时更新双塔的参数来达成这一点,这是在线模型的路子;但是很多情况下,并非一定要采取在线模型,毕竟实施成本高,而可以固定用户侧的塔模型参数,采用在输入端,将用户最新行为过的Item做为用户侧塔的输入,然后通过User侧塔打出User Embedding,这种模式。这样也可以实时地体现用户即时兴趣的变化,这是特征实时的角度,做起来相对简单。

  • 最后,有了最新的User Embedding,就可以从FAISS库里拉取相似性得分Top K的Item,做为个性化召回结果

以上回答来自知乎。关于双塔模型的更多思考,可参考SENet双塔模型:在推荐领域召回粗排的应用及其它这篇文章。

4. 双塔模型的优势

双塔模型的优势,总结如下:

  • 可以离线计算item的embedding
  • 线上计算user(&context)的embedding
  • 线上计算相似度
  • 实时性好

说来说去,主要就是实时性好,cos的表达是有限的,很难提取交叉特征,所以双塔还是比较适用于召回场景。

参考文章

双塔输出用内积还是余弦相似度

1. 内积和余弦相似度的区别

余弦相似度计算公式:
请添加图片描述
余弦值越接近1,就表明夹角越接近0度,也就是两个向量越相似,这就叫"余弦相似性"。

可以看出,余弦相似度实际上就是归一化的内积。那么,归一化的意思在哪里?如果不归一化的话,这个内积的意义又是什么呢?

其实,两者表达的意思不一样,不能一概而论。余弦举例只考虑了角度差(衡量两个向量在方向上的相似性,对绝对的数值不敏感),而内积综合考虑了角度差和长度差。比如,有两个向量 A(1,1,0) 和 B(0,1,1),他们的余弦相似度是 1 2 2 = 1 2 \frac{1}{\sqrt{2}\sqrt{2}} = \frac{1}{2} 2 2 1=21。余弦相似度不考虑向量的长度,所以 A(1,1,0) 和 C(0,3,3) 的相似程度与A和B的相同。

但是,如果向量的长度本身对相似有真实的影响时,推荐使用内积。比如,对商品的几个属性打分,1表示不确定,依次到,5表示很确定,那么 A(1,1,1)、B(4,4,4)、C(5,5,5) 三个商品,根据内积,B 与 C 更相似。但是,余弦相似度在这里就无法区分 A、B、C的相似性。

2. 用内积还是余弦相似度

在得到query和item各自的embedding之后,到底是采用内积,还是采用余弦相似度?实验表明,采用余弦相似度效果更好且易于训练。还加了温度参数,如下所示。加上温度参数可以锐化结果。文中实验 τ \tau τ 的范围在[0.05,0.1],那么 1 τ \frac{1}{\tau} τ1 的范围在[10,20]。
请添加图片描述
参考文章

双塔模型一般怎么做特征

用户塔输入包括user相关特征(用户id、用户基本信息、群体统计属性以及行为过的Item序列等)和Context上下文(如地理位置)特征。物品塔输入为Item相关特征(物品id、Item基本信息、属性信息等)。对id类特征要生成Embedding。

参考文章

双塔模型为什么不直接把两个塔合起来输入一个DNN

1)首先,采用双塔可以减少计算量

对 Item 和 User 两个tower直接计算内积即可拿到最终的目标。Item和User各自的embedding可以通过多层NN得到,这部分可以离线计算好,线上只需要计算最终一次向量内积,计算量就很低,在召回阶段还能使用hnsw、ivf-pq等ANN算法。比如,如果离线把user和item的向量提前计算好放在内存中(占用 O ( 2 n ) O(2n) O(2n) 的空间,实际上一般只存储item的向量,user的向量会实时进行计算),线上直接把对应的向量拿出来进行内积操作即可,极大地减少了计算量。

为什么不采用单塔呢?如果是一个单塔的网络,在训练时,原始的item和user的特征在网络中必然要进行交叉,最后得到输出,从而导致网络的中间层表示的是user和item交叉过后的向量,如果要存储这个向量,空间就变成了 O ( n 2 ) O(n^2) O(n2) ,或者说就只能线上再进行实时计算了。

2)双塔是指对bias信息用单独的tower建模,好处是更灵活更好的对bias建模

以上解答参考知乎~

参考文章

排序

介绍下Wide&Deep

1. W&D概述

一句话概括W&D:由浅层(或单层)的Wide部分神经网络和深层的Deep部分多层神经网络组成,输出层采用softmax或logistics regression综合Wide和Deep部分的输出

Wide&Deep模型有两个重要的概念就是Memorization(记忆能力)和Generalization(泛化能力)。Wide部分有利于增强模型的“记忆能力”,Deep部分有利于增强模型的“泛化能力”。

  • Wide层采用LR模型加上大量原始特征和叉乘特征作为输入,‘记忆’历史数据中曾共同出现过的特征对;
  • Deep层则主要为sparse特征学习低维的dense embeddings来捕获特征相关性,学习到的embedding本身会带一定的语义特征。

加入wide层学习浅层特征的动机:
1)因子分解机或者深度神经网络在低维稠密向量下学习,但是无法get到稀疏高维的情况,会对小众查询给出非零的预测,也就是过拟合;
2)线性模型用外积特征变换可以依赖少量的参数记住特征对

1.1 Wide层

wide部分是一个广义的线性模型,输入的特征主要有两部分组成,一部分是原始的部分特征,另一部分是原始特征的交叉特征即cross product外积运算,当两个特征同时交叉出现时为1,任意一个特征不出现表示为0。

为什么Wide部分要用L1 FTRL训练?

对于wide部分训练时候使用的优化器是带L1正则的FTRL算法(Follow-the-regularized-leader),FTRL可以理解为稀疏性很好,精度又不错的随机梯度下降方法。W&D模型采用L1-FTRL是想让Wide部分变得更加的稀疏,即Wide部分的大部分参数都为0,这就大大压缩了模型权重及特征向量的维度。通过这样Wide部分模型训练完之后留下来的特征都是非常重要的,那么模型的“记忆能力”就可以理解为发现"直接的",“暴力的”,“显然的”关联规则的能力。

1.2 Deep层

Deep部分是一个DNN模型,输入的特征主要分为两大类,一类是数值特征(可直接输入DNN),一类是类别特征(需要经过Embedding之后才能输入到DNN中)。Deep部分可以减少人工的特征参与,对历史上没出现过的情况有更好的泛化能力。对于Deep部分的DNN模型作者使用了深度学习常用的优化器AdaGrad,这也是为了使得模型可以得到更精确的解。

1.3 联合训练

联合训练的公示如下,wide_n_deep模型的组合依赖于其输出的对数几率的加权作为预测。随后这一值被输入到一个一般的逻辑损失函数中联合训练。联合训练和拼装不同,其是在训练过程中同时优化wide和deep模型及总和的权重,而拼装是将模型分别训练,结果是在最后进行组合。

2 总结

Wide部分输入的是两个id类特征的乘积,id特征为User Installed App 和 Impression App,不难猜测Google的工程师使用这个组合特征的意图,是想发现当前曝光app和用户安装app的关联关系,以此来直接影响最终的得分。两个id类特征向量进行组合,在维度爆炸的同时,会让原本已经非常稀疏的multihot特征向量,变得更加稀疏。正因如此,wide部分的权重数量其实是海量的。为了不把数量如此之巨的权重都搬到线上进行model serving,采用FTRL过滤掉那些稀疏特征无疑是非常好的工程经验。

而Deep部分的输入,要么是Age,订单次数,评分这些数值类特征,要么是已经降维并稠密化的Embedding向量。所以Deep部分不存在严重的特征稀疏问题。因此wide部分记住的是历史数据中那些常见、高频的模式,是推荐系统中的“红海”。

实际上,Wide侧没有发现新的模式,只是学习到这些模式之间的权重,做一些模式的筛选正因为Wide侧不能发现新模式,因此我们需要根据人工经验、业务背景,将我们认为有价值的、显而易见的特征及特征组合,喂入Wide侧。而deep侧通过embedding的方式将categorical/id特征映射成稠密向量,让DNN学习到这些特征之间的深层交叉,以增强扩展能力。

参考文章

介绍下DeepFM

1 模型演进历史

DeepFM借鉴了Google的wide & deep的做法,其本质是

  • 将Wide & Deep 部分的wide部分由 人工特征工程+LR 转换为FM模型,避开了人工特征工程
  • FM模型与deep part共享feature embedding

1.1 线性模型

最开始CTR或者是推荐系统领域,一些线性模型取得了不错的效果。比如:LR,FTRL。线性模型有个致命的缺点:无法提取高阶的组合特征。所以常用的做法是人为的加入pairwise feature interactions。即使是这样:对于那些出现很少或者没有出现的组合特征以及高阶组合特征依旧无法提取。

LR最大的缺点就是无法组合特征,依赖于人工的特征组合,这也直接使得它表达能力受限,基本上只能处理线性可分或近似线性可分的问题。

1.2 FM模型

线性模型差强人意,直接导致了FM模型应运而生(在Kaggle上打比赛提出来的,取得了第一名的成绩)。FM通过隐向量latent vector做内积来表示组合特征,从理论上解决了低阶和高阶组合特征提取的问题。但是实际应用中受限于计算复杂度,一般也就只考虑到2阶交叉特征。

后面又进行了改进,提出了FFM,增加了Field的概念。关于FM和FFM模型的原理剖析可参考FM、FFM、DeepFM学习笔记这篇文章。

1.3 遇上DL

随着DNN在图像、语音、NLP等领域取得突破,人们见见意识到DNN在特征表示上的天然优势。相继提出了使用CNN或RNN来做CTR预估的模型。但是,CNN模型的缺点是:偏向于学习相邻特征的组合特征。RNN模型的缺点是:比较适用于有序列(时序)关系的数据

FNN (Factorization-machine supported Neural Network) 的提出,应该算是一次非常不错的尝试:先使用预先训练好的FM,得到隐向量,然后作为DNN的输入来训练模型。缺点在于:受限于FM预训练的效果。 随后提出了PNN (Product-based Neural Network),PNN为了捕获高阶组合特征,在embedding layer和first hidden layer之间增加了一个product layer。根据product layer使用内积、外积、混合分别衍生出IPNN, OPNN, PNN三种类型。

无论是FNN还是PNN,他们都有一个绕不过去的缺点:对于低阶的组合特征,学习到的比较少。而前面我们说过,低阶特征对于CTR也是非常重要的。

Google意识到了这个问题,为了同时学习低阶和高阶组合特征,提出了Wide&Deep模型。它混合了一个线性模型(Wide part)和Deep模型(Deep part)。这两部分模型需要不同的输入,而Wide part部分的输入,依旧依赖人工特征工程

但是,这些模型普遍都存在两个问题:
1)偏向于提取低阶或者高阶的组合特征。不能同时提取这两种类型的特征
2)需要专业的领域知识来做特征工程。

DeepFM在Wide&Deep的基础上进行改进,成功解决了这两个问题,并做了一些改进,其优势/优点如下:
1)不需要预训练FM得到隐向量
2)不需要人工特征工程
3)能同时学习低阶和高阶的组合特征
4)FM模块和Deep模块共享Feature Embedding部分,可以更快的训练,以及更精确的训练学习

2 DeepFM

DeepFM架构图:

主要做法如下:
1)FM Component + Deep Component。FM提取低阶组合特征,Deep提取高阶组合特征。但是和Wide&Deep不同的是,DeepFM是端到端的训练,不需要人工特征工程
2)共享feature embedding。FM和Deep共享输入和feature embedding不但使得训练更快,而且使得训练更加准确。相比之下,Wide&Deep中,input vector非常大,里面包含了大量的人工设计的pairwise组合特征,增加了他的计算复杂度。

2.1 FM Component

FM部分的输出由两部分组成:一个 Addition Unit,多个 内积单元
请添加图片描述
这里的d是输入one-hot之后的维度,我们一般称之为 feature_size。对应的是one-hot之前的特征维度,我们称之为 field_size。这部分具体解析见csdn

FM架构图:

Addition Unit 反映的是1阶的特征。内积单元反映的是2阶的组合特征对于预测结果的影响。

FM Component总结:

  1. FM模块实现了对于1阶和2阶组合特征的建模。
  2. 没有使用预训练
  3. 没有人工特征工程
  4. embedding矩阵的大小是:特征数量 * 嵌入维度。 然后用一个index表示选择了哪个特征。

需要训练的有两部分:

  1. input_vector和Addition Unit相连的全连接层,也就是1阶的Embedding矩阵
  2. Sparse Feature到Dense Embedding的Embedding矩阵,中间也是全连接的,要训练的是中间的权重矩阵,这个权重矩阵也就是隐向量V

2.2 Deep Component

Deep Component架构图:

Deep Component是用来学习高阶组合特征的。网络里面黑色的线是全连接层,参数需要神经网络去学习。

由于CTR或推荐系统的数据one-hot之后特别稀疏,如果直接放入到DNN中,参数非常多,我们没有这么多的数据去训练这样一个网络。所以增加了一个Embedding层,用于降低纬度

这里继续补充下Embedding层,两个特点:

  1. 尽管输入的长度不同,但是映射后长度都是相同的.embedding_size(k)
  2. embedding层的参数其实是全连接的Weights,是通过神经网络自己学习到的。

Embedding层的架构图:

embedding layer表示为:
a ( 0 ) = [ e 1 , e 2 , . . . , e m ] a^{(0)}=[e_1,e_2,...,e_m] a(0)=[e1,e2,...,em]

其中 e i e_i ei 是第 i i i 个 filed 的 embedding,m 是 filed 数量; 然后 a ( 0 ) a^{(0)} a(0) 传递给deep part,前馈过程如下:
a ( l + 1 ) = σ ( W ( l ) a ( l ) + b ( l ) ) a^{(l+1)}=\sigma(W^{(l)}a^{(l)} + b^{(l)}) a(l+1)=σ(W(l)a(l)+b(l))

其中 l l l 是层深度, σ \sigma σ 是激活函数, a ( l ) a^{(l)} a(l), W ( l ) W^{(l)} W(l) , b ( l ) b^{(l)} b(l) 分别是第 l l l 层的输出,权重和偏置。

然后得到dense real-value 特征矢量,最后被送到sigmoid函数做CTR预测:
请添加图片描述
其中 ∣ H ∣ |H| H 是隐藏层层数,值得注意的是:FM模块和Deep模块是共享feature embedding的(也就是V)

好处:

  1. 模型可以从最原始的特征中,同时学习低阶和高阶组合特征
  2. 不再需要人工特征工程。Wide&Deep中低阶组合特征就是同过特征工程得到的。

3. 对比其他模型

模型图:

3.1 FNN Model

FNN使用预训练的FM来初始化DNN,然后只有Deep部分,不能学习低阶组合特征。

FNN缺点:

  1. Embedding的参数受FM的影响,不一定准确;
  2. 预训练阶段增加了计算复杂度,训练效率低 ;
  3. FNN只能学习到高阶的组合特征。模型中没有对低阶特征建模。

3.2 PNN Model

PNN:为了捕获高阶特征。PNN在第一个隐藏层和embedding层之间,增加了一个product layer。

根据product的不同,衍生出三种PNN:IPNN,OPNN,PNN 分别对应内积、外积、两者混合。

作者为了加快计算,采用近似计算的方法来计算内积和外积。内积:忽略一些神经元。外积:把m*k维的vector转换成k维度的vector。由于外积丢失了较多信息,所以一般没有内积稳定。 但是内积的计算复杂度依旧非常高,原因是:product layer的输出是要和第一个隐藏层进行全连接的。

PNN缺点:

  1. 内积外积计算复杂度高。采用近似计算的方法外积没有内积稳定;
  2. product layer的输出需要与第一个隐藏层全连接,导致计算复杂度居高不下 ;
  3. 和FNN一样,只能学习到高阶的特征组合。没有对于1阶和2阶特征进行建模。

3.3 Wide&Deep

Wide & Deep设计的初衷是想同时学习低阶和高阶组合特征,但是wide部分需要领域知识进行特征工程。

Wide部分可以用LR来替换,这样的话就和DeepFM差不多了。

但是DeepFM共享feature embedding 这个特性使得在反向传播的时候,模型学习feature embedding,而后又会在前向传播的时候影响低阶和高阶特征的学习,这使得学习更加的准确。

Wide&Deep缺点:

  1. 需要特征工程提取低阶组合特征

事实上,论文已经明确指出了DeepFM相对于 Wide & Deep 的创新点:
2. 将Wide & Deep 部分的wide部分由 人工特征工程+LR 转换为FM模型,避开了人工特征工程;
3. FM模型与deep part共享feature embedding,使得embedding特征得到了很好的表征,建模能力更精细。

3.4 DeepFM

优点:

  1. 没有用FM去预训练隐向量V,并用V去初始化神经网络。(相比之下FNN就需要预训练FM来初始化DNN);
  2. FM模块不是独立的,是跟整个模型一起训练学习得到的。(相比之下Wide&Deep中的Wide和Deep部分是没有共享的);
  3. 不需要特征工程。(相比之下Wide&Deep中的Wide部分需要特征工程);
  4. 训练效率高。(相比PNN没有那么多参数)。

总结就是:

  1. 没有预训练(no pre-training);
  2. 共享Feature Embedding,没有特征工程(no feature engineering);
  3. 同时学习低阶和高阶组合特征(capture both low-high-order interaction features)。

以上模型对比图如下:

参考文章

介绍下DIN

1. 背景介绍

深度兴趣网络(Deep Interest Network)的应用场景是阿里巴巴的电商广告推荐。用户场景很简单,就是在一个电商网站或APP中给用户推荐广告,当然对于阿里妈妈来说,广告也是商品,所以这篇文章的广告场景其实也是一个经典的推荐场景。

既然要推荐,我们当然需要利用用户的历史数据了,对于一个电商来说,历史数据当然就是点击,添加购物车,下单这些行为了。论文中给了一位用户的行为序列。

显然是一个女生的行为历史啦,从最左边的手套,鞋子到右边的杯子,睡衣。要被推荐的候选商品是一件女式大衣。我们应该如何计算这件大衣的CTR呢?

如果按照之前的做法,我们会一碗水端平的考虑所有行为记录的影响,对应到模型中就是我们会用一个average pooling层把用户交互过的所有商品的embedding vector平均一下形成这个用户的user vector,机灵一点的工程师最多加一个time decay,让最近的行为产生的影响大一些,那就是在做average pooling的时候按时间调整一下权重。

但是我们仔细想一想我们自己的购买过程,其实每个用户的兴趣都是多样的,女生喜欢买衣服包包,也喜欢化妆品,甚至还为自己男朋友挑选过球衣球鞋,那么你在买大衣的时候,真的要把给男朋友买球鞋的偏好考虑进来么?具体到本文的例子中,在预测大衣的CTR这件事情上,用户浏览过杯子,跟用户浏览过另一件大衣这两个行为的重要程度是一样的吗?显然,肯定是浏览过另一件大衣这件事的参考价值高啊。

2.1 Base Model

介绍 DIN 之前,先了解一下 Base Model,模型结构如下:

阿里的推荐系统主要用到四组特征:用户画像特征、用户行为特征、候选商品、上下文特征。本文只需关注用户行为特征如何处理即可。

Base 模型的做法是将用户点击的商品序列,简单的进行 SUM Pooling,然后将聚合得到的 embedding 向量,作为用户的兴趣表示

这种做法的缺陷也很明显,简单的累加无法突出某些商品的重要性。对于与候选商品具有强关联性的 item,应该给予更大的权重,让其在提取用户兴趣时发挥更大的作用。

2. DIN Model

2.1 DIN注意力机制体现在哪里

注意力机制顾名思义,就是模型在预测的时候,对用户不同行为的注意力是不一样的,“相关”的行为历史看重一些,“不相关”的历史甚至可以忽略。那么这样的思想反应到模型中也是直观的。

上式中, V u V_u Vu 是用户的embedding向量, V a V_a Va 是候选广告商品的embedding向量, V i V_i Vi 是用户u的第i次行为的embedding向量,因为这里用户的行为就是浏览商品或店铺,所以行为的embedding的向量就是那次浏览的商品或店铺的embedding向量。

因为加入了注意力机制, V u V_u Vu 从过去 V i V_i Vi 的加和变成了 V i V_i Vi加权和 V i V_i Vi 的权重 w i w_i wi 就由 V i V_i Vi V a V_a Va 的关系决定,也就是上式中的 g ( V i , V a ) g(V_i,V_a) g(Vi,Va) ,不负责任的说,这个 g ( V i , V a ) g(V_i,V_a) g(Vi,Va) 的加入就是本文70%的价值所在。

那么 g ( V i , V a ) g(V_i,V_a) g(Vi,Va) 这个函数到底采用什么比较好呢?看完下面的架构图自然就清楚了。

相比原来这个标准的深度推荐网络(Base model),DIN在生成用户embedding vector的时候加入了一个activation unit层,这一层产生了每个用户行为 V i V_i Vi 的权重。简单来说就是,DIN 引入了 Activation Unit 为每个商品计算一个重要性权重,再 Pooling 得到兴趣表示。下面我们仔细看一下这个权重是怎么生成的,也就是 g ( V i , V a ) g(V_i,V_a) g(Vi,Va) 是如何定义的。

传统的Attention机制中,给定两个item embedding,比如u和v,通常是直接做点积uv或者uWv,其中W是一个|u|x|v|的权重矩阵,但这篇paper中阿里显然做了更进一步的改进,着重看上图右上角的activation unit,首先是把u和v以及u v的element wise差值向量合并起来作为输入,然后喂给全连接层,最后得出权重,这样的方法显然损失的信息更少。但如果你自己想方便的引入attention机制的话,不妨先从点积的方法做起尝试一下,因为这样连训练都不用训练。

再稍微留意一下这个架构图中的红线,你会发现每个ad会有 good_id, shop_id 两层属性,shop_id只跟用户历史中的shop_id序列发生作用,good_id只跟用户的good_id序列发生作用,这样做的原因也是显而易见的。

DIN注意力机制小结

DIN详细的模型结构如下:

主要关注下 Activation Unit 内的权重计算方式,该单元的输入为:用户点击的商品(Inputs from User)、候选商品(Inputs from Ad)。

计算方式小结:

  • 计算点击的商品与候选商品的外积,得到一维embedding;
  • 将外积结果与原始输入 Concat 在一起;
  • 后面结两层全连接,隐层激活函数使用 PRelu或Dice,输出映射到一维,表示权重分数。

用户点击的多个商品,分别按照以上方式与候选商品计算权重,然后加权再取 SUM Pooling 即可。这样就突出了重要商品发挥的作用,可提取到更精确的用户兴趣表示。

DIN 最大的创新点就是引入了 Activation Unit,这也是与 Base Model 唯一不同的地方。

好了,到这里为止我们基本讲完了这篇文章的重点部分,如果说上面的部分是文70%的价值所在,那么余下30%应该还有这么几点:

  • 用GAUC这个离线metric替代AUC
  • 用Dice方法替代经典的PReLU激活函数
  • 介绍一种Adaptive的正则化方法
  • 介绍阿里的X-Deep Learning深度学习平台

2.2 Data Adaptive Activation Function

上图为激活函数的梯度变化曲线,Dice 激活函数是对 PRelu 的改进。因为 Relu、PRelu 的梯度发生变化的点都固定在 x=0 处,神经网络每层的输出往往具有不同分布,所以固定在一处无法适应多样的分布,所以变化点应随着数据的分布自适应调整。


Dice 的计算方式如上,s表示当前 batch 的数据,p(s) 的计算可以看做是先对 s 进行标准化,即减去均值、除以方差,得到 e 的指数部分,然后进行 sigmoid 变换得到概率值 p(s)。

f(s) 的计算是利用 p(s) 的值对 s 进行平滑,第二部分需要乘上一个权重 a,该权重随模型学习得到。

2.3 mini-batch aware regularization


对 L2 正则化的改进,在进行 SGD 优化的时候,每个 mini-batch 都只会输入部分训练数据,反向传播只针对部分非零特征参数进行训练,添加上 L2 之后,需要对整个网络的所有参数进行训练,计算量非常大。

所以引入该方法,只对每一个 mini-batch 中不为 0 的参数进行梯度更新,以此降低训练开销。

2.4 GAUC


3. 总结

优点:

  • 引入 Attention 机制,更精准的提取用户兴趣;
  • 引入 Dice 激活函数与,并优化了稀疏场景中的 L2 正则方式。

缺点:

  • 没有考虑用户点击商品的相对位置信息,后续的 DIEN 也是针对这点进行了改进。

参考文章

介绍下DIEN

1. DIEN提出的动机

DIN重点是针对某个候选广告,用attention对用户行为序列进行权重计算,得到用户针对这个候选广告的兴趣向量,然后去做点击率预估。

DIN能够捕捉到用户多样的兴趣,但是缺点就是用户行为序列中的条目是被等价对待的,并没有考虑到用户兴趣的漂移。

比如,随着风潮的变化,用户喜欢的衣服风格可能发生变化;类似的,用户在某个时间段会关注一类书籍,但是过了这个时间段,可能会关注其他类型的书籍,或者其他商品比如衣服。

综上,用户的兴趣有如下特点:

  • 多样性,用户感兴趣的商品会有很多种类。
  • 进化性,用户的兴趣会随着时间发生变化,包括在某种商品内的细粒度变化,或者不同种商品间的变化等。

所以,针对上述问题,DIEN对用户的行为序列进行了建模,从而能捕捉到用户兴趣的漂移

2.1 BaseModel

在介绍模型的改进之前,再来回顾一下基础模型。经典的CTR预估模型是Embedding + MLP。

对于阿里的广告点击率预估问题来说,有四大类特征:

  • 用户信息: 例如性别,年龄等。
  • 用户行为序列: 用户看过的商品序列。
  • 广告: ad_id, shop_id等等
  • 上下文: 时间,地点等。

大部分是离散特征,可以用one-hot进行编码表达。而对于商品来说,因为商品数目太多,使用one-hot不现实,所以使用密集编码(即稠密向量),即给每个商品一个向量编码,然后对于用户行为序列中的每一个商品,取得对应的编码,将所有的商品向量编码拼接起来,得到行为序列的编码。

得到的Embedding之后,就可以将数据输入给MLP多层神经网络进行处理了。使用的损失函数为:

2.2 DIEN

DIEN,全称是Deep Interest Evolution Network,即用户兴趣进化网络。这个算法中用两层架构来抽取和使用用户兴趣特征:

  • Interest Extractor Layer: 从用户行为序列中提取信息
  • Interest Evolving Layer: 从用户行为序列中找到目标相关的兴趣,对其进行建模

2.2.1 兴趣抽取层

使用LSTM的变种GRU对用户行为序列进行建模。GRU可以达到和LSTM类似的结果但速度更快。

其中, σ \sigma σ 是sigmoid操作,而 ⊙ \odot 是内积操作。

但是如果只用上面BaseModel的损失函数的话,是无法将GRU训练好的。因为最后的target只是针对一种兴趣的,所以GRU建模的序列上得不到足够的监督信息。为了解决这个问题,提出了一种辅助损失函数用来帮助训练GRU。

方法就是使用行为序列中的下一个行为来作为当前步隐含状态的监督信息,这是正例;另外还采样了一个其他的行为来作为负例。而行为都是embedding好的,所以和普通的GRU训练不同,在这里我们将行为embedding和隐含状态做内积然后再计算损失函数,计算公式如下:

其中, e b i \pmb{e}_b^i eeebi 是正例,带帽的 e ^ b i \pmb{\hat{e}}_b^i e^e^e^bi 则是负例。

有了这个辅助损失后,就可以较好的用GRU建模行为序列。

最后的损失函数则是 L = L t a r g e t + α ∗ L a u x L = L_{target} + \alpha * L_{aux} L=Ltarget+αLaux

2.2.2 兴趣进化层

上面使用的GRU的隐含信息可以组成一个兴趣序列,而根据预测目标的不同,我们需要从兴趣序列中拿到不同的信息,这时候,attention机制就粉墨登场了。

Attention是在目标和GRU的每一个隐含状态间进行计算。计算公式如下,即在目标和隐含状态间用矩阵去做乘法,然后再做归一化。

基于上面的attention计算公式,我们再构建一个GRU来处理兴趣进化,提出了三种方法来构建这个GRU。

  1. AIGRU: GRU + Attention Input
    将抽取层的GRU的隐含状态乘以attention权重作为下一个GRU的输入。这种方法表现不是特别好,因为即使权重为0,输入给GRU后依然会改变GRU的隐含状态,影响兴趣进化的学习。

  2. AGRU: Attention based GRU
    用attention得到的权重来改变GRU中隐含状态的更新方式。

  3. AUGRU: GRU with attention update gate
    AGRU的一个变种,上面的AGRU用一个scalar替代了GRU的参数向量来做加权,使得GRU的能力变弱,这里做了改进,用权重来更新GRU的参数向量,然后用更新过的向量去更新GRU隐含状态。

    显然,从描述中看,最后一种更全面,效果会更好。

3 算法架构

有了上面的两层,就得到了整个架构:

小结:

DIEN对用户行为序列进行建模,捕捉了用户兴趣进化信息,从而能提高CTR。技术上,使用GRU对序列建模,使用辅助损失来对GRU更好的训练,类似DIN,使用attention来对序列进行筛选,只对目标相关的兴趣进行序列建模,总体上,提升CTR达到20.7%,相当大的impact了。

参考文章

  • 4
    点赞
  • 22
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值