推荐系统(十一)阿里深度兴趣网络(一):DIN模型(Deep Interest Network)

推荐系统(十一)阿里深度兴趣网络(一):DIN模型(Deep Interest Network)

推荐系统系列博客:

  1. 推荐系统(一)推荐系统整体概览
  2. 推荐系统(二)GBDT+LR模型
  3. 推荐系统(三)Factorization Machines(FM)
  4. 推荐系统(四)Field-aware Factorization Machines(FFM)
  5. 推荐系统(五)wide&deep
  6. 推荐系统(六)Deep & Cross Network(DCN)
  7. 推荐系统(七)xDeepFM模型
  8. 推荐系统(八)FNN模型(FM+MLP=FNN)
  9. 推荐系统(九)PNN模型(Product-based Neural Networks)
  10. 推荐系统(十)DeepFM模型

写在前面:
建议大家看DIN论文的时候看arxiv上的V1版本,传送门链接:DIN v1版本,不要看发表在KDD’18上的正式论文,个人认为正式版本的论文包装的太过厉害,尤其模型部分的图,看完之后完全不理解模型细节。而arxiv上的v1版本则朴实无华,非常容易理解,模型细节呈现的比较清晰。强烈建议看v1版本。

DIN(Deep Interest Network)模型是阿里妈妈盖坤团队发表在KDD’18上的文章,因为有阿里的光环,因此,这个模型在业界还是比较有名气的,至于最终在其他公司场景下有没有效果,取决于对比的baseline,如果你的baseline足够弱,理论上会有一定效果的提升,当然,如果你的baseline够强,可能一点效果都没有。之前博客介绍的模型都在解决如何有效的学到高阶交叉特征,而DIN的核心思想是把attention机制引入了到用户兴趣建模上。

工业界当前广告/推荐的模型基本都是遵循Embedding&MLP(embedding+mlp)的范式,在embedding阶段,所有的离散特征都要被映射成一个固定长度的低维稠密向量。离散特征一般有单值特征和多值特征,分别要做one-hot编码和multi-hot编码,单值特征没什么问题,直接映射成embedding向量即可,而对于多值特征,比如:用户点击过的item序列,用户点击过item类目的序列,通常的操作都是每个item映射成一个embedding向量,然后做一个sum/average pooling,最终得到一个embedding向量。当然,有条件的厂可能还会对这个序列使用一个LSTM,效果嘛,看天吃饭,反正也是有的没的。下图展示了单值特征和多值特征做embedding向量时的区别。

推荐系统(十一)阿里深度兴趣网络(一):DIN模型(Deep Interest Network)_第1张图片
接下来,重点来了,我们在对多值特征做pooling的时候,只是简单的做sum或者average,这相当于认为序列中的每个item的重要性是一样的,所以最好的方式是给每个item一个权重,问题是权重怎么给?依据什么给?DIN这篇paper则非常朴素的认为,因为你的task是CTR预估,那么显然每个item的权重应该由目标广告(商品)与该item之间的相关性决定

用论文中的一个例子来说明,假设某个用户在最近XX内点击(收藏、或者其他行为)序列为:泳衣、泳帽、薯片、坚果、书籍。候选广告是:护目镜。那么,显然在用户的点击行为序列中,决定这个用户是否点击推荐的护目镜是泳衣和泳帽,因为这两个item与目标候选广告之间相关性更强,因此所做的贡献也就更大。所以,DIN做的就是把传统多值特征做pooling的方式加了个权重,而这个权重是由item个候选广告之间的相关性决定的

这里我们延伸一下,思考一下,有过工业界广告/推荐经验的同学应该很清楚,在Embedding&MLP的范式架构下,依然需要大量的人工特征工程,其中包含了大量的交叉特征。我个人酷爱的一类交叉特征是:目标与行为的交集及数量。比如上面那个例子,用户历史行为为:泳衣、泳帽、薯片、坚果、书籍,候选广告为护目镜。泳衣、泳帽与护目镜的类目都是相同的,因此我们可以用:护目镜类目与上述用户点击过item的类目做交集及数量,得到的结果为:泳衣类#2,2为交集集合长度(泳帽、泳衣、护目镜都属于泳衣类)。因此,如果有了这个交叉特征,理论上普通的Embedding&MLP效果应该不比DIN差多少,所以,如果你打算尝试DIN,不妨先试试上面我说的方法

