一、资料
目前的很多资料均是基于张伟楠的FNN模型,但还没有很大规模的应用。
另一种是google提出的wide & deep learning模型,主要用于推荐,美团的文章中也有介绍。
- Deep Learning over Multi-Field Categorical Data: A Case Study on User Response Prediction
-
- 介绍FNN模型。将FM模型训出的结果作为其中的embedding层,上面套上全连接神经网络。
- Product-based Neural Networks for User Response Predictions
-
- 介绍PNN模型。在FNN的embedding层的上面加入produce层,往上还是用全连接神经网络。
- Wide & Deep Learning for Recommender Systems
-
- Google提出的wide和deep learning模型。
- 用户在线广告点击行为预测的深度学习模型
-
- 这是来自张伟楠博士在携程技术中心主办的深度学习Meetup中的主题演讲。张伟楠博士现在是上海交大的助理教授,其个人主页是 http://wnzhang.net/,他是FNN和PNN的主要作者,还是SVDFeature的作者之一,11年和12年的KDD Cup都有他的身影。
- 闲聊DNN CTR预估模型
-
- 作者 Kintocai (蔡建涛,来自腾讯)
- 这篇文章写得非常好,而且还有作者的一些精辟分析和实践经验,特别是在最后给出了一个总结性的框架图,将这些模型以及一些连续特征的处理方法统一到一个整体框架中,非常赞。
- 很同意作者的好几个观点,比如:
-
- 在训练样本量足够的情况下,尽可能用简单一些的模型,减少inference的计算量,提高计算的吞吐量,大数据本身就可以解决很多问题。
- 离散LR依然是二分类问题场景的首选方案,LR加上良好的特征工程足以解决大部分实际问题。
- 不过对于dropout的使用,个人觉得在全连接层适当使用dropout是有用的,它可以在一定程度防止模型的过拟合。当然如果是训练数据量较大,特征维度较少时,dropout不是必需的。
二、FNN/PNN原理
主要摘自《 用户在线广告点击行为预测的深度学习模型》与《 闲聊DNN CTR预估模型》
1、基本思路
(1)使用FM计算出每个特征对应的隐变量。
(2)将样本中的每个特征转化为对应的隐变量。
(3)各个隐向量进行内积或者外积计算后,输入DNN模型
2、embedding:将one-hot离散数值映射为连续数值
我们需要将非常大的特征向量嵌入到低维向量空间中来减小模型复杂度,而FM(Factorisation machine)无疑是被业内公认为最有效的embedding model:
第一部分仍然为Logistic Regression,第二部分是通过两两向量之间的点积来判断特征向量之间和目标变量之间的关系。
3、基本网络
基于上面的讨论,我们可以得出以下DNN网络结构:
(1)各个field转化为对应的隐变量(这里假设每个field只有一个是特征是1,比如只有city=shanghai为1,其余为0,则只需要将shanghai这个特征转为相应的隐变量即可)
(2)将各个field的隐变量分别两两做内积/外积。
(3)将这个内积/外积结果作为输入,继续进入DNN计算。
4、FNN
根据上面的讨论,FNN的网络结构如下
5、FNN的效果
那我们可以看出FNN的效果优于LR和 FM 模型。我们进一步考虑FNN与一般的神经网络的区别是什么?大部分的神经网络模型对向量之间的处理都是采用加法操作,而FM 则是通过向量之间的乘法来衡量两者之间的关系。我们知道乘法关系其实相当于逻辑“且”的关系,拿上述例子来说,只有特征是学生而且在上海的人才有更大的概率去点击迪斯尼广告。但是加法仅相当于逻辑中“或”的关系,显然“且”比“或”更能严格区分目标变量。
6、PNN
我们接下来的工作就是对乘法关系建模。可以对两个向量做内积和外积的乘法操作:
可以看出对外积操作得到矩阵而言,如果该矩阵只有对角线上有值,就变成了内积操作的结果,所以内积操作可以看作是外积操作的一种特殊情况。通过这种方式,我们就可以衡量连个不同域之间的关系。
在此基础之上我们搭建的神经网络如下所示:
首先对输入数据进行embedding处理,得到一个low-dimensional vector层,对该层的任意两个feature进行内积或是外积处理就得到上图的蓝色节点,另外一种处理方式是把这些Feature直接和1相乘复制到上一层的Z中,然后把Z和P接在一起就可以作为神经网络的输入层,在此基础上我们就可以应用神经网络去模型了。
那么对特征做内积或是外积处理就会产生一个复杂度的问题:假设有60个域,那么把这些feature做内积处理,就会产生将近1800个元素的矩阵,如此就会产生一个很大的weight矩阵,那我们需要学习的参数就很多,那我们的数据集可能就满足不了这个要求。那接下来的做法就是:由于weight矩阵是个对称阵,我们可以用factorization来处理这个对称阵,把它转换为一个小矩阵乘以这个小矩阵的转置,这样就会大大减少我们所需要训练的参数:
7、PNN的效果
8、PNN隐藏层数量
我们还测试了最佳的隐层层数,隐层层数并不是越多越好,层数过多的模型会出现过拟合效应,这个隐层数是跟数据集大小相关,一般而言数据集越大所需要的隐层就越多,我们这里模型显示的最佳隐层是3层:
《用户在线广告点击行为预测的深度学习模型》还有其它一些数值配置
三、关于FNN/PNN的一些讨论
部分观点来自 《闲聊DNN CTR预估模型》
1、关于embedding
从离散到连续, embedding确实是非常合适的方案, embedding可以把离散特征嵌入到高纬连续空间, 而且embedding 可以通过BP训练求解。
Embedding解决了离散到连续的transform并不代表解决了所有的问题。CTR Prediction已经步入了千亿样本、千亿特征的时代[7],Google Play App 推荐都已经是5000亿样本了[8]。 如果每个离散特征都对应一个representation vector,假设dimension 为50, 那么就是50 * 千亿 级别的参数。毫无疑问, 训练如此庞大参数规模的模型是非常困难的,甚至不可为。解决这个问题可以有很多思路, 比如砍掉低频特征、降低representation vector dimension、特征选择、设计连续值特征等等。试着回想一下离散特征体系, 很容易可以发现离散特征总量是千亿级别, 但是category field (feature set或则叫feature slot)总数一般也就几十到几百, 那么一种很显而易见的思路就是把离散特征的representation vector 都归一到每个category field上, 如此一来dnn的输入规模瞬间回到了 num_category_field * dimension 的复杂度。
2、FM用作embedding
在FNN/PNN,train 一个FM模型就可以得到embedding。
工业上很多时候都会选择基于FM来产生representation,包括比较有名的百度凤巢、今日头条、阿里。【注:其实不是基于FM产生representation的方法最优秀, 只是国内大部分公司都没有复杂模型自主研发能力, 如果TF、MxNet之类开源DNN Lib没有现成支持离散特征Embedding版本的话就只好如此了。还有一种原因是线上迁移成本以及实际应用场景缘故导致的, 比如线上也想用FM\LR的预估。】输入层可以使用 FM产生的所有数据,包括feature vector、w,同时可以引入其他统计值特征以及新设计的连续值特征。学术界以及一些比赛当中会有一些CNN预估模型, 设计方案也特别令人印象深刻, 这里就不多展开了。
3、矩阵分解
通过使用每个category field的feature vector 做inner product 或则 outer product 来产生dnn 输入层(也就是上图里面的Product Layer)。这种做法有助于特征的交叉,同时也会导致另外一个问题: 输入层的膨胀。假设有100个category field, inner product 就会产生接近5000个输入节点, outer product 那就更多了。 为解决这个问题作者又引入了一个矩阵分解的方法来优化, 也算是比较常见的优化方法吧。除此之外,文章还提到了一些包括激活函数选择、 隐层数选择、dropout 概率选择等等trick, 这些都不是我今天想要讲的重点, 有兴趣的同学可以参看对应的paper。
4、样本假设的合理性
这里Dr.Zhang 有一个假设:
每个category field 有且只有唯一 positive value。
第一个问题是category 有且仅有一个positive value这个假设大部分时间是不成立的。比如用户的兴趣特征, 很可能有多个兴趣标签, 也可能缺失。当然这个问题也很好解决, 多个的话可以选择average(类似于Word2vec的隐层处理), 缺失的话可以选择均值默认填充。
5、dropout
第二个问题,dropout的真的好么?直观上广告特征输入的稀疏性很强, 大量的category field 缺失, dropout 很可能会极大稀疏性, 引起效果损失。但是用不用dropout没有绝对性, 和特征覆盖以及样本数量强相关, 比如你和百度凤巢或则Google一样拥有数千亿样本, 就没有必要使用dropout。
6、inner/outer product
第三个问题, 输入层是否真的需要做inner product或则outer product?这应该是学术界的方法, Dr.zhang引用的那篇文章还没公开发表, 所以暂时没有对比数据。但是只要展开w 以及feature vector, 隐层潜在就会完成outer product,通过隐层数以及隐层节点数可以控制交叉程度。 输入层复杂度增加会影响整个系统的吞吐,如果样本数据量足够大, 尽可能设计简单一些的模型, 提高吞吐量, 大数据本身就可以解决很多问题。
7、DNN真的就这么强吗?
DNN 虽然已经是非常常见的模型了, 而且工业界应用非常广泛了, 但是杀鸡焉用牛刀, 离散LR依然是二分类问题场景的首选方案。不可小看大离散LR, 设计精良的离散LR效果杠杠的, 足够解决大部分实际问题。