IJCAI-18 阿里妈妈搜索广告转化预测大赛总结

前言

从去年11月下旬开始入坑机器学习,到如今也已经有半年了,一开始就是学习机器学习理论方面的知识,可是学到两三个月的时候总以为没点实际操做,因此感到知识点很空洞。本身是自学机器学习的,周围又没有实际项目能够作,能拿来练手的恐怕只有各类数据算法竞赛了。今年二月到三月第一次参加了kaggle上的Toxic文本分类比赛,可是因为自身经验严重不足,和理论知识的浅薄,致使此次比赛几乎能够以惨败收场,虽然最后的排名也是在20%左右,这对于一个机器学习的小白来讲也并非很是差,可是总以为内心的落差仍是挺大的。kaggle的比赛结束不久,还想继续参加,但是kaggle后来的比赛的数据量实在是太大,动辄几十个G,仍是未解压的,本身的渣渣笔记本实在是玩不起。这时候发现天池大数据有个阿里妈妈广告转化预估的比赛,看到初赛的数据量比kaggle小多了,而且比赛的背景也很是符合实际的应用,我很是感兴趣,就立刻参加了,并积极准备起来。在接近两个月的比赛的过程当中,数据不断更换,本身的排名也不断地跌宕起伏,天天除了看书就是想着怎么把排名提上去以及怎么才能进复赛,还好最终也是顺利进复赛了,虽然排名比较落后,初赛第346名,不过能进复赛已是很是满意了,毕竟比赛总共有5200多支队伍参与,本身仍是个初学者,嗯,也不算不好吧,反正就这么给本身打气,但愿复赛可以杀进前一百。复赛的数据要比初赛大不少,解压后数据集有10多个G,这时个人渣渣笔记本又有了巨大的压力,最后是仅使用了七分之一的训练数据,要是整个数据都跑恐怕跑个baseline便Memory Error了。固然最后复赛的结果仍是没能达到预期的前一百名,只有187名,这让我知道了天池的比赛也是高手如云,挺进前一百名那是至关不易啊。不过也好在事情是朝着好的方向发展的,毕竟复赛排187也比初赛的346名强不是?仍是在数据难度加大的状况下,嗯,又来自我安慰了哈哈。闲话很少说,如今稍微总结一下我在天池上的这一场处女赛。代码地址附在文末。html

比赛简介

此次的比赛的目标是预测商品的转化率,就是用户看到这个商品的各类广告信息来估计这个用户买这个商品的几率。原始的特征给出了用户的id,商品的id,商品所属的类别和属性以及上下文等信息,既有类别型特征又有数值型特征。评估预测结果的方法是log-loss,具体详情见比赛网址git

数据

比赛给出的数据是用前几天的数据状况来预测最后一天的状况,好比给出1到7号的历史数据,里面有各类用户商品的信息做为特征,以及给出用户是否购买的状况,1为成交,0为未成交,因此这就是一个二分类问题。初赛的数据比较小,因此我用了所有的数据进行了训练,可是复赛数据实在是太大了(对个人机器来讲),彻底没办法使用所有的数据,仅仅加载数据进去就耗尽了70%多的内存了。这时候有两种选择,一种是进行样本采样,从原始的样本数据中采样出五分之一到八分之一的数据进行训练,其他的抛弃;另外一种是仅使用最后一天的样本进行训练,以前天数的数据所有抛弃。我也不清楚哪种更好,固然,所有数据都保留,一块训练那是最好,但是硬件条件不容许。后来对复赛的训练数据进行了简单的分析,发现前面几天的转化率都差很少,可是最后几天的转化率明显有异常,典型的是倒数最后三天的状况,倒数第二和第三天的转化率仅是开始那几天的一半,而最后一天的转化率居然是开始那几天的4倍左右,而让你预测的那天数据和训练集最后一天的数据是同一天的,因此我就想这训练集的最后一天多是相似于双十一狂欢节这类的日子,只有在双十一或双十二的时候用户会买不少商品,毕竟有活动,看到个优惠广告就点进去,而后发现价格也不贵,嗯就买了吧,因此形成了那天的转化率对比平时异常地变高。那么为何前两天转化率变低了呢,应该是人们早就知道狂欢节有优惠,故而在前两天看好本身想买的东西,可是不急着买,等打折了再买,只看不买的行为多了,不就形成了转化率低了么。因为要你预测的日期和训练集最后一天是同一天的,同时这一天的转化率和其余天还不同,某种程度上就是数据的‘分布’不一样,个人直觉认为仅用最后一天进行训练会比用采样后的样本训练要好,因此就仅使用了训练集最后一天来做为训练集。固然这是否是真的就比使用采样样原本训练要好,就有待于对比检验了。github

