2019腾讯广告算法大赛参赛总结

写在前面

这是本人第一次参加比赛,最后初赛B榜成绩84.8,排名第232,遗憾未能进入复赛(取前20%,最终785支参赛队伍)。但跟着大佬一起学习讨论,收货颇丰,特此总结以下经验。

赛提描述

腾讯效果广告采用的是GSP(Generalized Second-Price)竞价机制,广告的实际曝光取决于广告的流量覆盖大小和在竞争广告中的相对竞争力水平。其中广告的流量覆盖取决于广告的人群定向(匹配对应特征的用户数量)、广告素材尺寸(匹配的广告位)以及投放时段、预算等设置项。而影响广告竞争力的主要有出价、广告质量等因素(如pctr/pcvr等), 以及对用户体验的控制策略。 通常来说, 基本竞争力可以用ecpm = 1000 * cpc_bid * pctr = 1000 * cpa_bid * pctr * pcvr (cpc, cpa分别代表按点击付费模式和按转化付费模式)。综上,前者决定广告能参与竞争的次数以及竞争对象,后者决定在每次竞争中的胜出概率。二者最终决定广告每天的曝光量。
本次竞赛将提供历史n天的曝光广告的数据(特定流量上采样), 包括对应每次曝光的流量特征(用户属性和广告位等时空信息)以及曝光广告的设置和竞争力分数;测试集是新的一批广告设置(有完全新的广告id, 也有老的广告id修改了设置), 要求预估这批广告的日曝光 。(出于业务数据安全保证的考虑,所有数据均为脱敏处理后的数据。)

数据说明

user.zip

同样需要再次解压,解压后的到用户数据文件,该数据记录了全部用户数据文件,包括用户的年龄、性别、爱好、地域等等特征数据,与ad_operation.dat中的定向人群有关系。

imps_log.zip

需要再次解压得到里面的内容,内容为全部的曝光日志,也就是广告被访问的请求日志,一条记录代表依次网络请求,代表一次广告曝光(也就是被用户看到)

ad_operation.dat

广告操作记录数据,该数据记录了广告的所有创建、操作记录,包括广告的状态值,如广告定向人群、投放时间、广告状态、广告出价等。

ad_static_feature.out

广告静态数据,该数据中包含了广告的静态数据,如广告素材尺寸、广告对应的商品类型、广告所在行业id、广告账号id等不会修改的静态内容。

test_sample.dat

测试样本,根据该样本预测N+1日样本广告的曝光量,并在官网提交预测结果获得成绩及排行。

赛题分析

可以看出,本次赛题的目标是通过对广告的历史信息预测未来某一天广告的日曝光量,我们可以将其看作是回归问题,更进一步可以看出时间序列回归问题。
本次比赛最大的特点是需要自己构建输入和标签。

数据清洗

我们需要先将曝光日志文件转为csv格式,因此在转换csv的过程中就可以完成大部分的数据清洗工作。具体操作如下:pandas读取原始 totalExposureLog.out 文件时,是逐行分解出各个字段,然后转为dataframe格式,最终保存为csv格式文件。而我们在逐行分解出各个字段时就可以进行该条记录是否是异常数据的判断了,如果是异常数据则扔掉,反之保存。数据中混杂了很多无效数据,需要对数据进行去重、空值处理、无效值处理等,可以参考官方给出的进行清洗。

构造训练集标签

首先说明一点,经过第一步之后,有三张表清洗过,totalExposureLog、ad_static_feature、ad_operation,意思就是说,凡是出现在totallExposureLog中的记录的广告id,一定必须要同时存在于ad_static_feature、ad_operation。
构建训练集标签思路:
官方数据给了5张表分别为:

  1. totalExposureLog :总的曝光日志文件(清洗过)
  2. user_data :用户属性文件
  3. ad_static_feature :广告静态特征(清洗过)
  4. ad_operation :广告操作数据(清洗过)
  5. test_sample :测试样本因此,label的构建实质上就是统计曝光日志文件中同一个广告的出现次数。
    先上一张数据图:这是曝光日志文件里的数据:
    2019腾讯广告算法大赛参赛总结_第1张图片
    可以观察到框中的部分,广告id都为61,但是出价大部分都不相同,出价是广告的一种属性,因此当出价不等时是不能看做同一个广告的。但是,我们可以看到图中红色方框框中的部分,他们的出价是一样的,因此可以暂时视这两条记录为同一个广告的曝光次数,暂定label=2。
    但是因为官方要求的是预估次日曝光量(这里有两种理解,第一种:次日0点到24点,第二种:创建/修改之后的24小时,先暂时当做第二种处理),所以这时我们需要考虑两种情况:第一种情况:在该广告创建/修改后24小时内是否又发生了修改?如果没有,那好我们只需要判断上述广告id=61的广告请求是否是在24小时内发生的,如果是,Label=2,反之,谁的请求时间没有在24小时内,谁就是无效广告。如果又发生了修改则看第二种情况:我们需要将统计了2次的广告请求时间进行归类,举个例子:假设在2点创建了广告,一条广告请求发生在3点。然后在4点发生了修改,又有一条广告请求发生在5点,那么放在训练集里就表现为两个样本,Label分别为1。

