推荐系统遇上深度学习(二十四)--深度兴趣进化网络DIEN原理及实战!

2023-07-04 10:38:45 学习 推荐 深度 二十四 遇上

在本系列的第十八篇(jianshu.com/p/73b6f5d00)中,我们介绍了阿里的深度兴趣网络(Deep Interest Network,以下简称DIN),时隔一年,阿里再次升级其模型,提出了深度兴趣进化网络(Deep Interest Evolution Network,以下简称DIEN,论文地址:arxiv.org/pdf/1809.0367),并将其应用于淘宝的广告系统中,获得了20.7%的CTR的提升。本篇,我们一同来探秘DIEN的原理及实现。

1、背景

在大多数非搜索电商场景下,用户并不会实时表达目前的兴趣偏好。因此通过设计模型来捕获用户的动态变化的兴趣,是提升CTR预估效果的关键。阿里之前的DIN模型将用户的历史行为来表示用户的兴趣,并强调了用户兴趣的多样性和动态变化性,因此通过attention-based model来捕获和目标物品相关的兴趣。虽然DIN模型将用户的历史行为来表示兴趣,但存在两个缺点:
1)用户的兴趣是不断进化的,而DIN抽取的用户兴趣之间是独立无关联的,没有捕获到兴趣的动态进化性
2)通过用户的显式的行为来表达用户隐含的兴趣,这一准确性无法得到保证。

基于以上两点,阿里提出了深度兴趣演化网络DIEN来CTR预估的性能。DIEN模型的主要贡献点在于:
1)模型关注电商系统中兴趣演化的过程,并提出了新的网络结果来建模兴趣进化的过程,这个模型能够更的表达用户兴趣,同时带来更高的CTR预估准确率。
2)设计了兴趣抽取层,并通过计算一个辅助loss,来提升兴趣表达的准确性。
3)设计了兴趣进化层,来更加准确的表达用户兴趣的动态变化性。

接下来,我们来一起看一下DIEN模型的原理。

2、DIEN模型原理

2.1 模型总体结构

我们先来对比一下DIN和DIEN的结构。
DIN的模型结构如下:



DIN

DIEN的模型结构如下:



DIEN

可以看到,DIN和DIEN的底层都是Embedding Layer,User profile, target AD和context feature的处理方式是一致的。不同的是,DIEN将user behavior组织成了序列数据的形式,并把简单的使用外积完成的activation unit变成了一个attention-based GRU网络。

2.2 兴趣抽取层Interest Extractor Layer

兴趣抽取层Interest Extractor Layer的主要目标是从embedding数据中提取出interest。但一个用户在某一时间的interest不仅与当前的behavior有关,也与之前的behavior相关,所以作者们使用GRU单元来提取interest。GRU单元的表达式如下:



GRU表达式

这里我们可以认为ht是提取出的用户兴趣,但是这个地方兴趣是否表示的合理呢?文中别出心裁的增加了一个辅助loss,来提升兴趣表达的准确性:



这里,作者设计了一个二分类模型来计算兴趣抽取的准确性,我们将用户下一时刻真实的行为e(t+1)作为正例,负采样得到的行为作为负例e(t+1)',分别与抽取出的兴趣h(t)结合输入到设计的辅助网络中,得到预测结果,并通过logloss计算一个辅助的损失:



2.3 兴趣进化层Interest Evolution Layer

兴趣进化层Interest Evolution Layer的主要目标是刻画用户兴趣的进化过程。举个简单的例子:

以用户对衣服的interest为例,随着季节和时尚风潮的不断变化,用户的interest也会不断变化。这种变化会直接影响用户的点击决策。建模用户兴趣的进化过程有两方面的好处:
1)追踪用户的interest可以使我们学习final interest的表达时包含更多的历史信息。
2)可以根据interest的变化趋势更好地进行CTR预测。

