专栏名称: 天池大数据科研平台
天池,基于阿里云的开放数据处理服务ODPS,面向学术界开放海量数据和分布式计算资源,旨在打造“数据众智、众创”第一平台。在这里,人人都可以玩转大数据,共同探索数据众创新模式。
目录
相关文章推荐
软件定义世界(SDX)  ·  李彦宏把AI的门槛打没了 ·  23 小时前  
数据派THU  ·  一文解读:时序基础模型的缩放定律 ·  5 天前  
艺恩数据  ·  男装市场稳增长,潮流趋势引航向 ·  6 天前  
数据派THU  ·  Github上的十大RAG(信息检索增强生成)框架 ·  1 周前  
51好读  ›  专栏  ›  天池大数据科研平台

开发攻城狮初试算法大赛,就夺得初赛第5!他是怎么入门的?【附学习资料】

天池大数据科研平台  · 公众号  · 大数据  · 2016-11-29 22:28

正文

11月28日,广东大赛之机场客流量的时空分布预测赛复赛终于完结!12月14日,top5的队伍将前往华南理工大学进行答辩。而比赛过程中,我们发现了这样一位选手。作为开发工程师,他是这样走上机器学习之路的……


字节,开发工程师,毕业于浙江大学。在涂子沛老师的介绍下,他成为了一名天池选手,并在广东航空大数据创新大赛之机场客流量的时空分布预测中首次接触数据挖掘竞赛。 目前就职于观数科技,从事数据产品的后端开发工作,工作中主要使用的语言为Scala和Python。



(广东航空大数据创新大赛——机场客流量的时空分布预测复赛最终排行)


以下是他的比赛历程自述


国庆节前后,公司小伙伴给我推荐了个传说中的天池机器学习算法大赛,说要参加下试试。作为一名名声在外的机器学习叶公好龙宗师,我内心一开始是拒绝的……妈蛋我也就上了几个课会调用调用MLlib的水平啊,这怎么突然就要来真枪实弹了,还以公司名义组了个队,这有点虚……正好那阵子业务开发也比较忙,就一直搁置着……


转眼到了10月中旬,正好有个下午无心干活,又想起了这个比赛,反正新手嘛,谁不是在被虐中成长起来的,要不就来天池划个水试试吧。说干就干,下载了数据,起了个Jupyter notebook,开始……学习pandas……


虽然之前没参加过比赛,不过上过几门课还是了解一些大致的流程。首先看下比赛提供的原始数据,主要就是5张表:

  • 机场中700多个WIFI AP点每分钟的详细连接数。这个也是最后需要预测的值。

  • 机场每天的航班排班表,其中有航班号,预定起飞时间和实际起飞时间。里面有不少缺失值。

  • 机场所有登记口和机场区域的关联表。WIFI AP的Tag上有机场区域信息,如E1, W1, T1, EC之类,而航班表里都是登机口比如B225,这个表就是用来做关联的。

  • 机场每天的乘客checkin记录表,包括航班号,起飞时间和checkin时间。根据我自己坐飞机的经验,这个应该指的是值机?感觉值机时人不一定要在机场,而且数据本身也有很多缺失。

  • 机场每天的乘客安检记录表,同样包含了航班号,安检时间。这个感觉会靠谱一些,虽然同样数据也有很多缺失。两张乘客表里的乘客ID也都有提供,不过两个表用的ID体系不同,无法关联。试着distinct了一下发现ID没有重复的,也就是说无法通过ID来确定某个乘客,基本就是无用的信息。


有了原始数据,就开始搞探索性分析。嗯,看看咋导入数据,要读取csv嘛……pandas.read_csv就可以了!果然简单!(省略各种pandas库方法的各种google搜索学习……)然后查看下数据质量啦(有没有缺失值异常值),画画图看看有啥分布规律啦,看看统计关联度啦等等……这块是我的弱项,可能因为本身数学功底比较差,对于画图也不是很有sense,所以也没有什么特别的发现。第一天基本就在pandas和matplotlib的基本使用学习中度过了。晚上试着跑了个平均值,作为第一次预测结果提交了。

10月15号


