talkingdata 广告欺诈检测分享
DataScience Club@BUAA
赛题链接: https://www.kaggle.com/c/talkingdata-adtracking-fraud-detection
赛题简述
之前写了一篇关于CTR/CVR的推送,这次回头来看还是有点不同的,CTR预估就是这样的任务:给定用户或某唯一标识,给定一个商品(Product),给定了一定的环境,来看用户会不会买这个商品,买商品的概率有多高;或者说给用户推荐一个电影,用户会不会看这个电影,看的概率有多高。形式化的表示就是建模P(click|content)给定上下文,建模点击/购买/下载/使用的概率。这个问题是识别广告欺诈行为,表面上是看也是是否转化成功,实际上关于user和product的分析还是有很大不同,在下面我们会仔细地探讨这个问题。
关于成绩
今天kaggle Talking Data结束了,开榜前踩着金牌最后一名提心吊胆,最后虽然选的结果是第7好的,但还是前进了3名。private榜单上排14,看了下单模型也有进金区的,这次比赛还是CV比较重要,trust local cv应该是每个kaggle玩家的座右铭了,上次toxic从10名掉下来,也是吃了这个的亏。当时感觉训练和测试分布不同,就全靠梭哈了。最后果然GG。
这次也是跟@砍手豪学到了很重要的一点。
亿级数据踩坑
先讲一下我们的比赛策略吧,我和砍手豪确定组队之后,就开始撸代码调bug的艰辛一周,他把基础框架搞定了之后,我就开始做了一些对于针对大数据量的优化,发现踩了很多坑。这里还是想分享一下,这些东西不算数据敏感性这种内功,招式还是很容易学到的。
1.pandas的dataframe在连接列的时候,如果你使用pandas.concat(["column1","column2"], axis = 1)就会变得超级慢,有多慢呢,我估计是O(nlog(n))的复杂度,目测考虑了两个index排序,然以用O(n)插入。所以如果你能保证有序的话,完全可以用dataframe的列赋值。
2.还有个坑是大数据量的时候,你可以根据整数类型,浮点类型的范围减少位数,比如用uint8, float32之类的代替int32,float64
3.还有一个lightgbm转换dataset的时候非常耗费内存,可以把数据load save一下
4.最后就是可能大家用了多进程multiprocessing来加速,调用pool.apply_async(XX) 之后get_result()会面临一个触发这个bug的问题,看了下开发issue列表,大家觉得这个不是正常人的需求,就没有搞这个。解决这个问题的方法就是, result.to_hdf()然后read回来。这样就巧妙地避开了,而且这样也有利用disk加速的好处,hdf5的io还是很快的。
上面都是亿行数据在特征维度变高的时候踩得坑。改bug和优化pipeline用了一周的时间,弄完后,我们就跑出了一直到比赛结束的最好的单模型大概就是单模型 private 0.9830264,所以说后面大多是没什么idea之后的特征筛选关于模型精度提升的验证试验,融合之后也没太大提升。
CV策略
CV策略也是很关键的地方。极大地缩短了我们快速验证特征有效性的实验次数。
如果把这个数据集掐头,然后调整时差后就是完整的4天数据。如何利用四天数据做好一个线下验证就很关键,解决了这个问题,你的线上线下基本就同步了。
所以我们做了三个策略。
阶段一,特征构造的时候只选含public的三个小时,用这部分数据可以粗略地筛除一部分特征,比如跟小时的统计值相关的,一部分跟天相关的,毕竟是一个下采样,而且不连续。所以这一部分完成后,用了大部分特征进入第二阶段。
阶段二,训练集改成第8天,测试集第9天,这样可以保证一天内连续,可以做关于小时的特征,以及连续时序,时间窗上的特征,带来的问题是,day的信息丢失了,然后这部分做完了,特征多了起来。进入第三阶段
阶段三,就是完整的78训练,9天验证了,根据相关性和特征重要度做进一步的特征筛选,修正模型在数据下采样上的偏差。让模型更鲁棒。以及增加时间粒度的实验。
阶段四,最终提交的时候,根据78训练,9验证的earlystop盲打,轮次变为1.1倍,直接梭哈
关于NN和FFM的实验
几天在美团跟eureka大佬聊天的时候,他说起之前的CTR/CVR比赛都是ffm起了很关键的作用,为什么这次不行呢,反而成了GBDT的天下。我当时觉得欺诈预估的问题与一般的ctr/cvr的明显区别就是建模user的困难,user会变化ip,设备,伪装自己,这样造成了user的隐变量的稳定性不是那么鲁棒。不过微软的Lightgbm真的很强,对catgory类做了很多优化,不用one-hot直接fit,关于这一块的原理,我也十分好奇,在好几个地方问过了,我记得有人跟我说是直方图弄概率分布啥的。这一块有大佬可以在评论里请指教一下。
NN我们做了大概public在9806private9820左右,不过最后融合没有使用。模型比较关键的地方就是交叉熵要做一个加权,让模型训练的时候多关注一下正样本,毕竟CTR里面正样本十分稀少而珍贵,解决数据不均衡的问题就比较关键。我自己做了一些FNN,PNN,网络写FM,DeepFM,deep&wide的实验,效果也一般,最后精力也没有放在这里,不过作为弹药库储备还是可以的,以后的比赛可以用上。
特征工程
特征工程的思路,这一块也是跟前排拉开差距的地方,真正的大佬完全可以用方法和特征对你完成降维打击,网络的出现让特征工程变的弱化,但是在这种非同秩数据上,特征工程才是制胜法宝。这也是我相对深度学习更喜欢数据挖掘的原因,数据挖掘中关键的一步,特征工程会更让你理解数据的本质,让你理解什么是同分布,什么是过拟合,什么是模型的bias。网络确实在同秩数据上诸如图像文本语音有一定的优势,但是那种对于结构反向解释,马后炮的感觉让人很难受,或许是距离真正的深度学习大佬差的太远,还没办法深入理解网络的原理。
我们这块特征工程大概就是学习了之前CTR的方案,特别感谢piupiu植物们的开源,让我们受益很多。推荐排序的建模方法也是从piupiu的摩拜单车地点预测开源方案学到了,后来这个方法用到蚂蚁金服的商铺赛题上,对推荐系统的建模,负采样策略有了更深刻的理解。
关于我们这里的feature,砍手豪整理了一个关于CTR问题的通用特征文档,非常详细,我这关于版权的问题就简要描述一下。要是有可能的话,公众号可以请他出一期分享~
我们大概做了的特征,basefeature,历史CVR,历史转换次数,时间窗(day,hour,quater,half hou,3min)各个维度的统计值(count, unique, max,var),连续点击时间间隔,各个维度的排序,以及一些二阶统计值,这部分比较关键,对app和channel的刻画重要度都非常高,还有一些user活跃持续时间,活跃频率等等,感觉特征也比较基础。没有什么特别出彩的地方,对数据的理解还要看前排大佬的分享。
有一个比较有意思的地方是赛后植物说关于修正同样样本预测值的trick,这是一个明显的训练和测试数据不同分布的例子,训练集中正样本都出现在了开头,植物的trick把除了最后一个抹0,public上了,private降了,第四名就从这角度,把训练集重排了下,提了四个万分位。高手还是高手,这种数据敏感性真的很强。
总结
最后总结一下,一定程度上(只针对监督学习的问题),模型和方法都是招式,数据敏感性才是内功。时刻牢记trust local CV。没有任何一个模型可以用样本代表整体,用一定程度的采样代表全世界。如何减轻bias,这不仅仅是数据竞赛的关键,也算是论文数据集可信度的关键吧。在我看来,只有imageNet这样规模足够的数据集检验下,模型才有一定的信度。很多人都是在老生常谈这个trick在提高数据集,那个trick提高数据集。重剑无锋,大工不巧,同秩数据,没有什么trick不trick,只有万变不离其宗的样本刻画方式,换句话说,就是如何把样本映射到向量空间,以及如何让模型在样本空间中寻找解。深度学习在试图解决这个过程的自动化,一定程度上,还是有多人工就有多少智能。当然真正的大佬,是可以从方法的革新上对你进行降维打击,让你怀疑全世界。比如alexnet之于ImageNet,svd features,ffm等之于Netflix,现阶段的xgboost,LGB等等。希望也能成长为给问题造新轮子的人,而不是检验轮子的人。最后谢谢队友们的坚持~started from the bottom.
领取专属 10元无门槛券
私享最新 技术干货