2016Bytecup之菜鸟进阶

来源:互联网 发布:4g卡显示2g网络能用吗 编辑:程序博客网 时间:2024/05/18 05:03

2016Bytecup之菜鸟进阶

写在前面:好久没写文章了,最近两个月忙成狗,基本上都是白天实验室做项目,晚上抽时间打比赛、学习。今年上半年开始入门,然后断断续续参加了几个比赛,大多都是水过去了,感觉没学到东西。国庆回来后决定抽时间好好玩一个比赛,认真学习一下,当时看了bytecup还有天池的航空大数据比赛,看了赛题后决定主要精力做bytecup。主要考虑比较典型的监督学习问题可以更好学习特征工程、模型调参等,像上半年的流行音乐大赛那类的长期预测问题对于我这种菜鸟来说实在找不到正确的打开方式,模型结果还比不过花样均值和规则(大神们口中的人工规则还也没有get到)。最终成绩一般吧(53th/1020,拿到一个IEEE会员和三个CCF会员),关键是在这期间刷了项亮的推荐系统实践以及一系列的推荐引擎paper和开源框架,SVD、FM等,对推荐系统有了一次系统的学习,陆续也会写一些相关的博文上来。最最重要的是认识了两位新队友,终于不是一个人在战斗了!还有比赛交流群的一些大牛也很nice,有问题他们基本会帮忙解答,还有分享思路的。比赛源码放在我的github上了点这里 。

注:菜鸟参赛体验,希望路过大神拍砖指导!

一、赛题介绍

比赛官网:2016 Byte Cup国际机器学习竞赛
赛题主要是利用给定的头条问答数据(包括专家标签、问题数据以及问题分发数据,详见数据描述部分),进行针对问题的专家挖掘。给定若干问题,参赛者需要预测哪些专家更有可能回答这些问题。
初赛数据: http://lab.toutiao.com/wp-content/uploads/2016/09/bytecup2016data.zip
最终测试数据(无标签): http://lab.toutiao.com/wp-content/uploads/2016/11/test_nolabel.txt
数据解释看这里:https://biendata.com/competition/bytecup2016/data/
评测方案跟其他比赛不太一样: 评估方面,给定一个测试集中的问题,我们先根据预测概率对候选专家进行排序,然后分别评估排序结果的NDCG@5,NDCG@10,最后评分公式为 NDCG@5 * 0.5 + NDCG@10 * 0.5。测试总分数等于所有测试问题评估分数的平均。
关于NDCG,赛题数据中有给参考资料和代码,这个评测指标关注的重点在于排序,对于同一个问题,专家回答可能性的排序越准,得分越高。

二、 验证集(season 1)

solution 1: Supervised Learning