第一次结果揭晓,竟然排到了200名以内!(当时总参赛队伍有2000多)简直不敢相信……搞个平均值就能进10%,这比赛真是对新手太友好了……

10月16号


继续学习pandas,做了些其它的分析比如乘客一般会在预定起飞时间前多久来机场过安检,飞机的平均延误情况如何,机场每天的航班排布是不是比较接近,然后略微改进了下简单的平均,做了下花式加权平均,进行了第二次提交。然后就冲到了100名附近。感觉自己势不可挡木哈哈……


10月17号


既然平均效果都这么好了,那要不试试ARIMA之类的经典时序预测?又学了下statsmodels库,看了下ARIMA模型需要序列stationary……好吧那做下一阶差分。然后模型拟合需要设置auto-regressive和moving-average的参数,这有点懵逼……随便瞎猜了下可能的回归周期,发现这个跑起来又慢效果也不怎么好,可能更适合长期粗粒度时间序列的预测吧……所以也就暂时没有采用。不过移动平滑这个好像是个不错的主意,继续加入到原先的加权平均模型中,做了第三次提交,貌似名次没什么变化……

10月18号


这天好像是换了数据,初赛只剩下最后6次提交了……这天花了非常多的时间,看了好些Kaggle winner's solution,开始上模型了!(后来才知道我之前用的那些平均之类的方法被大家称之为“规则”,很多情况下规则方法就可以达到不错的成绩了)添加了航班数量的feature,加上之前的时间点平均,移动平均,一阶差分等等,用sklearn搞了个GBRT模型!离线验证下效果也不错,信心满满进行提交!果然成绩一出,冲到了第6名……当时的感觉就是,一个能打的都没有啊!(摇手指

10月19号


这天继续疯狂地学习着各种比赛经验,以一种王者的姿态哈哈哈,把玩我的模型们。唔,原来随机森林这种bagging为基础的ensemble方法是主要降低variance的,所以每棵树的深度不能太小,否则bias会过大……而gradient boosting主要降低bias,所以每棵树不能太深太细……唔,原来做模型融合不只有简单的加权平均,还可以在模型基础上做stacking……期间借鉴了很多Kaggle前辈们在github和Kaggle kernels上的代码,不得不表示Kaggle的分享氛围真的是非常好啊!像我这样一次参赛的新手也瞬间变得一招一式有板有眼起来……不过当天提交后,成绩反而大幅下降……妈蛋,我是不是拿错剧本了……


10月20号

此时的我已经杀红了眼,前一天肯定是under fit了!于是我开启狂暴模式,除了自己本本还用了几台公司的虚拟机进行并发模型超参数grid search。这里犯了不少错误,比如很多时候特征工程,数据清洗之类的要远比复杂的模型重要,有了基本模型之后花太多时间做超参数搜索其实也是非常浪费时间,而且数据量(应该做一下down sampling)和模型复杂度上去之后,跑一个简单的cross validation都需要几个小时,而提升很可能并不大。最要命的是,真正比赛时的cross validation方法其实是很讲究的,而我只是很傻很天真地使用了random split……结果就是凄惨的over fit,离线效果很好,上线效果傻逼。这还不是最悲催的,那天几乎是通宵作战,到起床收训练结果的时候才发现,模型预测时需要依赖前几个时间点的数据,而在预测集里面这些值都是未知的,必须得边跑预测边把预测值填进去进行下一个点的预测,这些feature的权重还都相当高。早上6点多发现问题,7点多改完程序后一直跑到10点(每天系统评分的时间点)结果还是没有出来。所以那天就相当于提交了个全0的结果,浪费了一次宝贵的验证机会……

10月21号


倒数第三天了,我终于静下心来思考整理了下战术,一条战线是完善之前的树模型,用上xgboost(这货比sklearn带的GBRT快了不止一点点,果然是大杀器)跟random forest和extra trees做混合,用一个2-fold stacking,第二层采用线性回归。然后超参数调优也学乖了点,用上了效率更高一些的bayersian optimization 。Feature方面完善了下时间(数据中包含了中秋节,做了点特殊处理),ap点位置等信息,pandas的get_dummies做one hot encoding相当清爽,一行代码搞定。提交完之后成绩终于止血回升,不过名次还是在40名左右。(由于提交次数有限,还有很多想法没法在比赛中验证。赛后对这条战线做了些进一步的优化,将第一次几个模型的预测结果作为feature加入到原来的训练数据中来做第二层的模型训练和预测,最终成绩可以排进前20。)

