先贴重要的链接
DeepFM的论文参考 https://arxiv.org/pdf/1703.04247.pdf
代码仓: https://github.com/PaddlePaddle/models/tree/develop/PaddleRec/ctr/deepfm
为什么用paddle做ctr预估
因为之前待过广告公司,所以对ctr这块一直有关注。CTR简介请参考我的另一篇文章https://blog.csdn.net/oqqYuan1234567890/article/details/105460846
paddle团队维护的models库中,有一个deepfm的例子,去年10月参加百度举办的AI快车道培训,还没有放出这个模型。到了年底看的时候已经有了。
其实tf社区也有deepFM的实现,但有两个因素是paddle的优势
- 百亿稀疏特征的embedding
- 分布式异步训练也能保证足够好的收敛效果(根据当时主讲的工程师说,异步训练的理论支撑不是很完备,但是百度的实践经验中,paddle的收敛效果是可以保证的)
所以paddle还是挺不错的,tf一直缺少稀疏特征的参数服务器,既然paddle有提供,那是很不错的,所以一直都有关注。
github上也有tf实现的例子,但是用的数据集都比较小。paddle的deepfm用的数据规模还行,最近把完整的数据跑一下。
熟悉数据
这个模型用的数据,是kaggle一个点击率比赛的数据集,具体的链接在: https://www.kaggle.com/c/criteo-display-ad-challenge/data
代码仓中,数据下载的代码在
data/download_preprocess.py
里面主要下载两份数据,一份数据是特征字典,可能是模型作者担心复现代码的开发者机器内存不够,就预处理了一份,这份数据用的是百度对象存储的服务,比较快。
主要数据的地址:https://s3-eu-west-1.amazonaws.com/kaggle-display-advertising-challenge-dataset/dac.tar.gz
由于这份criteo的ctr数据是托管在amason s3服务的,国内下特别慢,建议找个windows的机器开迅雷下,在linux用uget工具开多线程都特别慢。
解压dac.tar.gz数据,可以看一下实际的数据量
$ cat train.txt|wc -l
45840617
$ cat test.txt|wc -l
6042135
训练数据大约4500万行,规模还是可以的。
数据格式说明
- Label - Target variable that indicates if an ad was clicked (1) or not (0).
- I1-I13 - A total of 13 columns of integer features (mostly count features).
- C1-C26 - A total of 26 columns of categorical features. The values of these features have been hashed onto 32 bits for anonymization purposes.
- 一共39个特征维度,1086460个特征数量。
评价指标AUC
AUC是从混淆矩阵里面演变出来的,参考 https://blog.csdn.net/u012735708/article/details/82877501
paddle里面,有一个auc layer用于auc计算,api说明位于https://www.paddlepaddle.org.cn/documentation/docs/zh/api_cn/layers_cn/auc_cn.html
import paddle.fluid as fluid
import numpy as np
data = fluid.layers.data(name="input", shape=[-1, 100], dtype="float32")
label = fluid.layers.data(name="label", shape=[1], dtype="int")
fc_out = fluid.layers.fc(input=data, size=1)
predict = fluid.layers.softmax(input=fc_out)
result=fluid.layers.auc(input=predict, label=label)
place = fluid.CPUPlace()
exe = fluid.Executor(place)
exe.run(fluid.default_startup_program())
x = np.random.rand(3,100).astype("float32")
y = np.array([1,0,1])
output= exe.run(feed={"input": x,"label": y},
fetch_list=[result[0]])
print(output)
组网
模型
y hat主要由fm部分与dnn部分相加,DNN负责特征交叉,不用做太多的特征工程。
fm部分
FM部分比较简单,按特征做embedding,然后做内积
dnn部分
DNN部分特征做emvedding,然后经过一个MLP网络
目标函数
采用 log loss 函数
N为样本数量,
p
i
p_i
pi 为预测输入实例
x
i
x_i
xi 属于类别 1 的概率
训练
训练环境
GTX 1070TI 8G
batch_size: 100, 一个epoch约耗时40分钟
batch_size: 400, 一个epoch约耗时10分钟,
我跑了8个epoch,验证集的AUC在0.79左右
根据Readme的介绍,22epoch的AUC大约是0.8046
由于自带的代码中没有实现checkpoint 恢复参数的功能