刚接触赛题前几天,觉得是比较典型的监督学习问题,于是思路就是数据预处理、特征工程、特征选择、选择分类模型(svm、xgboost等),模型融合。
(1).数据预处理,主要用的是SQL进行GROUP,JOIN等,将专家特征、问题特征合并到train集,然后做一些统计分析。这里还做了一些数据清洗,主要是去除一些重复的ui对(专家-问题对)label取最大值(0或1)。
(2).特征工程,基于标签做了一些统计特征,然后用的python进行特征构造,一共做了20维左右的特征。特征包括专家特征(专家回答问题数,回答率),问题特征(问题回答数、点赞数、sp回答数、问题回答率等),专家-问题特征(ui_回答数、ui_回答率、ui_标签距离、ui_描述词向量相似度、ui_描述字符向量相似度,ui_词距离等。
(3).特征选择,看过一些大神的分享直接用xgboost输出特征得分,于是选择用xgboost训练并输出每个特征的得分,以此来进行特征选择,后来从队友那学习用sklearn的包进行特征选择也是不错的方法。经过特征选择留下了大概十几维的特征。
(4).模型主要用了lr(队友完成),svm、xgboost,通过线上反馈以及群里的大神分享,发现线性模型的效果更好。
(5).开始一两周的尝试,线上成绩并不不是很理想,最好到0.48,所以打算换思路,模型融合也没有做了。

solution 2:Recommender System

开始两周埋头苦干,结果线上成绩糟糕(200名左右了),有点灰心了就丢一边了。接着一周就开始水群,逛DC、kaggle一些经验分享,让自己也重新梳理了思路,认真分析了评测函数,于是又打开了新的一扇窗–>推荐系统。因为要预测的是专家会不会回答一个问题,这是个典型的推荐系统问题!于是开始找各种推荐系统相关的资料,协同过滤、SVD、SVD++等。 在知乎上找到一个回答几乎涵盖了所有流行的开源框架:https://www.zhihu.com/question/20253152
(1).协同过滤,userbased,itembased. 线上0.44
(2).SVD、SVD++ 线上0.47
大概花了一周的时间,试了几种推荐算法,但是线上成绩还是一般,又是失望啊… 成绩已经200名开外了,第一赛季也只剩一周了。这时候我想监督学习的方法用了很多特征,但推荐系统只用了ui特征(后来发现SVD貌似也可以加特征..),于是我决定将监督学习模型得到的结果与推荐得到的结果融合一下,果然成绩一下提高到0.49了。

solution 3:Factorization Machines

在尝试了一些推荐系统方法没有得到较大提升后,终于又发现了新的黑科技FM,FM可以理解成加强版的LR或者更加强大的SVD,它可以很好的实现特征组合。美团技术团队有一篇介绍FM/FFM的文章,非常棒,看这里深入FFM原理与实践。

FM是一种比较灵活的模型,通过合适的特征变换方式,FM可以模拟二阶多项式核的SVM模型、MF模型、SVD++模型等,相比SVM的二阶多项式核而言,FM在样本稀疏的情况下是有优势的;而且,FM的训练/预测复杂度是线性的,而二项多项式核SVM需要计算核矩阵,核矩阵复杂度就是N平方。

FM最权威的应该是libfm了,时间问题决定找个python实现,于是就找到了graphlab,里面已经实现了基于FM的推荐算法,可以添加user特征、item特征以及ui特征,并且还有RANK功能,似乎更适合该赛题。发现这个黑科技已经是第一赛季最后一天,熬夜完成了一般提交,线上0.492+!!!这可以是单模型啊,而且只用了回答率特征,就比我之前各种折腾成绩还好,本来打算放弃的我又找到了新希望。
同样是这一天,在群里跟人交流,非常幸运的现在的队友私聊我了,于是我们交流了一些思路,决定组队。

三、 测试集(season 2)

可以说是带着新的憧憬进入最后十天的(测试集)比赛,趁着周末我们各自整理之前的思路、特征,然后讨论了一下,队友主要用的是LR(加了规则线上0.492+),还试了Deep Learning(效果一般,线上0.47)。通过讨论我们决定还是按照各自的想法做,特征共享,然后最后融合。
小插曲:season 2开始前两天没有验证集提交评测,我的内心是崩溃的,感觉刚发现了新科技但是没机会根据线上反馈来提升了(后来第三天就开了,长舒一口气…),于是我跟队友就打算线下用相同的划分数据集,然后线下评测。不过按队友的说法,他之前老是过拟合…线下很好,线上糟糕。
也是因为过拟合问题我们开始找原因,根据一段时间来的线上反馈,我们都发现了回答率是个非常关键的特征,但是基于标签的回答率很可能发生“特征穿越”,因为用了先验知识。于是我开始思考怎么减少这种穿越带了的过拟合影响。重新对数据进行统计分析,我发现有很大一部分专家他的回答次数很少,可能就只回答了一两次,但是刚好他们只收到了这一两条推送,因而使得他们的回答率奇高,如果把这个回答率当做他们的全局回答率特征显然是不科学的。train集也是采样得到的,这类专家的ui对完全有可能只采样到label为1的样本,而在验证集与测试集中的分布就不一定了。我把这个想法跟队友交流了一下,队友也觉得有道理于是我两马上实现一波“特征惩罚”,对于回答数少但是回答率高的专家进行特征惩罚(除以一定系数)。果然提交后提升至0.493+!然后又对ui_label回答率(专家对某类问题的回答率)也做了类似处理,继续提升0.494+。
接着几天我接着调整惩罚系数,效果一般。很快比赛只剩下最后三天,我觉得特征可能很难提升了,于是开始准备调整模型以及融合(blend和lr融合)。看了一些大神分享,我把调整了FM的隐变量数(1024)以及迭代次数到2000+,电脑配置一般,跑一次结果要三个多小时…不过验证集线上成绩提升到了0.4953+,成功冲进前100。最后两天由于出差没时间折腾了,就在走之前一天晚上跑了几个不同特征、参数的测试结果级给队友融合用。

……

出差回来,终版成绩也出来了,最终成绩也比较意外,我们冲到了53名。可能有些队伍搞其他比赛去了,测试集就没提交了,也有一部分前面的队伍过拟合了。不过还是挺开心的,跟前面大神们还是差很远,但是跟之前的成绩比已经进步很大了。今天收到了官方的邮件,填了信息,也就结束了本次比赛。

四、 总结

从上半年接触数据挖掘以来,这是第一个完整坚持下来的比赛吧,抱着学习的态度,收获还是挺大的。不足之处也很明显,特征工程仍需修炼,特别是一些细节处理,缺失值处理,独热编码,dummy variable等,模型还需多学习,理解原理才好拿来实践,模型融合大法的奇效也没有真正领会到。
遗憾还是有的,初赛始终没能突破0.5,群里苍老师说光uid,qid就能破0.5啊!!!一直没有get到,坐等大神们的分享。比赛结束后也有人说用FM迭代个1000次就能前20了,啊,难道我的黑科技打开方式还不对?!
So,革命尚未成功,同志仍需努力!!!

大神思路分享

这个完全参考的FM原文,不用创新,直接对应撸一下,按原文,初赛成绩是 0.518—段子

我还是觉得fm里面取倒数不如用idf+平滑的好—苍老师

tfidf 我在规则中用过,每个问题的用户列表看作分词—段子

坐等开源!等大神们公布代码了再贴上他们的github。

2016 Byte Cup 国际机器学习大赛TOP2代码分享—苍老师

2016 Byte Cup 国际机器学习大赛TOP3解决方案—段子

byte cup 机器学习TOP3,代码分享(协同过滤部分)—段子

1 0
原创粉丝点击