计算广告CTR预估系列(八)-PNN模型理论与实践

计算广告CTR预估系列(八)--PNN模型理论与实践

计算广告CTR预估系列(八)--PNN模型理论与实践

一、介绍

1.1 名词解释

1.2 数据特点

1.3 参数约定

二、相关工作

三、损失 & 评价函数

3.1 损失函数

3.2 评价函数

四、PNN详解

4.1 架构图

4.2 IPNN

4.3 OPNN

4.4 PNN*

五、优化

六、总结

七、代码实战

IPNN

OPNN

Reference

计算广告CTR预估系列往期回顾

一、介绍

非常感谢PNN论文作者,上海交通大学曲彦儒同学的耐心讲解,PNN细节的地方还是挺多的。作者的github大家可以关注下:

https://github.com/Atomu2014

1.1 名词解释

在信息检索领域(IR,Information Retrieval),个性化任务是一类非常重要的任务。包括:推荐系统、web search、线上广告。

其核心就是User Respinse Predicton,是指给出用户关于一个预先定义好的行为的概率。这些行为包括:clicks、purchases。预测的概率代表了用户对特定物品感兴趣的程度,物品包括:新闻、商品、广告。而这会影响商家对于展示文档的排序,广告投标等。

1.2 数据特点

IR问题最大的数据特点就是multi-field categorical,举例来说:

,经过one-hot之后转换成高纬度稀疏的数据:

One-hot示例

一个类别型特征就是一个field,比如上面的Weekday、Gender、City这是三个field。

1.3 参数约定

我们约定参数含义如下:

N。Field个数,也是嵌入向量的个数。

M。Embedding Vector的维度。

D1。第一个隐藏层的神经元个数。

lz。Product Layer中z对应的输出,也就是lz乘以全连接权重w就得到了第一个隐层的输入的一部分。

lp。Product Layer中p部分对应的输出,再经过全连接权重W就得到第一个隐层的输入的一部分。

二、相关工作

在PNN之前提出了Logistic Regression、GBDT、FM等模型,期待能高效的学习线性与非线性模式,减少人工特征工程的干预。但是都不是非常理想,像LR GBDT依旧非常依赖人工特征工程,FM则缺少对高阶组合特征的建模,仅仅对特定阶的组合特征建模。

随着DNN在图像处理、语音识别、自然语言处理领域大放异彩,将DNN应用于CTR预估或者推荐系统的研究逐渐多了起来。DNN的输入往往是dense real vector 但是multi-field类别型特征起初是高维且稀疏的。常见的做法是通过加入Embedding Layer将输入映射到低维度的Embedding空间中。FNN使用FM初始化embedding vector,同时也受限于FM;CCPM利用CNN卷积来学习组合特征,但是只在相邻的特征间卷积,没有考虑到非相邻的特征的组合;

所以有了PNN,主要的做法如下:PNN包括三层:Embedding Layer、Product Layer、Full-connect Layer。

最开始的输入太稀疏维度太高,没法直接放到DNN中去学习,所以比较通用的做法就是通过Embedding到一个低维的稠密的实数向量中,作为原始特征的在Embedding空间中的表示。

然后PNN利用Product Layer来学习filed之间的交互特征,这也就引入了非线性的组合特征。可以采用内积、外积、内积+外积的形式。

最后利用全连接层充分的学习高阶组合特征,并得到最终CTR预测概率。

三、损失 & 评价函数

3.1 损失函数

PNN使用的是log loss,形式化如下:

PNN log loss

3.2 评价函数

论文中给出了几种常用的评价函数,包括:AUC、log loss、RIG、RMSE。

RIG(Relative Information Gain), RIG = 1 - NE。 NE就是我们上一篇文章LR+GBDT中提到过的Normalized Cross Entropy。

四、PNN详解

4.1 架构图

PNN 架构图

我们按照上图,一层一层的来分析,看看从输入到输出,模型有哪些参数,参数的维度大小是多少,哪些需要训练,哪些不用训练:

Input

首先,一个类别型特征就是一个Field。比如用户信息包括:性别、职业等,这里的性别是一个Field,职业是另一个Field。上图中的Input是one-hot之后的,而且只给出了类别型特征。所以每个Field i都是一个向量,向量的大小就是类别型特征one-hot之后的维度。所以不同Field的维度是不同的。

Embedding Layer