相比较上面我说的方式,DIN里的做法更加soft,更加丝滑。这里不得不感叹,这种小细节,经过比较好的包装,外加一些其他方面的创新,就能够产生一篇高质量的论文,因此,阿里妈妈每年能产出这么多paper也不是没有原因的。

说了这么多,我们来具体剖析下DIN这篇论文,接下来将会从以下几个方面来介绍DIN:

  1. DIN模型整体的网络结构
  2. DIN网络核心模块Activation unit
  3. 自适应的正则技术:Adaptive Regularization Technique
  4. 激活函数Dice(Data Adaptive Activation Function)
  5. 评估方式GAUC

一、DIN模型整体的网络结构

直接上图,来看看DIN的网络结构(图片来自arxiv上DIN v1版论文,KDD的正式版包装的都不认识了,必须吐槽下~)
推荐系统(十一)阿里深度兴趣网络(一):DIN模型(Deep Interest Network)_第2张图片
DIN网络结构整体上来看是在embedding层与MLP(全连接层)之间加入了activation unit。从上图,我们能够看出,用户历史点击过的商品id(good id)只与候选广告的商品id算相关性(上图中是element-wise减,当然你也可以算内积等,甚至可以都算),用户历史点击过的商铺id只与候选广告的商铺id算相关性。

二、DIN网络核心模块Activation unit

这个模块是整个DIN网络的核心模块,也是该模型的创新之处,如下图所示。
推荐系统(十一)阿里深度兴趣网络(一):DIN模型(Deep Interest Network)_第3张图片
上图比较清晰的展示了activation unit模块是如何工作的,以用户历史行为的商品id序列与候选广告id举例子。
假设用户历史行为:

  1. 商品id序列为 u g = [ u g 1 , u g 2 , . . . , u g n ] ug = [ug_1,ug_2,...,ug_n] ug=[ug1,ug2,...,ugn],经过embedding层后对应的向量为 u g e = [ u g e 1 , u g e 2 , . . . , u g e n ] uge = [uge_1,uge_2,...,uge_n] uge=[uge1,uge2,...,ugen]
  2. 商铺id序列为 u s = [ u s 1 , u s 2 , . . . , u s n ] us = [us_1,us_2,...,us_n] us=[us1,us2,...,usn],经过embedding层后对应的向量为 u s e = [ u s e 1 , u s e 2 , . . . , u s e n ] use = [use_1,use_2,...,use_n] use=[use1,use2,...,usen]

候选广告:

  1. 商品id为 a g ag ag,经过embedding层后对应的向量为 a g e age age
  2. 商品id为 a s as as,经过embedding层后对应的向量为 a s e ase ase

则activation unit的做法为:

  1. 把用户历史行为的商品向量与候选广告商品向量做 ⊝ \circleddash (向量对应元素相减),即 a u g = [ a g e ⊝ u g e 1 , a g e ⊝ u g e 2 , . . . , a g e ⊝ u g e n ] aug = [age\circleddash uge_1, age\circleddash uge_2,..., age\circleddash uge_n] aug=[ageuge1,ageuge2,...,ageugen]
  2. 把用户历史行为的商铺向量与候选广告商铺向量做 ⊝ \circleddash ,即 a u s = [ a s e ⊝ u s e 1 , a s e ⊝ u s e 2 , . . . , a s e ⊝ u s e n ] aus = [ase\circleddash use_1, ase\circleddash use_2,..., ase\circleddash use_n] aus=[aseuse1,aseuse2,...,aseusen]
  3. 把1,2步中得到的结果向量 a u g , a u s aug, aus aug,aus与用户商品向量 u g e uge uge,用户商铺向量 u s e use use,候选广告商品向量 a g ag ag,候选广告商铺向量 a s as as,做拼接concatenate,输入一个全连接网络

