腾讯2017社交广告比赛(广告转化率预测)总结与分享--by Coda_Allegro

2017腾讯广告比赛结束也有一段时间了,决赛得了23名,无比残念(前20名有奖)

一直没时间总结一下比赛的得失。乘着懒癌没到晚期,赶紧写了。


顺带一提。我把代码开源到了github上:https://github.com/BladeCoda/Tencent2017_Final_Coda_Allegro

顺便求一波github的星星。(可耻)

---------------------------------------------

1.问题&思路分析

腾讯本次竞赛的题目为移动App广告转化率预估(pCVR,Predicted Conversion Rate)。以移动App广告为研究对象,预测App广告点击后被激活的概率:pCVR=P(conversion=1 | Ad,User,Context),即给定广告、用户和上下文情况下广告被点击后发生激活的概率。

题目链接在这里:http://algo.tpai.qq.com/home/information/index.html

那么从本质上看,这就是一个二分类问题(你的点击有没有转化,即true/false)。只不过由于转化这件事情几率实在是太过于低,比赛要求你给出的是转化的概率,但这其实很好办,很多的分类器在最后预测数据类别时其实就是用概率最大进行选择的。典型的代表就是各种神经网络分类器,最后总是会接个Softmax的全连接层,通过输出层概率取最大来进行预测。

那么简而言之,这就是个非常传统的机器学习任务了。我们可以把这个任务切割成如下的子任务

1.提取数据特征

2.选取合适的模型,训练模型

3.调参与特征筛选

4.融合

--------------------------

2.特征提取

其实打了这个比赛后,很多人都会有这么个感受。这其实就是半个特征选择大赛嘛。大佬挖掘出强特,trick。之后就可以吊打后面那些死肛统计特征什么的玩家了。。当然,你会机器学习就应该知道一点,对于分类器而言,数据记录其实就是一个特征的集合,机器学习学习的就是特征的分布。如何用一个好的方法把原始数据表达成一组有代表意义的特征向量,这便是特征提取的任务,也是这个比赛占了大部分内容的地方。要做到这点你就必须:

1.充分理解业务

2.开脑洞 -_-!!!!

这个我使用的特征其实非常少,由于我是用一台笔记本肛完整个比赛了。决赛数据量又爆炸。我只提取了50多维特征。大致为一以下几个种类。

I.基础特征:顾名思义,就是基础给你的那个属性,比如广告位ID,用户ID,用户性别,年龄之类的。这些属性其实一定程度上就能够指导转化率的预测了(即让分类器学习这些属性对于是否转化的分布)。当然,这种特征练出来的只不过是baseline级别的玩意。初赛提交占板凳用的。

II.用户的统计特征:这是重中之重,转化与否都是看用户的意愿的,而提取用户相关的特征自然是非常重要的。这里我给出我提取的一些有效的特征:

1.基本统计:类似于用户的安装数量,点击数量。用户安装同类别APP的数量等等。

2.时序统计:用户点击广告之前的一些行为都这次点击是否转化是具有很强的指导意义的。统计点击时间(clicktime)之前的一些特征能够很好的提高预测效果。例如统计clicktime之前的用户点击量,app安装数量之类的种种。

III.trick:喜闻乐见的环节,由于网速之类的问题,用户可能在很短的时间类不断的点击一个同一个广告,利用这里连续的记录是很有效的。具体使用方法举个例子,对短时间类重复的点击记录编号(1,2,3....),记录当前点击与前一次点击,后一次点击的时间差,亦或者同统段时间内用户的点击量(如1分钟内)。

*这儿必须要提一点,那就是数据泄露问题,简而言之,就是你用了未来的数据预测当前的转化率,或者直接用了和label相关性很强的特征来训练模型。后者危险性极大,直接造成线下结果超神,线上GG.很好理解,你等于用了答案在做题目-_-||||。但是前者就有意思了,理论上,实际业务你是无法提取这种特征的,但是,这是比赛,你懂得。用户是否重复点击,与后一条记录的时间差,这都是未卜先知的操作,而且这些泄露特征也是有风险的。具体自行操作感受。

IV.平滑后的转化率:你可能会想:我要预测转化率,那我用以前的转化率当特征不就OK了,你对了。但是,不全对。举个例子,统计同一广告位APP的历史转化率。由于广告位上线有前后,上线慢的统计不充分,最后特征基本就没用了。用户历史转化率就更危险了。大多数用户只点击过APP一次,历史转化率就是100%,你拿这个训练其实就是用了label来训练模型(就是前面我说的数据泄露的后者)。那种肿么办?