算法或模型

先讲下使用的算法吧,原本这应该是比赛流程中的最后一步,可是我在这方面花的时间很少,使用的也都是广泛的东西,参数也没怎么调,就先说下吧。初赛的时候使用过两三种算法,对于这种CTR预估的场景,最经典或者说最经常使用的大概就是逻辑回归(Logistic Regression, LR)了吧,确实逻辑回归算法简单易用,训练速度还比较快,获得的结果精度也能知足大多数应用场合了。可是后面主要使用的算法是LightGBM,这种树算法的训练速度很是快,每次大概几十秒就能够出结果,保证了训练的时间效率,关键得出的结果精度还挺高,因此当仁不让地成为我在此次比赛中的主力模型。随机森林(Random Forest, RF)在初赛时候也使用了,相对来讲它的结果精度不如前两个模型,log-loss值差的有点多,训练时间也多了几倍。总之,初赛时候因为数据集小,可使用多个模型进行尝试,也花不了不少时间,就把三个模型都套用了一遍,最后的提交结果是三个预测的结果取的加权平均,按LightGBM,LR,RF依次取0.6,0.3,0.1来的。初赛的结果不如人意我想是本身特征工程作的不行,复赛时候要注意了(虽然最后也仍是没找到强特征)。复赛仅使用了LightGBM这一种模型,没有和其余模型进行stack或blend,由于测试LR和RF模型的时候发现结果特别差,再加上时间和机器等杂七杂八的缘由,就没有尝试其余模型了。其余可用在CTR预估的算法诸如FM,FFM,DeepFM,GBDT+LR等,须要对数据进行必要的处理或者训练时要GPU加速,本身因为精力和硬件上的不足,没有应用,下次要尝试一下。GBDT+LR的模型其实也是在实际中用的比较多的,主要思想就是利用GBDT利用原始特征生成一些叶子结点做为新的特征再输入到LR里,嗯,也算是一种特征选择吧,其实这是一种很是好的思想,可是不知为什么我在实验的时候发现效果并很差,可能仍是使用方法上有些问题,当时并未仔细思考追究。下面说下特征工程。算法

特征工程

我使用的特征主要分为三大类,分别是组合统计特征,时间差特征以及转化率特征,这部分是本身想得比较多且用的比较多的地方。网络

  • 组合统计特征

就是把各类属性类别类特征进行组合,而后统计它们在某一时间段内的行为。举个例子,好比user_id和item_id这两个特征,分别表明用户名和商品名,可是同一个用户可能看过好几个商品(反过来也成立,即一个商品可能会被多个用户看过),因此能够统计该用户在同一天内看过的商品个数,以及在这一天内,该用户在看过了某个商品以前已经看过了多少个商品,或者在看某个商品以后还会看多少个商品,这就对这个用户的行为进行了必定的统计。固然,统计了同一天内,还能够再统计一个小时内,一分钟内,甚至是一秒钟内用户看商品的行为。一秒钟内一个用户看好几个商品的状况是有可能出现的,缘由多是这个用户同一秒钟疯狂地点击好多个广告,或者是由于网络缘由这个用户老是点击同一个广告,这些都是有可能的。另外,除了统计总数,还能够统计这个用户看到的商品有多少是惟一的,例如用户一天内看了代号为1,2,2,3,3这一共5个商品,按照上文叙述,这里会统计为5,可是惟一的商品只有1,2,3这三种,因此惟一商品的总数为3,这也能够做为一个特征,再者,两者的比例一样也能够做为一个特征,即3/5。同时,这里也能够整理出商品的一些特征,好比代号为3的商品出现了两次,那么这个商品就能够构造出2/5这样的特征,即某个用户在某个时间段内,他看过的某个商品占他全部看过的商品的比例。诸如此类的组合统计特征能够构造出至关多数量,关键点就在于怎样才能构造出有利于预测转化率的特征组合,而后对其进行行为统计。dom

  • 时间差特征