模型选择

作为基础的模型,lightgbm和xgboost都非常合适。为什么选择这两个模型呢,主要因为树模型对特征处理的要求不高而且效果也相当不错,不管是类别特征,连续特征效果都很友好,同时多缺失值也可以训练,不需要填充。(有时缺失值也是有意义的,随意填充可能导致预测结果变差)。
在生成初步的训练集后,内部包含的特征有,广告id,商品id,商品类别,账户id。。。这样的类别特征(离散特征),也有像素材大小这样的连续特征。我在本题中使用的是lightgbm,因为数据量太大,lgb的内存优化,能让我们的服务器能够承受得住。在lgb与xgb相同的参数时,lgb模型40G足够,但是xgb模型64G也不够。同时速度也是一个方面,lgb的话,据说速度比xgb快10倍。至于调参工作,在数据量很大的时候有两个方法,一个是按比例抽样出小的数据集用以调参gradsearchCV是一个选择,git上也有别人写好的调参轮子,但是这个时候有可能会使你调出来的参数离最优参数很远。还有一种方法就是控制变量法,其参数不变,每次只调一个参数,这个方法比较慢,但是能取得比较接近最优参数的结果。

到上述为止,就完成了一个初步的模型,再想继续上分就需要做一些更有意义的操作,对于lgb模型训练,可以加入一些更有意义的特征,比如对于人群定向的统计特征,时间统计特征等,也可以对于统计特征生成一些组合特征,还可以通过目标编码等构建新的特征等。对于规则模型,又可以加入一些更具有业务内涵的规则。

最后在A榜的得分可以达到86.3左右。由于B榜更新了大量的新广告id,选择去掉了广告id这个特征进行训练,以及新加入了部分特征,选择五折交叉验证。但是总体思路和上述相差不大,最后得分84.8,遗憾未能进入复赛。

总结

在看了第一名大佬的分享后,主要的差距在于:

  1. 构建训练集本身:大佬选择广告操作表中广告创建时间有出价,定向人群和投放时段的广告id,这是第一部分的广告id,第二部分是三月份出价唯一的广告id,然后将这两部分广告id结合起来作为最终训练集广告id,然后再构造每天的曝光量。最终25w训练样本。
  2. 预处理阶段:对异常样本进行排查删除,这里指的是离群点。
  3. 特征提取:大佬对于CTR问题的理解比我更为深刻。对于特征的刻画划分了细粒度和粗粒度的特征,对于特征的处理更为细致。细粒度的特征对活跃用户比较好,可以更精细地刻画他的喜好,提供更个性化的商品排序;而粗粒度的特征是为了服务不活跃用户甚至是新用户,用大数据中总结出的一般规律来提供商品的排序。
  4. 使用历史平移用过去的历史信息,比如历史曝光量,历史pctr等。这种方法在涉及到时间的时序问题似乎很有效。
  5. 使用CountVectorizer进行统计,这个虽然是NLP中的常用方法,但是大佬灵活运用到了这上面。CountVectorizer是一种文本特征提取方法,对于每一个训练文本,它只考虑每种词汇在文本中出现的频率。
  6. 大佬采用Lgb与使用NN的队友进行模型融合

这次比赛,自己花了百分之九十左右的时间在数据预处理上,可能还是自己对于真实业务数据不太了解,真实业务数据由于格式,脏数据等问题需要自己一步一步清洗,最后得到干净的训练集。这可能需要花费很多时间与精力。
最后,参加竞赛一定要一心一意扎进去,全心全意投入去做,才会有提升,切忌心浮气躁,最好不要双开,除非你是大牛。希望你永远保持着,大智若愚,求知若饥的心态。

你可能感兴趣的:(2019腾讯广告算法大赛参赛总结)