用论文中形式化的公式表达为(虽然个人认为有了上面的例子,公式没必要了,但还是贴出来吧):
V u = f ( V a ) = ∑ i = 1 N w i ∗ V i = ∑ i = 1 N g ( V i , V a ) ∗ V i (1) V_u = f(V_a) = \sum_{i=1}^Nw_i*V_i = \sum_{i=1}^Ng(V_i,V_a)*V_i \tag{1} Vu=f(Va)=i=1NwiVi=i=1Ng(Vi,Va)Vi(1)
其中, V u V_u Vu表示用户 u u u的向量, V a V_a Va表示广告 a a a的向量, V i V_i Vi表示行为 i i i的向量(比如商品id,商铺id), w i w_i wi表示行为 i i i的attention得分。

论文中给出的是同类id做向量减 ⊝ \circleddash ,当然你可以做内积,甚至都要。DIN作者给出的实现中就使用了内积,参见:https://github.com/zhougr1993/DeepInterestNetwork/blob/master/din/model_dice.py#L241
另外一点是,论文中明确说了他们没有把权重做归一化,论文原文为:

That is, normalization with softmax on the output of a(·) is abandoned. Instead, value of ∑ i w i \sum_iw_i iwi is treated as an approximation of the intensity of activated user interests to some degree.

但在实现的时候,却用了softmax做归一化,参见:https://github.com/zhougr1993/DeepInterestNetwork/blob/master/din/model_dice.py#L221

我们来看下具体的实现(paddle):

		"""
		hist_item_seq: 用户点击过的商品序列,Tensor(shape=[32, 2], 
		               2-->由该batch内用户点击过的商品序列最大长度决定,比如20。
                       不够的用0(不在id集合内的任意数字都可以)补全
        hist_cat_seq: Tensor(shape=[32, 2], 用户点击过的商品类目序列,同hist_item_seq
        target_item:  Tensor(shape=[32],推荐广告商品
        target_cat: Tensor(shape=[32],推荐广告商品类目
        label: Tensor(shape=[32, 1],点击标记
        mask: Tensor(shape=[32, 2, 1],mask矩阵,用于hist_item_seq和hist_cat_seq中补        0的部分失效,对于补齐的网格部分,初始化为-INF,从而在sigmoid后,使之失效为0; 目前做法是有数据的为0,补齐的用-INF
        target_item_seq: Tensor(shape=[32, 2],因为候选打分广告item要与用户点击过的每个item做减法(或内积,或加法),因此,需要把target_item扩展成与hist_item_seq维度一样,即把target_item重复len(hist_item_seq)次
        target_cat_seq: Tensor(shape=[32, 2],同target_item_seq
		"""
		# Tensor(shape=[32, 2, 128])
        hist_seq_concat = paddle.concat([hist_item_emb, hist_cat_emb], axis=2)
        # Tensor(shape=[32, 2, 128])
        target_seq_concat = paddle.concat(
            [target_item_seq_emb, target_cat_seq_emb], axis=2)
        # Tensor(shape=[32, 128]
        target_concat = paddle.concat(
            [target_item_emb, target_cat_emb], axis=1)
        # shape=[32, 2, 512]
        # 1. 这里不光做element-wise减,还做内积
        concat = paddle.concat(
            [
                hist_seq_concat, target_seq_concat,   # shape=[32, 2, 128], shape=[32, 2, 128]
                hist_seq_concat - target_seq_concat,  # shape=[32, 2, 128]
                hist_seq_concat * target_seq_concat   # shape=[32, 2, 128]
            ],
            axis=2)
        # 2. 输入一个全连接网络
        # [Linear(in_features=512, out_features=80, dtype=float32), Sigmoid(), 
        # Linear(in_features=80, out_features=40, dtype=float32), Sigmoid(), 
        # Linear(in_features=40, out_features=1, dtype=float32)]
        for attlayer in self.attention_layer:
            concat = attlayer(concat)
        # concat: Tensor(shape=[32, 2, 1]
        atten_fc3 = concat + mask
        # Tensor(shape=[32, 1, 2]
        atten_fc3 = paddle.transpose(atten_fc3, perm=[0, 2, 1])
        # Out=scale*X
        # Tensor(shape=[32, 1, 2]
        atten_fc3 = paddle.scale(atten_fc3, scale=self.firInDim**-0.5)
        # 3. 权重归一化
        # Tensor(shape=[32, 1, 2]
        weight = paddle.nn.functional.softmax(atten_fc3)
        # [32, 1, 2]*[32, 2, 128] = [32, 1, 128]
        # 4. 权重与用户历史行为序列(商品,商铺)相乘
        # Tensor(shape=[32, 1, 128]
        output = paddle.matmul(weight, hist_seq_concat)
        # Tensor(shape=[32, 128]
        output = paddle.reshape(output, shape=[0, self.firInDim])