上图说的非常清楚,Embedding是Field-wisely Connected。什么意思那?就是每个Field只管自己的嵌入,Field之间网络的权重毫无关系,自己学习自己的。而且只有权重,没有bias。一个Field经过嵌入后,得到一个Feature,也就是对应的Embedding Vector嵌入向量。其维度一般是预先设定好的定值,论文中采用的是10. 也就说是不同Feature的维度都是一样的。

Product Layer

重点来了,上图有个地方困扰我很久,最终跟论文作者讨论了下终于看懂了。先给出结论:

Product Layer中z中每个圈都是一个向量,向量大小为Embedding Vector大小向量个数 = Field个数 = Embedding向量的个数

Product Layer中如果是内积,p中每个圈都是一个值;如果是外积,p中每个圆圈都是一个二维矩阵

一个是向量,一个是值(也可能是矩阵),全给画成圈了(吐槽下……)

解释下怎么回事,这里对于Embedding Vector有两种处理策略:

直接和内积或外积结果拼接,输入到神经网络

先进行一次线性变换,再和内积或外积结果拼接,输入到神经网络

Embedding Layer中的那个1,其实就是直接把Embedding Vector拿来用并没有进行线性变换。这样做处理起来很简单,但是也有个缺点。Embedding Vector和内积项或外积项的数值分布差异交大,没有进行线性变换,导致分布不稳定不利于训练。不过,听作者说,在新论文中这个问题已经被很好的解决了,大家拭目以待吧~

在数据流中,假设Field个数为N,那么经过Embedding后的Field得到了N个Feature,或者说是N个嵌入向量。这N个嵌入向量直接拿过来并排放到z中就是z。这部分代表的是对低维度特征,或者说原始特征的建模。作者的说法是,不加入这一部分训练会非常不稳定,加入之后稳定了很多。

然后,针对这N个嵌入向量,两两组合进行Product operation,把结果放到一起就得到了p。首先,N个向量两两组合,会产生对组合,这就是p中圆圈的个数,或者说神经元的个数。如果是内积运算,那么每个神经元就是一个实数值;如果进行外积运算,那么每个神经元就是一个二维矩阵。后面我们详细讨论。

Hidden Layer

把z和p直接拼接起来,就得到了第一个隐层的输入。经过多个隐藏层最后给出CTR预测值。

根据Product Layer的操作不同,PNN有三种变体:IPNN、OPNN、PNN*

4.2 IPNN

如果Product Layer使用内积运算,那么就是IPNN。p中每个神经元都是一个实数值,和z中的嵌入向量拼接起来,喂给神经网络就行了。

4.3 OPNN

如果Product Layer使用外积运算,就得到OPNN。外积得到的是一个矩阵,所以p中的每个神经元都是一个矩阵。针对两个M维的嵌入向量e1和e2. 它们外积得到的是M*M的二维矩阵。一共有N个嵌入向量,那么矩阵就有个。那么一个二维矩阵怎么输入到神经网络中去那?

针对外积产生的每一个二维矩阵,我们都通过另外一个矩阵W,大小为M*M。这两个矩阵对应位置相乘,再相加,就得到了最终的结果。

也就是说,最终外积产生的二维矩阵,通过和另外一个需要学习的参数矩阵,对应位置相乘,再相加,得到了一个标量,一个实数值。

逻辑上如下图所示:

PNN_Product_Layer逻辑理解

上图是最朴素的逻辑,实际写代码的时候利用下面的公式来稍微降低下复杂度:

假设两个嵌入向量,列向量U,V。⊙表示对应位置相乘,然后再相加的操作。UV的外积结果为二维矩阵。那么有公式:

UV

T

⊙W=U

T

WV

等式右边比左边的复杂度要低一些。写代码的时候,就是按照公式右边来计算的。公式可以这样理解:外积与参数矩阵相乘,相当于对u经过w矩阵投影,在投影空间中与v计算内积。是一个非常有用的trick。这里的参数矩阵并不是神经网络的参数矩阵,而是用来把外积的结果矩阵,转变为一个实数值的矩阵,对应代码中的kernel矩阵。

4.4 PNN*

如果Product Layer同时使用内积+外积,把内积和外积的结果拼接起来,就得到PNN*。

五、优化

PNN中针对内积和外积的运算都进行了优化。但是其实并不是必须的,只要计算资源足够,两个优化直接忽略即可。

