一、背景
在天猫的个性化推荐场景中,无论是召回还是排序阶段,最重要的都是为用户兴趣建模。然而建模用户兴趣存在问题:一个用户可能对多种物品感兴趣。
现有的推荐算法采取过多种方法来对用户兴趣建模。基于协同过滤的方法用用户历史行为或隐性因子来表示用户兴趣,这种方法的局限性在于稀疏性和计算困难。深度学习方法通常将用户兴趣表示为一个低维度的embedding,然而这种方法中,embedding的维度可能会成为表达用户各种兴趣的瓶颈。DIN在表示用户兴趣时引入了attention,然而由于计算复杂性,这种方法只能用在排序阶段。
本文提出的MIND模型关注点在于在召回阶段为用户的兴趣多样性建模。我们设计了一个多兴趣抽取层,利用动态路由来将用户的历史聚合为用户的embedding表达。这一动态路由可以看做是一种soft clustering,将用户历史聚合成一些簇。这样对于一个用户,MIND就可以输出多个向量来表达用户的多种兴趣。
二、亮点
- 用多个向量来表示一个用户,这些向量编码用户兴趣的不同方面。
- 设计了基于胶囊网络动态路由的多兴趣抽取层,来聚类历史行为和提取不同的兴趣。
- 设计了label-aware attention机制,从而学习具有多个向量的用户表示。
三、模型具体结构
1. 问题形式化
推荐系统召回阶段的目标就是从一个巨大的物品池 I 中为每个用户 u ∈ U 召回一千级别的物品,并且每个物品都与用户兴趣相关。为达成这一目标,推荐系统生成的历史数据被收集下来来构建召回模型。其中的每个样本可以表示为一个三元组
(
I
u
,
P
u
,
F
i
)
(I_u, P_u, F_i)
(Iu,Pu,Fi),其中
I
u
I_u
Iu表示用户 u 交互过的物品,
P
u
P_u
Pu表示用户的基础画像(包括性别、年龄等)。
F
i
F_i
Fi表示目标物品的特征。
MIND的核心任务就是学习一个映射关系,将原始特征与用户表示映射起来:
其中
V
u
=
(
v
u
1
,
.
.
.
,
v
u
K
)
∈
R
d
∗
K
V_u = (v_u^1, ..., v_u^K) \in R^{d *K}
Vu=(vu1,...,vuK)∈Rd∗K表示用户向量。 K为向量个数。若 K = 1 ,那么就像youtube DNN一样只用一个向量表示用户。目标物品 i 则用以下embedding表示:
在得到用户和物品的embedding后,topN的物品根据以下分数进行召回:
2. embedding&pooling层
如上图所示:MIND的输入由三部分组成:用户属性,用户行为和目标物品。每个部分都有一些类别id特征,对于这些特征我们进行embedding。对于用户属性embedding,我们直接将其拼接起来;对于物品的id和商标id等,我们对它们进行平均池化。
3. 多兴趣抽取层
我们认为将用户兴趣表示为一个embedding可能是限制用户兴趣多样性的一个瓶颈,因为我们必须将用户的所有兴趣压缩进一个embedding,于是就会导致召回阶段不能够精确地召回物品。因此我们用多个向量分别来表示用户的兴趣。为学习这一表示,我们利用聚类方法来将用户的历史行为聚成多个簇。这一设计是受到了近期提出的动态路由的启发。
3.1 动态路由
假设我们有两层胶囊网络,分别为低级胶囊和高级胶囊。动态路由的目标就是通过低级胶囊的值来迭代地计算高级胶囊的值。在每次迭代中,给出低级胶囊和对应的向量
c
i
l
∈
R
N
l
∗
1
,
i
∈
{
1
,
.
.
.
,
m
}
c_i^l\in R^{N_l * 1 }, i \in \{1, ..., m\}
cil∈RNl∗1,i∈{1,...,m},以及高级胶囊和对应的向量
c
j
h
∈
R
N
h
∗
1
,
j
∈
{
1
,
.
.
.
,
n
}
c_j^h\in R^{N_h * 1 }, j \in \{1, ..., n\}
cjh∈RNh∗1,j∈{1,...,n},路由的logit用下面方法计算:
其中
S
i
j
∈
R
N
h
∗
N
l
S_{ij} \in R^{N_h * N_l}
Sij∈RNh∗Nl表示需要被学习的双线性空间映射矩阵,m和n分别为高级胶囊和低级胶囊的数量。
有了这样的一个路由logits,高级胶囊的候选vector就可以由所有低级胶囊的加权和表示:
其中
w
i
j
w_{ij}
wij表示连接低级胶囊和高级胶囊的权重,是由路由logits求softmax得到的:
最后,一个非线性的squash函数用来得到高级胶囊:
b
i
j
b_{ij}
bij的值被初始化为0,路由过程通常重复三次以使得胶囊值收敛,当路由结束后,高级胶囊的值就可以输入下一层。
3.2 B2I动态路由
Capsule Network中的Capsule概念对应于传统神经网络中的neuron,操作也类似。传统的神经网络输入一组标量,对这组标量求加权和,之后输入非线性激活函数得到一个标量的输出。而Capsule输入是一组向量,对这组向量进行仿射变换之后求加权和,把加权和输入非线性激活函数得到一个向量的输出。
基于向量的胶囊能够表示实体的不同属性,其中胶囊的方向表示一个属性,胶囊的长度用户表示该属性存在的概率。相应地,多兴趣提取层的目标是学习表达用户兴趣属性的表死后,以及是否存在相应地兴趣。胶囊和兴趣表征之间的语义联系促使我们将行为/兴趣表征视为行为/兴趣胶囊,并利用动态路由哦那个行为胶囊中学习兴趣胶囊。
我们可以把胶囊理解成一个由多个向量组成的神经元,每个向量可以表达实体的不同属性。我们对动态路由做了三个改动,以使之适用于用户兴趣的表示:
- 共享双线性映射矩阵。原始的动态路由每对高级-低级胶囊都有一个双线性映射矩阵,而我们对所有高级-低级胶囊共享同一个矩阵。我们这样做的原因一方面是用户的行为是变长的,我们希望固定的映射矩阵能够增强模型的泛化能力;另一方面,我们希望兴趣胶囊能够全部位于同一向量空间。于是路由逻辑可以表示为:
其中 e i e_i ei表示用户行为对应的物品i的embedding, u j u_j uj表示兴趣胶囊j的embedding - 路由逻辑的随机初始化。由于共享双线映射矩阵S,将路由logit初始化为0会导致初始兴趣胶囊完全一致,然后后续的迭代便会陷入一个循环:不同的兴趣胶囊参数始终是完全相同的。为避免这种情况,我们用从高斯分布中采样的随机矩阵来进行初始化。
- 动态兴趣数量。由于不同用户的兴趣胶囊数目不同,我们引入了一个启发式的规则来为不同的用户调整兴趣胶囊的数目K:用户u的K值由下式计算:
这一策略对于那些兴趣点较少的用户来说,既可以节约计算的时间,也可以节约内存。(但是这里不太明白是怎么做到向量空间统一的。。。)后面实验有针对这个策略进行验证,对CTR没有提升,所以好像可以不使用这个策略。
整个动态路由算法的流程为:
3.3 label aware attention
通过多兴趣抽取层我们生成了多个兴趣胶囊。不同的兴趣胶囊表示了用户兴趣的不同方面,相关的兴趣胶囊被用来评估用户对特定物品的兴趣。于是在训练期间我们设计了一个label-aware的attention层,attention是基于缩放点积的。特别地,对于一个目标item,我们计算出每个兴趣胶囊与它的相关性然后将兴趣胶囊加权求和作为用户向量。在label-aware attention中,label(目标item)是query,兴趣胶囊是key和value。输出的用户向量由下式计算:
其中p是个可调的参数,当p接近于0时,每个兴趣胶囊都会参与到运训中,p越大,点积较大的值就会有更大的权重。当p趋近于正无穷时,上式就变成了一个hard attention,也就是只采用点积最大的value而无视其他所有value。我们的实验表明hard attention能够加速收敛。
3.4 训练&线上服务
得到用户向量之后,用户u与物品i交互的概率就可以得到:
于是整体的目标函数就是:
其中D是包含用户和物品交互的训练集全集。由于物品的数量是十亿规模,我们在计算softmax的时候进行了采样。在训练的时候用了Adam优化器。
训练完成后,MIND网络会用来进行用户向量的生成。为一个用户生成多个兴趣向量后,用这些向量召回top N的item到推荐系统的下一步。
参考资料
- Multi-Interest Network with Dynamic Routing for Recommendation at Tmall
- 如何刻画用户的多样兴趣——MIND network阅读笔记