本文主要内容如下:
-
DeepFM 模型介绍
-
DeepFM 在贝壳房源详情页推荐展位的实践应用
DeepFM 模型介绍
Wide & Deep 是一个 Wide 侧使用 LR,Deep 侧使用 DNN 的联合学习模型(详情见《wide&deep 在贝壳推荐场景的实践》)。但在 Wide 侧 LR 一般需要大量的特征工程工作。华为的诺亚方舟实验室提出的 DeepFM 则使用 FM[3] 替换 Wide & Deep 模型中 Wide 部分的 LR,以实现 Wide 的自动特征交叉,降低人工特征工程的工作。DeepFM 结构如图-1:
左侧是一个 FM 结构,右侧是一个 DNN 结构。DeepFM 的预测公式因此为:
要了解 DeepFM 模型,先要了解 FM 模型。
FM 模型
FM 原理介绍
FM 全称 Factorization Machines(因子分解机),是 2011 年在文献[3]中提出的一种具备特征自动交叉能力的模型。
LR(Logistic Regression,逻辑回归模型) 因其模型简单、可解释性强等优点被广泛应用,但其缺点也十分显著:模型简单,无法学习原生特征与最终目标间的非线性关系,需要人工设计高阶特征,对特征工程极其依赖。
为了解决这一缺点,让 LR 能够学习到原生特征同最终目标间的非线性关系,一个直观的方法就是就是引入原生特征间的自动交叉,比如两个原生特征间的交叉项——二阶交叉项:
特征经过离散化和 OneHot 编码后,特征数量会十分巨大, 几万至几百万不等(依赖使用到的 ID 类特征数量),二阶交叉项的参数数量能够达到几亿至几千亿。巨大的参数数量,使得模型的 VC 维大,复杂度高,要充分训练如此复杂的模型,需要庞大的样本数量。一般我们认为,样本数量需要至少是参数数量的 10 倍,模型才不容易过拟合,才能学习到真正的知识。
由于交叉特征数量巨大,而样本数量有限,模型很难得到充分训练,必须对二阶交叉项进行参数精简。
DeepFM 中的 FM 结构
在 DeepFM 中,FM 的结构见图-2:
从下往上看:
DNN
DNN 结构这里就不多介绍了,只是简单介绍 DeepFM 中使用的 DNN 结构:
从下往上看:
第一层 Sparse Features 与 FM 同。
DeepFM 在贝壳房源详情页推荐展位的实践应用
背景介绍
我们将 DeepFM 应用在了贝壳找房 APP 中房源详情介绍页的推荐展位上,见图-4(a):
图-4 详情页推荐位介绍
这个推荐场景最显著的特点是有很强的上下文约束。很长一段时间, 这个场景一直使用 LR 模型作为一个 benchmark 的排序模型,2019 年我们开始精准优化这个核心场景的推荐效果。
在前一篇文章中我们提到,首页推荐场景采用了 Wide & Deep,这是因为首页推荐场景积累了很长时间的人工特征,且没有上下文约束,采用 Wide & Deep 可以很好的继承原有的人工特征,实现无缝迁移。但在详情页推荐场景下,上下文约束很强,需要大量上下文交叉特征,因此,我们采用了 DeepFM,借助 FM 的上下文特征自动交叉减轻我们在特征工程方面的工作。
样本构建
一开始,我们使用的正负样本构建方式:将一次推荐列表中点击的房源(左边列表红框)作为正样本,最后一个点击位之前的曝光未点击的房源作为负样本。如图-5 所示(左边表示有点击行为的推荐列表,右边表示无点击行为的推荐列表)
图-5 样本构建1
且对矛盾样本去重——如果同一个用户在同一个上下文下对同一个推荐房源既有点击行为也有未点击的行为会合并成一条正样本。
但是这种方式构建的训练样本实际效果并不好,我们通过这种方式构建的样本训练的模型在训练集上的 AUC 都只有 0.566 左右,且伴随有过拟合的迹象。
随后我们猜测是因为样本的问题:
-
样本量不够。由于房产领域用户是低频行为,因此我们只有百万级别的训练数据(与 Paper 中动辄上亿的训练数据有很大差距),每个用户的行为数据也比较少;
-
样本存在偏差。我们只是将有点击行为的列表的曝光无点击数据作为负样本,对于那些只有曝光无点击的列表则直接抛弃了,使得模型学习不到这部分负样本的信息。
基于上述两个考虑,我们重新进行样本构造:
第一,我们将有点击(左边列表红框)的列表中点击之后的曝光未点击样本也采集作为负样本;
第二,我们将无点击的曝光列表(右边)中的第一个曝光未点击的样本也采集作为负样本。
这里有两个小细节需要注意:
-
为什么都没有加入最后一个曝光的数据?
这个主要是出于具体的产品情况的考虑,我们详情页中只要房源曝光了一点就算曝光,也就是说用户可能并没有看到这个房源,但是系统也算曝光了,因此我们将最后一个曝光的数据直接去掉了。 -
为什么无点击的曝光列表中只采用第一个曝光的样本?
主要是为了保证正负样本相对平衡,避免变成一个样本不平衡学习。我们当前的样本构建方式正负样本比约为 1: 5。如果将无点击的曝光列表的所有数据都作为负样本,则正负样本比为约为 1 : 18,正负样本严重失衡。
特征工程
特征选择
我们分析了我们的场景,详情页推荐的一个基本假设是:用户对详情页的房源感兴趣,推荐相似的房源用户也感兴趣。但是如果只关注上下文房源的特征容易造成推荐的房源都是极度相似的房源,不具备差异性,给用户造成视觉上的疲劳。但如果推荐的房源和上下文的房源差别较大,那么很容易让用户产生不信任。为了平衡这两者,我们决定引入用户画像特征,让模型自己学习个性化和上下文相似的平衡关系。
因此,我们总共选择了如下 6 大类特征:
-
上下文房源特征
-
推荐房源特征
-
用户特征
-
上下文房源与推荐房源匹配特征
-
上下文房源与用户画像匹配特征
-
推荐房源与用户画像匹配特征
每类的具体特征如图-7:
在特征变换中:
-
离散特征
-
Embedding,离散特征都进行 Embedding 编码。
-
-
连续特征
-
异常值填充。对于偏好类的特征我们采用 0 填充,对于房源属性特征(如价格,面积等)则使用均值填充;
-
去极端值,为了避免极端值或异常点对最后归一化造成影响(比如存在一个超大的异常点,最后做 MinMax 归一化则会造成这一维的值都会偏小甚至趋向于 0)。因此我们使用分位点的方式将大于 95% 分位点的值替换成 95% 分位点;
-
归一化,归一化我们使用了 MinMax 归一化方式。
-
此外,还对部分连续特征做了离散化,最终得到了 324 维特征,其中连续特征 143 维,离散特征 181 维。
模型构建
具体的 DeepFM 模型网上有很多优秀的开源项目,这里就不具体介绍。这里主要介绍实施过程中的一些细节。
离线评估
我们将数据划分为训练集、验证集和测试集三部分,其中前 N 天作为训练集、1 天作为验证集,1 天作为测试集。
训练集和验证集中的样本采用前面提到的样本构建方式进行构建。
测试集样本则使用点击为正样本,曝光未点击为负样本。这么构建的原因在于:
-
测试集的正负样本比例要同实际线上样本分布保持一致。原本离线评估使用的 AUC 指标与线上 AB 使用的 CTR 之间就存在 Bias,如果测试集还对测试样本进行选择会增加离线评估的 Bias;
-
而训练集为了解决数据不平衡,样本同实际分布不一致;
-
统一测试集。后续模型迭代都使用统一的测试集,保证模型之间的可比性。
参数调优
-
batch_size
batch_size | AUC |
---|---|
64 | -5.8% |
512 | +0.0% |
2048 | +0.6% |
-
网络结构
我们使用了 2 层的全连接层。
神经元数 | AUC |
---|---|
256, 128 | +0% |
128, 64 | +0.17% |
-
BN 层
加入 BN 层,AUC 相对提升 0.68%。
-
Embedding Size
Embedding Size 从 32 到 64 没有带来明显的效果提升,因此最终使用 32 维。
在线评估
通过线上 AB 实验,CTR 相对提升 12.65%。
参考资料
[1]wide & deep[1]
[2]deepfm[2]
[3]fm[3]
[4]深度学习在美团搜索广告排序的应用实践[4]
[5]from ranknet to lambdarank to lambdamart: an overview[5]