原始数据集共包含3个,实验时存放在目录rank/examples/dataset/raw_data/
下。
-
user_info_5w.csv
- 该文件共包含了5万条用户的个人数据;
- 特征分别包括了:['user_id', 'device', 'os', 'province', 'city', 'age', 'gender'];
- 各特征的含义为:['用户id', '设备名称', '操作系统', '所在省', '所在市', '年龄', '性别'];
-
doc_info.txt
- 该文件包含了所有新闻的特征数据;
- 各特征的含义为:['文档id', '标题', '发文时间', '图片数量', '一级分类', '二级分类', '关键词'];
-
train_data_5w.csv
- 该文件为用户点击数据,包含了5万个用户在过去13天的点击数据;
- 各特征的含义为:['用户id', '文档id', '展现时间', '网路环境', '刷新次数', '展现位置', '是否点击', '消费时长(秒)'];
数据处理的文件存放在rank/examples/dataset/data_process/
下。
训练集和测试集的划分程序为:train&test_data_split.py
-
训练集:将所有用户在前12天的点击行为划为训练集;
-
测试集:
- 将所有用户在第13天的点击行为化为测试集;
- 测试集丢弃特征:消费时长(秒),展现位置,是否点击;
-
测试标签:
- 将测试集的真实标签单独进行存储;
其他特征处理:
- 选中消费时长小于0的样本,并将其消费时长设置为0;
- 对所有样本的展现时间进行了格式处理,并新增了特征展现日期;
- 新增特征index,目的是为了后续对测试集进行评估;
用户数据和文档数据的处理程序为:user&doc_data_process.py
用户数据处理
-
性别特征:原始的用户性别数据为用户对应不同性别的概率,这里直接将概率最高的性别作为用户的实际性别;
-
年龄数据:原始的用户年龄数据为用户对应不同年龄段的概率,这里将概率最高的年龄段作为用户所处的年龄段;
文档数据处理
- 发文时间:对于部分发文时间异常或者为空的数据,使用已有文档中最早的发文时间进行填充;
- 发文日期:将文档的发文时间,提取出对应的发文日期(年-月-日);
- 图片数量:对部分异常的脏数据,使用
$0$ 进行填充处理; - 二级分类:对于存在多个二级分类的文档,从其选取一个作为其二级分类。优先选择不等于一级分类的二级分类,对于二级分类为空的文档使用一级分类进行填充;
- 关键词:
- 每篇文档均存在多个关键词,每个关键词也会对应一个权重,这里选取权重最高的关键词作为文章的唯一关键词;
- 文档中不同的关键词及权重是采用逗号进行隔开的,但部分关键词本来就包含逗号(如==你好,李焕英==),故相关函数还对此进行了特殊处理;
统计特征的生成的程序为:news_data_process.py
-
从文档发文到展示的时间差:对于每一个样本,统计对应文档从发文到展示的日期差;
-
用户特征统计:
- 统计每个用户过去几天,所展现的文档总数;
- 统计每个用户过去几天,在不同类别文档(一级分类)上的展现总数;
- 统计每个用户过去几天,在不同类别文档(二级分类)上的展现总数;
- 统计每个用户过去几天,整体的点击率;
- 统计每个用户过去几天,对不同类别文档(一级分类)上的点击率;
- 统计每个用户过去几天,对不同类别文档(二级分类)上的点击率;
- 统计每个用户过去几天,消费时长的总和;
- 统计每个用户过去几天,在不同类别文档(一级分类)上的总消费时长;
- 统计每个用户过去几天,在不同类别文档(二级分类)上的总消费时长;
- 统计每个用户过去几天,在不同类别文档(一级分类)上的平均消费时长;
- 统计每个用户过去几天,在不同类别文档(二级分类)上的平均消费时长;
- 统计每个用户过去几天,在不同类别文档(一级分类)上的消费时长的方差;
- 统计每个用户过去几天,在不同类别文档(二级分类)上的消费时长的方差;
-
文档特征统计:
- 统计每篇文档在过去几天,被展示的总次数;
- 统计各类别(一级分类)文档在过去几天,被展示的总次数;
- 统计各类别(二级分类)文档在过去几天,被展示的总次数;
- 统计每篇文档在过去几天,平均的被点击率;
- 统计各类别(一级分类)文档在过去几天,平均被点击率;
- 统计各类别(二级分类)文档在过去几天,平均被点击率;
- 统计每篇文档在过去几天,总的被消费时长;
- 统计每篇文档在过去几天,平均的被消费时长;
- 统计每篇文档在过去几天,被消费时长的方差;
- 统计各类别(一级分类)文档在过去几天,总的被消费时长;
- 统计各类别(一级分类)文档在过去几天,平均的被消费时长;
- 统计各类别(一级分类)文档在过去几天,被消费时长的方差;
- 统计各类别(二级分类)文档在过去几天,总的被消费时长;
- 统计各类别(二级分类)文档在过去几天,平均的被消费时长;
- 统计各类别(二级分类)文档在过去几天,被消费时长的方差;
-
连续型特征:
- 连续型特征包含的主要是统计特征,这里对于空值统一使用
$0$ 进行填充; - 之后,对所有的连续型特征进行对数归一化, 即取
$log$ 对数;
- 连续型特征包含的主要是统计特征,这里对于空值统一使用
-
类别型特征:
- 类别型特征这里主要是通过
$LabelEncoder$ 的方式进行编码,以便后续模型处理为相应的$Embedding$ ;
- 类别型特征这里主要是通过
排序模型的执行程序存放在rank/examples/
下,分别为deepfm_news.py
和deepfm_ppnet_news.py
。
DeepFM是2017年由华为与哈工大提出的排序模型,,模型主要包含两部分:FM部分+Deep部分。
- FM部分:对不同特征域的Embedding进行两两交叉,以加强模型在浅层网络中的特征组合能力。
- Deep部分:多层感知机网络模型。通过对特征各个维度进行充分的特征交叉组合,来学习到更多非线性以及组合特征的信息。
论文链接:[DeepFM: A Factorization-Machine based Neural Network for CTR Prediction (arxiv.org)
实验结果
- 参数设置
# data para
seed: 48
# model para
embed_dim: 32
drop_rate: 0.5
use_bn: Ture
hidden_units: [64, 128, 64]
# compile para
learning_rate: 0.001
epochs: 20
batch_size: 2048
val_splite: 0.1
patience: 5
restore_best_weights: True
- 运行结果
Epoch 1/20
2653/2653 [==============================] - 47s 17ms/step - loss: 0.3921 - auc: 0.7287 - val_loss: 0.3628 - val_auc: 0.7588
Epoch 2/20
2653/2653 [==============================] - 44s 17ms/step - loss: 0.3619 - auc: 0.7616 - val_loss: 0.3581 - val_auc: 0.7647
Epoch 3/20
2653/2653 [==============================] - 44s 17ms/step - loss: 0.3569 - auc: 0.7705 - val_loss: 0.3561 - val_auc: 0.7682
Epoch 4/20
2653/2653 [==============================] - 47s 18ms/step - loss: 0.3548 - auc: 0.7754 - val_loss: 0.3557 - val_auc: 0.7699
Epoch 5/20
2653/2653 [==============================] - 47s 18ms/step - loss: 0.3540 - auc: 0.7777 - val_loss: 0.3560 - val_auc: 0.7702
Epoch 6/20
2653/2653 [==============================] - 46s 18ms/step - loss: 0.3536 - auc: 0.7788 - val_loss: 0.3557 - val_auc: 0.7708
Epoch 7/20
2653/2653 [==============================] - 45s 17ms/step - loss: 0.3533 - auc: 0.7797 - val_loss: 0.3556 - val_auc: 0.7714
Epoch 8/20
2653/2653 [==============================] - 45s 17ms/step - loss: 0.3532 - auc: 0.7802 - val_loss: 0.3558 - val_auc: 0.7712
Epoch 9/20
2653/2653 [==============================] - 46s 17ms/step - loss: 0.3530 - auc: 0.7806 - val_loss: 0.3560 - val_auc: 0.7713
Epoch 10/20
2653/2653 [==============================] - 46s 17ms/step - loss: 0.3530 - auc: 0.7808 - val_loss: 0.3560 - val_auc: 0.7711
Epoch 11/20
2653/2653 [==============================] - 45s 17ms/step - loss: 0.3529 - auc: 0.7811 - val_loss: 0.3560 - val_auc: 0.7715
Epoch 12/20
2653/2653 [==============================] - 46s 17ms/step - loss: 0.3528 - auc: 0.7813 - val_loss: 0.3557 - val_auc: 0.7718
251/251 [==============================] - 3s 11ms/step - loss: 0.3719 - auc: 0.7508
test AUC: 0.750784
将DeepFM模型中,DNN 模块替换为PPNet模型:
- 在语音识别领域中,2014 年和 2016 年提出的 LHUC 算法(learning hidden unit contributions)核心思想是做说话人自适应(speaker adaptation),其中一个关键突破是在 DNN 网络中,为每个说话人学习一个特定的隐式单位贡献(hidden unit contributions),来提升不同说话人的语音识别效果。
- 借鉴 LHUC 的思想,快手推荐团队在精排模型上展开了尝试。经过多次迭代优化,推荐团队设计出一种 gating 机制,可以增加 DNN 网络参数个性化并能够让模型快速收敛。快手把这种模型叫做 PPNet(Parameter Personalized Net)。
参考链接:1.9万亿参数量,快手落地业界首个万亿参数推荐精排模型
实验结果:
- 参数设置
# data para
seed: 48
# model para
embed_dim: 32
drop_rate: 0.5
ppnet_size: 256
ppnet_features: ['user_id', '一级分类', '年龄']
use_bn: Ture
hidden_units: [64, 128, 64]
# compile para
learning_rate: 0.001
epochs: 20
batch_size: 2048
val_splite: 0.1
patience: 5
restore_best_weights: True
- 运行结果
Epoch 1/20
2653/2653 [==============================] - 56s 20ms/step - loss: 0.3929 - auc: 0.7303 - val_loss: 0.3648 - val_auc: 0.7568
Epoch 2/20
2653/2653 [==============================] - 53s 20ms/step - loss: 0.3620 - auc: 0.7622 - val_loss: 0.3591 - val_auc: 0.7651
Epoch 3/20
2653/2653 [==============================] - 55s 21ms/step - loss: 0.3578 - auc: 0.7706 - val_loss: 0.3580 - val_auc: 0.7690
Epoch 4/20
2653/2653 [==============================] - 53s 20ms/step - loss: 0.3560 - auc: 0.7755 - val_loss: 0.3587 - val_auc: 0.7701
Epoch 5/20
2653/2653 [==============================] - 54s 20ms/step - loss: 0.3551 - auc: 0.7787 - val_loss: 0.3580 - val_auc: 0.7706
Epoch 6/20
2653/2653 [==============================] - 55s 21ms/step - loss: 0.3545 - auc: 0.7809 - val_loss: 0.3587 - val_auc: 0.7718
Epoch 7/20
2653/2653 [==============================] - 54s 20ms/step - loss: 0.3541 - auc: 0.7829 - val_loss: 0.3586 - val_auc: 0.7720
Epoch 8/20
2653/2653 [==============================] - 53s 20ms/step - loss: 0.3538 - auc: 0.7842 - val_loss: 0.3587 - val_auc: 0.7721
251/251 [==============================] - 4s 13ms/step - loss: 0.3686 - auc: 0.7543
test AUC: 0.754304
# 数据预处理
1. user&doc_data_process.py
2. train&test_data_split.py
3. news_data_process.py
# 排序模型
4. deepfm_news.py 或 deepfm_ppnet_news.py
- Tensorflow2.5 (GPU)
- Numpy
- Pandas
- Swifter
- Sklearn