用先验知识来给转化率设置一个初值啊。

初值咋来?这个就涉及贝叶斯平滑啦。这个讲起来可以直接再开一个博客了。给大家一点资料:http://blog.csdn.net/mytestmy/article/details/19088519

总结一下,就是

假设一,所有的广告有一个自身的转化率,这些转化率服从一个Beta分布。
假设二,对于某一广告,给定转化次数时和它自身的转化率,它的点击次数服从一个伯努利分布

然后用梯度下降来学习这个分布。

-----------------------------

3.训练集构造&分类器选择

有了特征,然后就是分类器的选取和训练数据集的构造问题了。决赛数据大概有10G左右,小破本根本就玩不了。

数据是按时间划分的(17-30天为训练集,31天为预测集)。我们其实只需要选取28,29就足够了。为何不选30,是因为30天数据统计有误差(官方说法,为了题目更真实)但是我用了第30天的数据并且得到了提高。第30天其实是非常重要的一天,因为广告具有很强的实效性,第30天是和第31天隔得最近的。它最能捕获31天的趋势,尽管不精确,但是30天究竟能不能用这和你的特征有关。我个人测试的结果(不保证正确):如果大量使用统计特征,请不要用第30天来训练

线下测试cross validation就够了,但是有人会转牛角尖,用cv,会造成使用未来的数据预测以前的数据啊。对此我想说--你trick都用了,还怕这个?。这还是和特征有关,至少我和一些同学用CV能保证大体线上线下同步。当然,你也可以用27,28,来训练,29来验证。这个保险,初赛我用了这个,但是决赛数据太大,我没用测试。

然后就是分类器了。这个又很多选择,例如LR,RF,XGBOOST,LightGBM等等,由于不可能一个个介绍。我就说的用的吧,那就是XGBOOST和LightGBM。(初赛还用了LR,决赛没有空,就没训练LR了)

XGBOOST推荐资料:http://www.52cs.org/?p=429

--------------------------

4.模型融合

这个是最后决胜负关键点之一!!!(当然,我就是跪在这里了,头天还是16.最后一天融合被人挤到23名)。何为融合,就是把一堆分类器揉到一起嘛。当然,这是有套路的。我这里只介绍2种,也是我用的2种。

1.加权平均:很好理解,讲多个分类器的预测结果做个加权平均。看似简单无脑,其实很有效果。但是权重不好确定,可以使用线下CV确定权重,或者线上猜权重(土豪玩法,一天就3次提交机会)但是使用加权平均保证,你用的几个分类器线上结果不能差的太悬殊。(就是不要加入没用的分类器)

*一个大佬告诉我的骚操作(我没试过):给分类器设一堆随机种子,然后训练出一堆结果加权。。。。。。。

2.stacking:一句话解释就是:用其他分类器预测的结果作为当前分类器的特征。

腾讯2017社交广告比赛(广告转化率预测)总结与分享--by Coda_Allegro_第1张图片

这是一张网上的图,和我的表达可能不太符合。只看上面那半就好(下面那半的average不是我想表达的,人懒,不想画新图了)。

大致说下步骤:

(1)讲训练集切成n分(这儿我取5)。

(2)用1,2,3,4份训练分类器来预测第5份的概率,用1,2,3,5训练分类器预测第4份的概率.....(以此类推)。然后用1-5份训练分类器预测测试集的概率

(3)讲这些概率作为另一个分类器模型的特征(在现有的特征上面加一列概率特征)来训练第二层模型

这个方法要点是:用于stacking的模型尽量要差异性大,我用的xgboost和lightGBM融合效果其实不行,原因就是两者都是树形分类器,没太大差别。

stacking的训练代价很大。破机器也很难玩好。融合这一步做的好,最后一天是可以翻身的(初赛我的stacking效果很好,决赛不知道为何就GG了)。

另外,如果你发现了两组强特,他们相关性很强,可以尝试用他们分别训练模型然后融合,可以得到不错的效果。(理论上)

最后我的融合方案是:

用xgboost来stacking训练lightGBM(Model1)

用lightGBM来stacking训练xgboost(Model2)

训练单模型lightGBM(Model3)

结果加权:0.25*Model1+0.25*Model3+0.5*Model2


以上就是我这次比赛全过程的细节了,基本是毫无保留了(源码都给你了),要是有也是人懒不想码的无关紧要的玩意。


你可能感兴趣的:(比赛经验)