Tencent-chusai 题目简单来说,即给出广告的基本设置,要求预测每个广告的日曝光量。但这个题比较有意思的是,初赛和复赛给出的数据集,不仅是数据量发生了变化,数据的内容也发生了很大的变化,可以说初赛和复赛预测广告日曝光量的已知条件发生了很大的变化。 初赛 1 - 初赛 初赛给出的数据集为 Logday.csv - 曝光广告日志文件 ad_static_feature.csv - 广告静态特征,可以直接merge应用 ad_opeartion.csv - 广告动态操作表 user_data.csv - 用户数据表
在实际的应用中,没有用上user_data数据,因为一个广告会被很多的user观看,因此一条样本会对应很多的uid,无法简单merge应用user data,初赛曾考虑将uid list和uid num作为feature,但是test集中无法得到这个fea。
【part A - train集合生成】 初次比赛,没有什么经验,只觉得应该精细做到题目的各个要求,应该可以取得比较好的效果,因此花了大量时间来构建一个符合各个条件的训练集,但是后面发现这样做和直接groupby产生日志的曝光量没啥太大的区别(反正在我这里没撒用orz),这就比较gg了。 因为题目中说只是对cpc计价的广告进行曝光量预测,因此就只考虑cpc计较的曝光日志,由于数据量较大,因此首先将原始的log日志split一下。由于非cpc计价的广告的bid变化较大,因此就将bid一天之内变化比较明显的,且不在操作表中的aid都删除掉【之后看别人思路,是直接将操作表中存在的aid取出来作为训练集即可】。 splitlog.py Maketrain.py文件是构造训练集的代码,里面考虑的构造训练集的点主要来自操作表,就是将操作表中修改了投放时间、bid和人群定向等的广告,都作为一个新的广告来处理,并且将状态为无效的广告的log去掉。 代码中顺便把人群定向中的各个特征进行了split操作,将所以的log处理完毕以后,按照'Reqday', 'ad_id', 'adBid', 'puttingTime’等进行groupby,【最开始我是将人群定向等特征也加进了groupby的条件中,发现太过苛刻,效果不好,看其他人的groupby都比较简单,直接是reqday和aid分组,我就简化了此项操作,但是在初赛后期和复赛中,我都是直接按照reqday和aid进行groupby生成的train集合】 【part B - 特征工程】 受到一些知乎的特征工程的思路影响,尝试了几种简单的特征,比如count特征,和日志曝光的历史平移特征。
- 单值特征进行了one-hot编码,多值特征进行了multi-hot编码【初赛后期直接将这部分特征去掉了,因为这里发现单值特征one-hot与否,对于lgb的影响不大,多值特征编码以后,也useless】
- 统计count特征,对于多值特征,分别统计特征值的count,返回是平均出现次数和最大出现次数作为特征
- 曝光量特征统计,即历史平移label
所有的关于初赛的特征提取的函数代码,都封装在了utils.py文件中,然后再lgb_fea.py文件中调用提取,生成对应的特征文件,然后在lgb.py中读取调用,这样做的一个好处是对于提取时比较耗时的特征,可以节省时间,一个很明显的缺点就是如果要修改特征,会比较麻烦,如果要用这种方法的话,最好的还是形成一个比较简单流畅的pipeline,这样比较方便于调试代码,反正我腾讯赛后期调试十分让人想选择狗带~ 之后看top的开源代码,基本上提取特征都是一个实时的过程。 还有一个比较重要的点是,我的train和test的特征都是分开来操作生成的,这样其实非常难以调试,之后看别人代码,都是train和test合并在一起进行特征提取的。 【part C - model】 模型一开始用的xgb,后面运行速度太慢了,就换成了lgb,因为Tencent赛题是一个时序题,因此初赛一直用的是时序验证,特征提取的时候也用的时序提取的,但是后面复赛改为了五折,发现五折可以上分orz。
初赛我的模型渣到爆了,跪给了自己一开始错误的估计了细节的重要性,以及做特征思路比较局限,虽然是第一次比赛,但是它没啥效果,我还是蓝瘦香菇。
【part D - 规则】 旧广告直接用前一天的中位数填充,新广告用前一天的各类id填充,还尝试了对各个id交叉,然后用交叉id填充新广告,这个想法来自于我之前看到一个点是,如果你的特征粒度越细,就越容易定位到一条样本。 Rule部分代码只是简单的pandas的应用,由于太乱就不放了。
初赛最后是规则和模型进行了简单加权融合,大概是90名左右的样子
2 - 复赛 复赛的数据发生了比较大的变化,用各大佬们的话说就是换了一个新题,给出的数据表如下 track_log.zip user_data.zip 广告数据文件(仍然是包括静态表和动态操作表两个表) 但是复赛的test提供了测试当天的用户请求队列,以及待预估广告被哪些请求召回。 也就是说这两个条件给出了,那么就不需要通过初赛中通过人群定向和投放时间等来得到广告的投放范围,而是更加去关注,这个竞争队列中,到底哪个广告容易被曝光。这样一个比较明显的有效特征就是这个广告的曝光率,因为已知这个广告的竞价次数,并且也已知这个广告成功曝光的次数,这样也意味着初赛中那些人群定向等特征彻底失效,虽然本身也没啥太大的贡献。 【part A - train集合生成】 复赛train集合的生成就比较简单粗暴,直接沿用开源的各位大佬的思路,去掉log中的一些异常样本,直接对day和aid进行groupby,然后merge上广告静态特征作为基础特征
【part B - 特征工程】
【part C - 模型】 使用lgb五折交叉验证 但这里的建模方法有一点需要注意,就是在复赛的log中其实给出了大量的0样本,有些广告虽然有曝光请求,但是都没有被曝光过,但是此时的0样本比例过大,所以对0样本采样处理,可以提分。 【part D - 规则】 用前一天的曝光成功率*当天的请求数量作为旧广告的曝光数,新广告填充0 有的广告前一天没有曝光,那么就次序往前推,直到找到它的曝光成功率。 初赛的规则基本上已经没有用了,尝试了用曝光成功率填充,效果也不好,所以就索性直接填充0了,因为模型预测出来,新广告的曝光量很低,都是0.X左右