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

1.概述

花了两个月时间参加了IJCAI-18 阿里妈妈搜索广告转化预测比赛,对于一个刚接触ML的小白,第一次参加天池的比赛,十分有幸的在初赛进入前500名,复赛进入前300名。
主要工作包括:特征工程与特征选择、多模型选择、调参等。

2.特征工程与特征选择

2.1 基础特征

Id类、Level类:对item_id、 shop_id 、item_brand_id等特征,对数值区间进行了处理之后直接使用;使用LR模型时进行了one-hot处理。
Score类:未处理
其他:item_property_list提取了出现次数最多的n种属性,然后对样本进行one-hot, 对item_predict_catogery字段提取了前3个预测catogery;对catogery提取了类别属性,其中一级类别都一样。

2.2 交叉特征

对基础特征进行交叉,可以描述更加复杂更有效的特征。比如对收藏次数等级特征item_collect_level,直观理解收藏次数越多说明受到越多的关注,广告更容易得到转化;但是考虑展示1000次被收藏10次、展示100次被收藏9次两种情况,显然从“回头率”角度来看,后者更有吸引力;因此结合展示次数等级特征item_pv_level,可以提取出比较有效的展示收藏率特征,而且两个特征的取值数目都较少,交叉之后不会出现数据稀疏的问题。
在比赛中,提取交叉特征一方面依靠对特征的理解,另一方面借助了大佬开源的代码,包括特征工程代码(bangdasun/tianchi 等)和特征选择代码(duxuhao/Feature-Selection)。在特征选择代码中,采用+、-、*、/等运算进行特征交叉,可以交叉出意想不到的特征,并且可以在线上和线下同时提高成绩,比如user_star_level乘以item_city_id、user_age_level除以item_sales_level。

2.3 统计特征

针对不同的类别以及类别组合,通过mean(),size(), count(), cumcount(), unique()等方法可以提取具有明显物理意思的特征,比如店铺的平均价格等级、店铺顾客平均年龄、user的查询次数,各种特征按时间的统计值等。

2.4 历史点击率特征

1) 基础特征的历史点击率
对id类和level类的基础特征,提取历史点击率是比较有效的特征。物理意义明显:某些人的购买能力和消费欲望更强、某些商品或店铺的销量更好。
没有采用滑窗构建特征,可能在一定程度上降低了此类特征的有效性。
为了避免评估和时间穿越(浅谈机器学习评估中的穿越问题)问题,将训练集的最后一天作为验证集,并在划分训练、验证集之后,再对训练集提取历史点击率特征,并将特征merge到验证集和测试集中去。
Merge特征时,对未出现的id取均值。需要注意的是,对shop_id、item_id、user_id等特征,验证、测试集中可能出现较多训练集中未出现的样本,这种情况提取历史点击率没有意义,甚至大幅度提高loss。比如本次比赛round2中的user_id, 在验证集中出现了530596个训练集中未出现的样本,占验证集总数1077175的一半,将该特征的历史点击率加入模型训练之后,验证集最佳loss由0.1805上升至0.1822左右,影响很大。
数据集的大小影响了特征的效果:round1中提取此类特征表现出了明显的过拟合,而round2中比较非常有效
2) 组合特征的历史点击率
组合特征对样本进行了进一步的细分,比如对样本按shop_id、user_age_level进行group_by操作,得到组合后的细分类别,并提取每一个细分类别的历史点击率,可以表达不同的shop对不同年龄段客户的吸引力。
在本次比赛中,对item、shop、brand分别提取不同age、occupation、gender细分的历史点击率。然后,效果并不好,出现了较为严重的过拟合。
基础特征、组合特征的历史点击率分别在round1和round2中出现较为严重的过拟合现象,可能原因为细分类别太多,导致每种类别对应的训练样本太少;当数据集增大,基础特征的点击率在round2中有效;当数据集进一步增大,却不明显增加各种id类特征的数量,组合特征的点击率特征应该会有较好的效果。

2.5 特征选择

特征选择主要从两个角度出发:一是从特征自身的分布特点,二是从模型性能。
从特征自身判断:①提取特征之后,确认特征在训练集、验证集、测试集中的分布接近一致,判断手段包括均值、方差等统计值;②通过corr等方法分析特征与label的相关性,作为判断一个特征有效性的参考。
从模型性能判断:①选择不同的特征集合然后训练,从训练结果判断集合的有效性,实现过程中采用前向和后向搜索两种贪心的选择方式;②从模型提供的特征重要性角度选择,值得注意的是,模型复杂度对特征重要性有较大的影响,当模型较为简单时,较多特征的重要性为零,而当模型较为复杂时,则几乎所有特征的重要性都大于零。

3. 模型

