写在前面
在刚刚(2020-6-22)结束的号称万人参加的“腾讯广告算法大赛”中队伍“软件大道东”在激烈的比赛角逐中遗憾出局,未能进入复赛。对于第一次参加大型比赛的我,这个成绩已经突破自我了,在这里我非常感谢我的队友(郭嘉伟)在比赛中给予我的帮助,带领着我们一步一步的走到了最后。这次比赛对我的影响很大,同时也学到了很多东西,写这篇文章就是为了复习一下我们队伍的思路和方案。排名不高,大佬们多多指正。
代码开源见文末
※赛题介绍※
赛题描述
2020腾讯广告算法大赛的题目为:广告受众基础属性预估。
本届算法大赛的题目来源于一个重要且有趣的问题。众所周知,像用户年龄和性别这样的人口统计学特征是各类推荐系统的重要输入特征,其中自然也包括了广告平台。这背后的假设是,用户对广告的偏好会随着其年龄和性别的不同而有所区别。许多行业的实践者已经多次验证了这一假设。然而,大多数验证所采用的方式都是以人口统计学属性作为输入来产生推荐结果,然后离线或者在线地对比用与不用这些输入的情况下的推荐性能。本届大赛的题目尝试从另一个方向来验证这个假设,即以用户在广告系统中的交互行为作为输入来预测用户的人口统计学属性。(逆向思考)
赛题目标
我们将为参赛者提供一组用户在长度为91天(3 个月)的时间窗口内的广告点击历史记录作为训练数据集。每条记录中包含了日期(从1到91)、用户信息(年龄,性别),被点击的广告的信息(素材 id、广告 id、产品 id、产品类目 id、广告主id、广告主行业id等),以及该用户当天点击该广告的次数。测试数据集将会是另一组用户的广告点击历史记录。(年龄10个类别,性别2个类别,这里可以把题目理解为一个分类问题,可以一起预测也可以分开预测)。
提交方式
参赛者提交的结果为一个带标题行的 submission.csv 文件,编码采用无 BOM 的 UTF-8,具体格式如下(字段顺序以下面的描述为准,各字段用逗号分隔,中间无空格):
⚫ user_id
⚫ predicted_age: 预测的用户年龄分段,取值范围[1,10]。
⚫ predicted_gender: 预测的用户性别,取值范围[1,2]。
测试数据集中每个用户均应在submission.csv文件中对应有且仅有一行预测结果。各用户
的预测结果在该文件中的出现顺序与评估结果无关。
评估方式
参赛者提交的结果计算预测的准确率(accuracy)。年龄预测和性别预测将分别评估准确率,两者之和将被用作参赛者的打分。(性别和年龄的acc相加)
※赛提数据※
初赛数据
● 用户行为数据
click_log.csv:
time: 天粒度的时间,整数值,取值范围[1, 91]。
user_id: 从1到N随机编号生成的不重复的加密的用户id,其中N为用户总数目(训
练集和测试集)。
creative_id: 用户点击的广告素材的id,采用类似于user_id的方式生成。
click_times: 当天该用户点击该广告素材的次数。
● 用户属性
user_id
age: 分段表示的用户年龄,取值范围[1-10]。
gender:用户性别,取值范围[1,2]。
● 广告属性表
ad.csv:
creative_id
ad_id: 该素材所归属的广告的 id,采用类似于 user_id 的方式生成。每个广告可能包
含多个可展示的素材。
product_id: 该广告中所宣传的产品的id,采用类似于user_id的方式生成。
product_category: 该广告中所宣传的产品的类别 id,采用类似于 user_id 的方式生
成。
advertiser_id: 广告主的id,采用类似于user_id的方式生成。
industry: 广告主所属行业的id,采用类似于user_id的方式生成。
※我们团队的方案※
一、.lightGBM+传统的统计特征+w2v (TFIDF,count2vec)。这部分的方案大家应该都试过(这部分可以参考鱼佬的高分进阶分享)具体的就不展开细说。(这一部分是没有组队时自己的方案,由于没有使用过nn,所有这一部分就没有用。)
1.先统计基础特征,提供的8个维度的 nunique,比如点击的不同的广告id数等,还有点击广告次数的最大最小值均值方差等等。
2.之后就是利用nlp的方法,比如:单独对8个维度,creative_id 编码。可以想到的类似使用NLP的特征提取,把一个人点击的所有 creative_id 看作句子,所有人点击的 creativeid 看做文档,使用 tfidf 编码,或者使用count2vec。对于tfidf的维度灾难问题,可以对参数进行调整eg:min_df。
3.w2v的话,它可以把高维稀疏向量变成稠密的向量,构造句子的方法和上面2的相同。(前面一直使用的是腾讯提供的云服务平台,这部分的训练总是会内存爆了,心态就有点炸了,最后就用了64维的训练,ps:有的大佬说:代码整理的好的话可以训练128维的,我…。)
感觉这部分很玄学,大家都是那样做的,分数就在1.31-1.32左右,而最好的有1.38+。应该是有些细节的地方没有大佬们做的好。等比赛结束了可以学习一下大佬开源的代码。
二、LSTM+pool+attention (rnn)+LSTM_GatedCNN 这部分是组队以后和队友写的nn方案,由于之前没有用过nn,所有这部分的对于我来说还是挺吃力的,那段时间就采用了速成的方式,直接在github上找简单地代码看,怎么实现的,怎么搭建网络。慢慢的也会了一些(下面写的不对的地方希望大佬们指正哈)
1.我们最开始采用的是1输入(creativeid),利用fasttext来训练词向量word_embedding来作为预训练模型,维度是128.(大部分人使用的是w2v来训练,具体效果哪个好,我们没有试过,试过的大佬们可以告知一下哈),这部分放到模型里面跑(没有atte+pool)分数在1.39+。
图中为4输入
2.期间我们对一输入进行调参,效果的提升没有那么显著。最后选择了最后的一对参数进行3输入的训练。3输入选择creativeid.ad_id,advertider_id。分数在1.41+。
3.3输入时在了attention,还做了训练集的数据增强。试了reverse,random delete,random swap,random synonym replace。效果确实提升了,最后选择了reverse和random swap。这时的分数在1.42+了。
4.后面我们还尝试做了cnn的模型,分数也是在1.42左右。期间尝试了很多不同的atte,self-atte。效果都不怎么好,提升的很小。(可以作为最后融合的模型)
5.这时我们已经掉了好几十名了。大佬们的上分速度属实惊人。迫于无奈,我们增加了一个输入:product_id,很遗憾没有多大的提升。(也可以作为最后融合的模型,可以这个模型跑了很久很久一个epoch跑了6个小时,我哭了。所以用的没有跑完的最好的epoch进行融合,融合的效果提升甚小),
6.最后的融合我们尝试了两种方式:1.加权平均,(两个47.6的模型融合到了48.4)2.用nn来训练权重,(把验证集又分了训练集和验证集,age训练集最好48.5,验证集是48.3,几乎没什么提升)。由于时间的原因我们没有尝试stacking。
※比赛总结※
这次比赛让给我学到了很多东西,从一个对nn无从下手的人到了慢慢能自己搭建网络。在这里我还是非常感谢我的队友。路漫漫其修远兮。在今年的这次疫情在家期间,我参加了两个比赛,一个是天池的智慧海洋建设,一个是腾讯广告算法,虽然成绩都不怎么好,但是这两次比赛也见证了我的成长,从一个什么都不会的小白,慢慢的一点点成长起来。接下来的时间就是准备秋招了。有一起准备的可以加个wx。本人在上海,如果可以的话可以面基,哈哈。
以上如有不对的地方,望大佬指正,谢谢。(第一次写文章排版不好,见谅)
代码正在整理中,如需要可以提供github链接。
我的知乎专栏,觉得不错的话可以点个赞,谢谢啦https://www.zhihu.com/people/1350221066/posts