而interest在变化过程中遵循如下规律:
1)interest drift:用户在某一段时间的interest会有一定的集中性。比如用户可能在一段时间内不断买书,在另一段时间内不断买衣服。
2)interest individual:一种interest有自己的发展趋势,不同种类的interest之间很少相互影响,例如买书和买衣服的interest基本互不相关。

为了利用这两个时序特征,我们需要再增加一层GRU的变种,并加上attention机制以找到与target AD相关的interest。

attention的计算方式如下:



而Attention和GRU结合起来的机制有很多,文中介绍了一下三种:

GRU with attentional input (AIGRU)
这种方式将attention直接作用于输入,无需修改GRU的结构:



Attention based GRU(AGRU)
这种方式需要修改GRU的结构,此时hidden state的输出变为:



GRU with attentional update gate (AUGRU)
这种方式需要修改GRU的结构,此时hidden state的输出变为:



2.4 模型试验

文章在公共数据和自己的数据集上都做了实验,并选取了不同的对比模型:



离线实验的结果如下:







DIEN使用了辅助loss和AUGRU结构,而BaseModel + GRU + AUGRU与DIEN的不同之处就是没有增加辅助loss。可以看到,DIEN的实验效果远好于其他模型。

3、DIEN模型实现

本文模型的实现参考代码是:github.com/mouna99/dien
本文代码的地址为:github.com/princewen/te
本文数据的地址为:github.com/mouna99/dien

3.1 数据介绍

根据github中提供的数据,解压后的文件如下:
uid_voc.pkl: 用户名对应的id
mid_voc.pkl: item对应的id
cat_voc.pkl:category对应的id
item-info:item对应的category信息
reviews-info:用于进行负采样的数据
local_train_splitByUser:训练数据,一行格式为:label、用户名、目标item、 目标item类别、历史item、历史item对应类别。
local_test_splitByUser:测试数据,格式同训练数据

3.2 代码实现

本文的代码主要包含以下几个文件:
rnn.py:对tensorflow中原始的rnn进行修改,目的是将attention同rnn进行结合。
vecAttGruCell.py: 对GRU源码进行修改,将attention加入其中,设计AUGRU结构
data_iterator.py:数据迭代器,用于数据的不断输入
utils.py:一些辅助函数,如dice激活函数、attention score计算等
model.py:DIEN模型文件
train.py:模型的入口,用于训练数据、保存模型和测试数据

好了,接下来我们介绍一些关键的代码:

输入数据介绍

输入的数据有用户id、target的item id、target item对应的cateid、用户历史行为的item id list、用户历史行为item对应的cate id list、历史行为的长度、历史行为的mask、目标值、负采样的数据。

对于每一个用户的历史行为,代码中选取了5个样本作为负样本。

self.mid_his_batch_ph = tf.placeholder(tf.int32,[None,None],name='mid_his_batch_ph')
self.cat_his_batch_ph = tf.placeholder(tf.int32,[None,None],name='cat_his_batch_ph')
self.uid_batch_ph = tf.placeholder(tf.int32,[None,],name='uid_batch_ph')
self.mid_batch_ph = tf.placeholder(tf.int32,[None,],name='mid_batch_ph')
self.cat_batch_ph = tf.placeholder(tf.int32,[None,],name='cat_batch_ph')
self.mask = tf.placeholder(tf.float32,[None,None],name='mask')
self.seq_len_ph = tf.placeholder(tf.int32,[None],name='seq_len_ph')
self.target_ph = tf.placeholder(tf.float32,[None,None],name='target_ph')
self.lr = tf.placeholder(tf.float64,[])
self.use_negsampling = use_negsampling
if use_negsampling:
    self.noclk_mid_batch_ph = tf.placeholder(tf.int32, [None, None, None], name='noclk_mid_batch_ph')
    self.noclk_cat_batch_ph = tf.placeholder(tf.int32, [None, None, None], name='noclk_cat_batch_ph')

相关文章