Round1: 使用了多种模型,都没有调参,LightGBM(线下0.0809)、LR(线下0.0813)、GBDT+LR(线下0.0813)、DNN模型(线下0.0819),LightGBM的效果较好。
Round2: 数据量太大,仅使用了两种模型,LightGBM的分类和回归模型(线下皆为0.1801)、XGBoost模型(线下0.1803)。
1) GBMs
Lgb的训练速度很快,有利于特征选择与快速的调参,是比赛主力;xgb的速度较慢,结果与lgb相当。针对二分类模型,回归和分类的模型都可以使用,模型融合成绩大概提升万分之五。
2) LR
需要做较多、较细致的数据预处理,one-hot之后数据量太大,且速度相对较慢,在复赛没有尝试
3) GBDT+LR
GBDT使用了SK中的GBDTClassifier、lgb和xgb,GBDTClassifier的性能最差而且很慢,lgb+LR最好,但是比不上lgb单模型。个人觉得可能是因为GBDT虽然能自动提取一些组合特征,但是一些重要的特征还是需要进行手动的特征工程。
4) DNN模型
简单看了一下论文和kaggle上相关比赛的模型实现,尝试了PNN和DeepFM等模型,但是由于不太熟悉这部分内容,效果一般。

4. 调参

主要针对lgb和xgb进行了调参,由于数据量特别大,又担心subsample影响样本的分布,尤其是较多item_id,user_id仅在训练集中出现,所以硬着头皮在所有训练集上进行调参。简单粗暴调参:固定较大的学习率,选取一个简单的模型作为baseline,对单参数逐个进行精调和粗调。
调参主要是针对过拟合和不平衡样本,具体参数参考lgb和xgb的帮助文档即可。其实两个模型除了max_depth和num_leaves两个参数有细微的差别之外,大部分参数的物理意义都非常相似;另外lgb的分类和回归模型的参数仅调一个即可。
对于正负样本极不平衡的数据集,scale_pos_weight参数非常重要,调参后成绩提升约千分之一;其次是max_depth、num_leaves; colsample_bytree、learning_rate影响也较为明显;其他L1、L2等正则化参数调参有一定的提升。

5. 其他

除了上述操作之外,还试了几个不靠谱的操作,都没有什么提升。
1) 对预测结果进行修正:对预测值进行排序,按一定比例将预测值较大的结果加上一个常数;对预测值较小的值减去一个常数。这么做的原因是:将预测值较大的结果全部判定为正例,将预测值较小的结果判定为负例,这样的正确率是远高于随机猜测的,根据log_loss的公式可以知道,这样的修正是能降低loss的。结果验证集loss降低万分之四左右,测试集loss几乎没有变化。可能原因是两个数据集的分布不一致,而且没有看到修正预测的均值逼近真实平均值的骚操作(https://github.com/infinitezxc/kaggle-avazu)。
2) 伪标签:在kaggle比赛Toxic Comment Classification Challenge的冠军分享中提到了这个思路,利用test集的预测结果,将test集加入训练集,对结果有一定的提升。进行了一定的尝试,效果一般。可能原因是:TCCC比赛的样本不平衡程度相对较小,训练结果的召回率和准确率都较高,可以使用分类结果而非分类概率作为伪标签,伪标签与真实标签的分布相差较小;而此次比赛数据集的数据非常不均衡,大部分预测结果都小于0.2,导致以概率作为伪标签之后,相对真实标签的分布相差太大,以至于效果非常不好,线下loss为0.194。
3) 在DNN模型中尝试了BiLSTM+ATTETION方案:主要考虑这样一个想法,每一个样本其实都可以描述为一句话:某个user在某个context环境下看到了某个item,该item具有某个属性blabla。这就可以借鉴文本分类的思路进行建模,BiLSTM+ATTETION或者BiGRU+ATTETION可以说是文本分类比较简单粗暴且有效的思路了,结果在round1中线下0.0823左右,效果一般;在round2中训练速度太慢,放弃之。

6. 总结

收获:

1) 从业务层面:在面向科学上网与帮助文档的基础上,磕磕绊绊独立完成了定义任务、从原始数据提取特征、特征选择、模型选择与调参的完整技术流程;了解了CTR任务的特点与常用模型;
2) 从技能树层面:以项目驱动方式熟悉了LightGBM、GBDT+LR、相关DNN模型,Pandas、SK等python包;同时也暴露出算法层面和工具层面的不足。

不足:

1) 模型层面:缺少对模型的深刻理解,对于模型选择没有充足的理论和经验支撑,停留在调包调参,单纯从模型性能选择模型的阶段
2) 特征工程层面:一方面缺少对实际业务背景的理解,另一方面没有形成特征提取、评估的一般性方法与流程。
3) 在编程基本功层面:程序和数据的复用程度较低,没有实现从数据→特征→特征评估→模型训练的模块化框架,做了大量重复的工作;没有充分了解python及相关包的语言特性、数据结构特性,在内存控制、算法复杂度等方面存在较多的不足。
总的来说,个人目前处于将长期处于看山是山、看水是水的社会主义初级阶段,对于业务、算法、工具甚至一些trick在直觉上有一定的认识,并且可以在借助一定辅助手段情况下完成从任务到结果的整个流程,但是从经验和理论层面都缺乏对各个环节的有效性能把控能力,像一张白纸,从项目实践中大量的、无论好坏的吸取经验。

你可能感兴趣的:(CTR)