最后,论文中给出了一张示意图比较清晰的展示了用户历史行为item与广告item之间的attention得分,DIN这种基于attention score的设计比较soft的得到了用户历史行为中每个item对于目标广告item的贡献度。
推荐系统(十一)阿里深度兴趣网络(一):DIN模型(Deep Interest Network)_第4张图片

三、自适应的正则技术:Adaptive Regularization Technique

这部分在KDD版本论文里被称为Mini-batch Aware Regularization,行吧,又是一个高大上的名词。既然是正则技术,显然是为了防止过拟合的,常用的防止过拟合的技术有:L1正则、L2正则和dropout等。不用L2正则的原因一来是计算复杂度相对较高,二来是在广告/推荐领域中导致过拟合的主要原因是数据的长尾分布导致的,很多特征值在整个数据集出现的频率非常低。当然,最常见的处理办法是在训练之前设置个频率阈值,过滤掉低于阈值的特征值,但这种方法多少有点僵硬。

阿里在这篇论文里提出了Adaptive Regularization Technique,即根据特征值的出现频率给其施加不同的正则话强度。当然这个技术基本上就是把李沐大佬论文DiFacto — Distributed Factorization Machines的东西搬过来微调了下,事后来看这么调的原因应该也是实践锤炼出来的。先来看李沐论文里的公式:
w i = w i − η [ 1 b ∑ ( x j , y j ) ∈ B ∂ L ( f ( x j ) , y j ) ∂ w i + λ n i w i I i ] (2) w_i = w_i - \eta [\frac{1}{b}\sum_{(x_j,y_j)\in B}\frac{\partial L(f(x_j),y_j)}{\partial w_i} + \lambda n_iw_iI_i] \tag{2} wi=wiη[b1(xj,yj)BwiL(f(xj),yj)+λniwiIi](2)
其中, B B B表示mini-batch内的样本集合, b b b 表示样本数量,等于batch size。 n i n_i ni表示特征 i i i出现的频率, λ \lambda λ为正则化系数。 I i I_i Ii表示该mini-batch内的样本 j j j是否包含特征 i i i(就是非缺失值),包含则为1,否则为0。
再来看看阿里DIN论文改造之后的公式:
w i = w i − η [ 1 b ∑ ( x j , y j ) ∈ B ∂ L ( f ( x j ) , y j ) ∂ w i + λ 1 n i w i I i ] (3) w_i = w_i - \eta [\frac{1}{b}\sum_{(x_j,y_j)\in B}\frac{\partial L(f(x_j),y_j)}{\partial w_i} + \lambda \frac{1}{n_i}w_iI_i] \tag{3} wi=wiη[b1(xj,yj)BwiL(f(xj),yj)+λni1wiIi](3)
公式(2)和公式(1)唯一的区别就在于 n i n_i ni 1 n i \frac{1}{n_i} ni1,也就是对频率高的特征究竟是该较大的惩罚,还是较小的惩罚。李沐论文里(公式1)是对出现频率高的特征给予较大的惩罚,而DIN则是对出现频率高的特征给予较小的惩罚。两种方法孰优孰劣,还是要看具体的场景,适用场景的才是最好的,就像公式(2)适用阿里的场景,因为高频率的特征对于用户兴趣的刻画更加准确。
DIN论文里给出了几种方法的比较:

  • 不用正则项
  • dropout
  • 直接设立一个阈值过滤:Filter good ids by occurrence frequency in samples and leave only the most frequent good ids. In our setup, top 20 million good ids are left
  • 公式(1)里的正则
  • L2正则
  • 公式(2)的Adaptive Regularization