10月22号


10月22号,换了条战线,打算对ap点做下归类,看了下貌似有Dynamic Time Wrapping做时间序列的距离函数效果不错,结合KMeans做clustering,然后用xgboost里拿到的权重比较高的几个feature,对几个cluster分别建线性模型来做预测。Validation方法也改成尽量跟线上一致的预测一段连续时间的值。尝试了下L1,L2模型正则化,混合一下做了提交。这天的结果到了12名。(看我的语气,简直风淡云轻!)

10月23号

最后一天了,进复赛应该很稳,心态也更加平和了……这天也是进入倒计时后难得的早早地在晚上9点就提交结果了,其它几天基本都是晚上通宵跑模型,早上6,7点起来看结果,做提交。这天主要是看了下各天数据的相关度,果断去掉了前面一大段的时间,只用最后一周的数据来做训练。然后用elastic net来替代之前的手动L1,L2混合,略微调整了下超参数,就提交了。


10月24号


最终截止日,我都没有去看成绩,还是微信上同事告诉我说最后冲到了第5名。应该还是有很大的运气成分……




(观数科技第一赛季排名)


第一赛季就这么结束了,虽然是后半程才加入,不过基本上每天都是如饥似渴地学习新知识,边跑模型,边看文章,跑完一轮再加点新调整,机器学习,我也学习……慢慢地也掌握了不少新技术,对数据竞赛也算有了些感性认识。其中走了不少弯路,尤其是一个人参赛,很容易思路僵化,走到“局部最优”点上去,怎么调都没提高……这个时候就要果断切换思路,好好做数据探索,可视化分析,特征提取。放到真实应用场景中,对业务本身的理解绝对是最重要的……对于大多数的问题,模型再高大上再复杂可能也只是微量的提升,但付出的训练,预测的时间代价都是相当大的,可能这也是为什么Netflix当年并没有采用大赛冠军的算法的原因之一吧。反观数据质量,业务特征这些往往是能拉开很大差距的地方。


当然,这些结论都是在不了解深度学习的我看来如此的……在比赛过程中我经常感觉我做的很多人肉工作比如特征选取完全可以由auto-encoder来替代,而不断提交结果不断改进模型的行为,也像极了一个SGD优化过程。我还在寻找自己作为一个人类的独有价值所在……


附几个当时看到的不错的学习资源:


某Kaggle大神的参赛示范代码:

https://github.com/ChenglongChen/Kaggle_CrowdFlower

Kaggle某次类似时间序列预测比赛的赛后分享和讨论:

https://www.kaggle.com/c/walmart-recruiting-store-sales-forecasting/forums/t/8023/thank-you-and-2-rank-model

Phunter大神分享的比赛脚本模板:

https://www.kaggle.com/phunter/flavours-of-physics/gridsearchcv-with-feature-in-xgboost/code

来自北大的著名天池选手的github(初赛第二名)

https://github.com/wepe

跟上面的大牛一起组队的另一只大牛的博客:

http://blog.csdn.net/bryan__/article/details/50977513

ensemble必读:

http://mlwave.com/kaggle-ensembling-guide/

xgboost调参指南:

https://www.analyticsvidhya.com/blog/2016/03/complete-guide-parameter-tuning-xgboost-with-codes-python/

复旦小鲜肉的Kaggle比赛指南:

https://dnc1994.com/2016/04/rank-10-percent-in-first-kaggle-competition/


在整个过程中向各位天池比赛前辈学习到了很多,在面对真实的大数据问题时应该如何分析处理也有了一些宝贵的实战经验。写这篇文章主要是做一下简单的比赛总结,抛砖引玉,希望能看到真正的大牛的比赛分享,共同学习进步。


至于第二赛季的经历,请持续在天池小报上等待我的更新哦:)


  读完点个赞呗!