Wide & Deep Model
文章目录
为什么要提出 Wide & Deep 模型?
传统的“特征海洋”战术实际上是一个很“宽”的模型,利用手工构造的交叉组合特征来使线性模型具有“记忆性”,使模型记住共现频率较高的特征组合,往往也能达到一个不错的baseline,且可解释性强。缺点有二:
- 特征工程需要耗费太多精力。
- 模型是强行记住这些组合特征的,对于未曾出现过的特征组合,权重系数为0,无法进行泛化。
深度神经网络用“深度”来革传统的“线性模型+特征工程”的命。用“深”代替“宽”。使用深度神经网络代替特征工程很“省事”,而且增强了泛化性,但由此带来的一个缺点就是可解释性不强。
Wide&Deep模型就是围绕记忆性和泛化性进行讨论的,模型能够从历史数据中学习到高频共现的特征组合的能力,称为是模型的Memorization。能够利用特征之间的传递性去探索历史数据中从未出现过的特征组合,称为是模型的Generalization。Wide&Deep兼顾Memorization与Generalization并在Google Play store的场景中成功落地。
模型结构及原理
重点和难点在于:根据自己的场景去选择那些特征放在Wide部分,哪些特征放在Deep部分。
Wide部分
wide部分是一个广义的线性模型,输入的特征主要有两部分组成,一部分是原始的部分特征,另一部分是原始特征的交叉特征(cross-product transformation)。
交互特征
ϕ
k
(
x
)
=
∏
i
=
1
d
x
i
c
k
i
,
c
k
i
∈
{
0
,
1
}
\phi_{k}(x)=\prod_{i=1}^d x_i^{c_{ki}}, c_{ki}\in \{0,1\}
ϕk(x)=∏i=1dxicki,cki∈{0,1}
c
k
i
c_{ki}
cki是一个布尔变量,当第i个特征属于第k个特征组合时,
c
k
i
c_{ki}
cki的值为1,否则为0,
x
i
x_i
xi是第i个特征的值,大体意思就是两个特征都同时为1这个新的特征才能为1,否则就是0,说白了就是一个特征组合。
优化器:带 L 1 L_1 L1正则的FTRL算法
对于wide部分训练时候使用的优化器是带 L 1 L_1 L1正则的FTRL算法(Follow-the-regularized-leader),而L1 FTLR是非常注重模型稀疏性质的(这也是L1正则化的特征),也就是说采用L1 FTRL是想让Wide部分变得更加的稀疏,即Wide部分的大部分参数都为0,这就大大压缩了模型权重及特征向量的维度。**Wide部分模型训练完之后留下来的特征都是非常重要的,那么模型的“记忆能力”就可以理解为发现"直接的",“暴力的”,“显然的”关联规则的能力。**例如Google W&D期望wide部分发现这样的规则:用户安装了应用A,此时曝光应用B,用户安装应用B的概率大。
关于模型的稀疏性:
稀疏性在机器学习中是很看重的事情,尤其我们做工程应用,稀疏的特征会大大减少predict时的内存和复杂度。下面给出常见的三种做稀疏解的途径:
1.L1范数能引入稀疏解。
因为是浮点运算,训练出的w向量也很难出现绝对的零。可以当计算出的w对应维度的值很小时,我们就强制置为零不就稀疏了么,后面的Truncated Gradient和FOBOS都是类似思想的应用。
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-ER5spMJ9-1616082086913)(media/16160771316467/262019559244301.jpg)]
2.在L1范数的基础上做截断。
最直观没技术含量的思路,那就设定一个阈值,做截断来保证稀疏,可以结合L1范数简单截断方法,每online训练K个数据截断一次,对OGD的迭代结果,每K步做一次截断置零。但是简单截断方法有问题:权重小,可能是确实是无用特征,还或者可能是该特征才刚被更新一次(例如训练刚开始的阶段、或者训练数据中包含该特征的样本数本来就很少),另外,简单rounding技术太aggressive了,可能会破坏在线训练算法的理论完备性。简单截断基础上,不太aggressive的Truncated gradient(09年的工作),其实后面的FOBOS也可以归为这一类。
3.Black-box wrapper approaches
* 黑盒的方法去除一些特征,然后重新训练的看被消去的特征是否有效。
* 需要在数据集上对算法跑多次,所以不太实用
FTRL可以看作RDA和FOBOS的混合,但在L1范数或者其他非光滑的正则项下,FTRL比前两者更加有效。
FTRL(Follow-the-regularized-Leader)算法是Google在先后三年时间(2010年-2013年)内完成从理论研究到实际工程化实现。在处理诸如逻辑回归之类的带非光滑正则化项(例如L1范数,做模型复杂度控制和稀疏化)的凸优化问题上性能非常出色。
Deep部分
Deep部分是一个DNN模型,输入的特征主要分为两大类,一类是数值特征(可直接输入DNN),一类是类别特征(需要经过Embedding之后才能输入到DNN中)。
**我们知道DNN模型随着层数的增加,中间的特征就越抽象,也就提高了模型的泛化能力。**对于Deep部分的DNN模型作者使用了深度学习常用的优化器AdaGrad,这也是为了使得模型可以得到更精确的解。
Wide 与 Deep 结合
将wide与deep两部分输出的结果结合起来联合训练,即在deep和wide部分的输出上使用一个逻辑回归模型做最终的预测,输出概率值。
注意:因为Wide侧的数据是高维稀疏的,所以作者使用了FTRL算法优化,而Deep侧使用的是 Adagrad。
P
(
Y
=
1
∣
x
)
=
δ
(
w
w
i
d
e
T
[
x
,
ϕ
(
x
)
]
+
w
d
e
e
p
T
a
(
l
f
)
+
b
)
P(Y=1|x)=\delta(w_{wide}^T[x,\phi(x)] + w_{deep}^T a^{(lf)} + b)
P(Y=1∣x)=δ(wwideT[x,ϕ(x)]+wdeepTa(lf)+b)
总体来看,Wide侧记住的是历史数据中那些常见、高频的模式,但没有发现新的模式,只是学习到这些模式之间的权重,做一些模式的筛选。我们需要根据人工经验、业务背景,将我们认为有价值的、显而易见的特征及特征组合,喂入Wide侧。Deep侧就是DNN,让DNN学习到这些特征之间的深层交叉,以增强扩展能力。
模型的实现与模型结构类似由deep和wide两部分组成。我们可以在wide部分加入了所有可能的一阶特征,包括数值特征和类别特征的onehot,也可以加入一些交叉特征。只要通过特征工程发现了能够发现高频、常见模式的特征,都可以放在wide侧,对于Deep部分,在本数据中放入了数值特征和类别特征的embedding特征,实际应用也需要根据需求进行选择。
思考题
见微知著,你真的搞懂Google的Wide&Deep模型了吗?
1.哪些特征适合放在Wide侧,哪些特征适合放在Deep侧,为什么呢?
wide:基于对业务的了解,或者通过特征工程发掘出的,已知的会对结果产生重要影响的特征或者交叉特征。稀疏特征。
deep:经过特征筛选出的“有用”特征,且不是特别稀疏的特征。
2.为什么Wide部分要用L1 FTRL训练?
因为L1 FTRL是一个结合了稀疏性和精度的随机梯度下降方法。又由于是随机梯度下降,当然可以做到来一个样本就训练一次,进而实现模型的在线更新。
W&D采用L1 FTRL是想让Wide部分变得更加稀疏。因为wide部分可能有很多的输入特征和交叉特征,甚至高阶级交叉特征。再白话一点就是,L1 FTRL会让Wide部分的大部分权重都为0,我们准备特征的时候就不用准备那么多0权重的特征了,这大大压缩了模型权重,也压缩了特征向量的维度。
补充:稀疏性不见得一直是一个好东西,它不管怎样都会让模型的精度有一定的损伤。肯定是特征向量维度过高导致“稀疏性”成为了关键的考量。实际应用中,两个id类特征向量进行组合,在维度爆炸的同时,会让原本已经非常稀疏的特征向量,变得更加稀疏。正因如此,wide部分的权重数量其实是海量的。为了不把数量如此之巨的权重都搬到线上进行model serving,采用FTRL过滤掉哪些稀疏特征无疑是非常好的工程经验。
3 为什么Deep部分不特别考虑稀疏性的问题?
大家注意观察可以发现Deep部分的输入,要么是Age,#App Installs这些数值类特征,要么是已经降维并稠密化的Embedding向量,工程师们不会也不敢把过度稀疏的特征向量直接输入到Deep网络中。所以Deep部分不存在严重的特征稀疏问题,自然可以使用精度更好,更适用于深度学习训练的AdaGrad去训练。