PNN原始的论文中,针对外积部分每两个嵌入向量组合,一共有这么多对组合。这个复杂度是O(NN)的,论文中通过下面的公式进行了化简:

论文中针对外积的优化,已经去掉

其中的fi就是嵌入向量。也就是说先把所有的嵌入向量相加求和,然后再和自己进行外积。得到一个(N,N)的外积矩阵。然后再和D1个不同的W进行对应位置相乘相加的操作,就得到了最后隐藏层输入的D1个值。

这里的优化主要是把嵌入向量的个组合对,优化成了一个。把平方的复杂度降低到线性的。

但是,经过作者沟通了解到,这一部分的优化其实没必要,在新的PNN中已经去掉了!

为什么那?因为即使是N平方的复杂度,但是每两个嵌入向量进行外积的计算完全可以并行化!其实是可以接受的,所以现在已经去掉了。

我们后面给出的代码也是没有进行优化的,因为嵌入向量的pair仍然是N^2的。

六、总结

PNN从FM何FNN的角度出发,提出利用内积或者外积来学习高阶的非线性特征,还是挺有创新的。

基本上使用DNN的模型,最开始都是经过Embedding把原始高纬度稀疏的输入转换为低维度稠密的向量,PNN也不例外。对于FM来说,这就是隐向量,FNN也是利用FM来进行Embedding Vector的初始化的。

PNN中如果采用内积操作,那么嵌入向量两两组合每对组合都得到一个实数值。如果后面隐藏层的权重矩阵W全是1的话,那么PNN就变成了FM。

PNN使用外积操作稍微麻烦,因为嵌入向量两两组合后,每对组合就是一个二维矩阵。那么怎么把这些二维矩阵输入到神经网络中那?通过和一个矩阵对应位置相乘在相加,就把这些二维外积矩阵转换成了一个实数值。

OPNN的实现代码中利用了公式进行了转换,稍微降低了复杂度。公式如下:

UV

T

⊙W=U

T

WV

另外,PNN论文中针对外积部分的优化,跟作者沟通得知在新的论文中已经去掉了,大家就不用纠结了

七、代码实战

数据的输入,Embedding Vector都是相同的,关键代码如下:

初始化Sparse Input到Embedding向量的权重参数,注意没有bias。而且Field自己进行自己的嵌入,不同的Field之间没有关系。

Product Layer中p部分pair数量,以及其输出的维度lz+lp:

Embedding操作,得到Embedding向量xw3d以及lz部分xw:

分别得到进行内积或外积操作的向量对,p中存储第一个向量,q中存储对应的第二个向量:

IPNN

对嵌入向量两两进行内积操作,得到

lz部分和lp部分组合起来,得到最终的Product Layer的输出:

经过隐藏层的激活,得到最终CTR结果:

OPNN

和IPNN不同的地方只有内积改为外积,也就是Product Layer中p部分的输出不同。关键代码如下:

初始化用于对外积结果矩阵进行对应位置相乘,再相加操作的矩阵:

得到组合的嵌入向量对p,q。根据公式

UV

T

⊙W=U

T

WV

,两个嵌入向量外积,再与矩阵W对位相乘相加,就等价于p的转置先和W相乘(真正的向量与矩阵相乘),在与V相乘(向量与向量相乘)。

但是,tensorflow不支持矩阵与向量相乘。所以我们需要把他拆分为向量与向量相乘,然后再求和。这就是这里还利用了multiply的boradcast特性:

最后,得到Product Layer层的输出,再连接到神经网络中得到最后的输出。注意Product Layer与First Hidden Layer之间是有全连接层连接的,这里的参数是需要学习的哦:

完整的代码,可以到我的github上找到,欢迎star

https://github.com/gutouyu/ML_CIA

Reference

Product-based Neural Networks for User Response Prediction

论文作者给出的实现

https://github.com/Atomu2014/product-nets

最后,用总裁的帽子戏法能镇住楼不?

第一步:吸气

第二步:得分

  • 发表于:
  • 原文链接https://kuaibao.qq.com/s/20180617G15Z4N00?refer=cp_1026
  • 腾讯「云+社区」是腾讯内容开放平台帐号(企鹅号)传播渠道之一,根据《腾讯内容开放平台服务协议》转载发布内容。
  • 如有侵权,请联系 yunjia_community@tencent.com 删除。

扫码关注云+社区

领取腾讯云代金券