推荐系统(十一)阿里深度兴趣网络(一):DIN模型(Deep Interest Network)_第5张图片

四、激活函数Dice(Data Adaptive Activation Function)

这里主要是对PReLU的改进,PReLU是何凯明大神发表在ICCV’15上的一篇论文中提出的,咱们先看LeakyReLU:
f ( x ) = { x , x > = 0 α x , x < 0 (4) f(x) = \left\{\begin{matrix} x , & x>=0\\ \alpha x , & x<0 \\ \end{matrix}\right. \tag{4} f(x)={x,αx,x>=0x<0(4)
其中, α \alpha α通常设置为0.01。这也是LeakyReLU的引入的一个缺点,即 α \alpha α是个常量,在深度学习的年代里,因为数据量的有恃无恐,一切常量都可变变量,交给网络date-driven的学,因此就有了PReLU, α \alpha α不再是一个固定的值,而是一个超参数,交给网络去学。为了后面和Dice做对比,我们把公式(3)换个等价的形式:
f ( x ) = m a x ( 0 , x ) + α ∗ m i n ( 0 , x ) (5) f(x)=max(0,x)+\alpha∗min(0,x) \tag{5} f(x)=max(0,x)+αmin(0,x)(5)
下面来看看Dice的公式:
f ( x ) = α ( 1 − p ) x + p x (5) f(x)=\alpha(1-p)x + px \tag{5} f(x)=α(1p)x+px(5)
上式中的 p = 1 1 + e − x − E ( x ) v a r ( x ) + ϵ p=\frac{1}{1+e^{-\frac{x-E(x)}{\sqrt{var(x)+\epsilon }}}} p=1+evar(x)+ϵ xE(x)1,其中 E ( x ) E(x) E(x) v a r ( x ) var(x) var(x)为mini-batch内的均值和方差,在训练过程中直接计算即可。

五、评估方式GAUC

GAUC也算是这篇文章的亮点之一,在业界也有比较大的影响。显然GAUC是对AUC的一个改进,GAUC细化到每个用户维度,假设有 n n n个用户,则GAUC的公式:
G A U C = ∑ i = 1 n w i ∗ A U C i ∑ i = 1 n w i = ∑ i = 1 n i m p r e s s i ∗ A U C i ∑ i = 1 n i m p r e s s i (6) GAUC=\frac{\sum_{i=1}^nw_i * AUC_i}{\sum_{i=1}^nw_i } =\frac{\sum_{i=1}^nimpress_i * AUC_i}{\sum_{i=1}^nimpress_i } \tag{6} GAUC=i=1nwii=1nwiAUCi=i=1nimpressii=1nimpressiAUCi(6)
其中 w i w_i wi可以是用户的点击数量或者曝光数量。





参考文献
  1. Zhou G, Zhu X, Song C, et al. Deep interest network for click-through rate prediction[C]//Proceedings of the 24th ACM SIGKDD international conference on knowledge discovery & data mining. 2018: 1059-1068.
  2. Li M, Liu Z, Smola A J, et al. Difacto: Distributed factorization machines[C]//Proceedings of the Ninth ACM International Conference on Web Search and Data Mining. 2016: 377-386.

你可能感兴趣的:(推荐系统,机器学习&深度学习,推荐算法,DIN,深度兴趣网络,CTR预估)