这种特征构造开始也须要像组合统计特征同样,要先对须要进行时间差计算的特征进行组合。仍是以user_id和item_id特征为例,一个用户看完当前商品以后,他可能还会再看另一个商品,即点击另一个广告,那么统计这两者的时间差或许会有所帮助。时间差有两类,一类是当前点击距离下次点击的时间,另外一类是当前点击距离上一次点击的时间。机器学习

  • 转化率特征

就是利用某种特征的历史转化率来构造特征。举个例子,某个item_id,发现它在过去几天中被人们点击数是10,购买数是8,那么这个商品就有8/10的转化率,而另一个item_id点击和购买数为10和2,那么转化率就是2/10,大大低于前者,因此就能够给前者设定一个比较大的数值而给后者设定一个比较小的数值,这便构造出了转化率特征。那么假若你要预测的这天有的商品没在前几天出现怎么办,不是没有转化率特征了么?设为0认为其历史转化率为0?这显然不符合实际,这时候就须要贝叶斯平滑算法了,来利用先验给其设定一个初值。而贝叶斯平滑的具体原理可能须要单独学习一下。这里就不说了。须要注意的是转化率特征一些事项,在个人我的实验中,是这个类别属性的多样性越大越好,好比用户的性别id,最多就三种状况,男或女或用户没有设置,对这三种状况进行贝叶斯平滑效果不见得有多好,而item_id,会有成千上万种,这类属性进行转化率特征构造可能会好得多。另外,千万不要构造当天的转化率特征来预测当天的状况,好比我7号的训练集,我构造了7号的item_id的转化率,而后再拿7号训练集的一部分做为训练集,一部分做为验证集,固然验证结果会表现的很好,可是要是用在预测你的预测集数据上,提交结果以后会发现线上效果不好,由于,已通过拟合了。这里我用了除最后一天的数据来计算各类属性的转化率,这也是复赛中惟一一次用了除最后一天的训练数据。post

  • 其余特征

其中有三个字符串特征,分别是item_category_list,item_property_list和predict_category_property,意思是商品的类别,商品的属性和商品的预测类别和属性。这三个特征是字符串型的,没法直接输入到模型里,但直接扔了不用有点惋惜。我在这里没进行多少处理,就是把预测类别属性的字符串给拆开,分红预测类别和预测属性,而后对比商品的真实类别和属性,计算它的预测命中率,即它的预测属性有多少在真实属性中出现过,再除以它的预测属性总数便获得了命中率。这个命中率我想也能反映出一些问题吧,毕竟若是可以精确地猜出用户输入的搜索关键词对应的类别和属性,那么用户的使用体验也会提升,购买商品的欲望也会强一些。我以前在初赛的时候有参考过天池官方论坛上的这篇文章,做者提出能够用文本分类中的TF-IDF的方法去处理predict_category_property这个属性,即把这个属性经TF-IDF处理后变成一个稀疏矩阵,再把这个矩阵输入到一个模型里预测结果,再将结果做为一个特征。我尝试了一下发现对预测结果影响不大就没使用了,或许是本身的操做不是很正确,就没有再去管它了,可是这个想法我以为很好。学习

其余

有几个问题未能很好解决测试

  • 类别属性直接和数值属性同样,直接输入到LightGBM模型中了,虽然感受不影响结果,LightGBM有比较好的处理类别特征的能力,可是应该有更好的表示类别属性的方法,曾经用过one-hot方法,但是对于
    LightGBM,输出的结果并很差,或许是由于LightGBM不能很好地处理大型稀疏矩阵。

  • 特征总数最后达到了三四百,这么多的特征对于我这渣渣笔记原本训练十分够呛,包括构造特征的时候都是用了不少繁琐的方法才把这些特征组合到一块儿,时常会有Memory Error,内存不足是硬伤。最后也是勉强用这全部特征预测出结果了,可是我认为能够进行特征选择,这么多的特征其实大多数是不起做用的,须要筛选出真正有做用的特征,但是筛选的成本实在过高,时间和机器都不足,就没又作了。关于特征筛选,可参考这个帖子

  • 强特不足,渣特来凑,最后特征筛选的方法其实很耗时间和资源的,关键点仍是在于对业务的深入理解上,以便构造出强有力的特征,我在这方面仍是涉猎太少,找不出问题的关键所在,因此学习任重道远。

最后感谢那些分享想法和代码的朋友们,我从大家那里收获了不少,再次感谢!也但愿本身下次比赛再接再砺。

求个星星!多谢!:)

再附上几个前排大佬的解决方案:

相关文章
相关标签/搜索