标签 Kaggle 下的文章

使用Kaggle的步骤

我在参与新类型Kaggle竞赛时采用的步骤如下,在赛程一半的时候进入(很多图像类竞赛没办法用Kernel跑完,可以在Discussion里找github上的代码,或者直接上github搜baseline代码,用谷歌搜比赛名也会出来不少github代码)。

  1. 仔细阅读Overview和Data中的内容。

  2. 下载数据后,对Kernels分数排序,优先查看分数高的和票数高的,如果某个Kernel是fork别人的,先看源头,选择几个采用不同方法的代码复制下来跑,感受下运行时间和效果。

  3. 按照方法名称搜原理,基本看懂这个方法的用途、优缺点、有哪些参数影响较大。

  4. 查看该方法的文档,对照着手上的代码看懂,然后把文档看几遍,里面会有少量技巧和调参方法,然后搜一下他人对参数的理解。

  5. 手工调参,看时间和效果的变化(本地和提交的差距)。

  6. 查看Kernels中的EDA,增加对这些数据的感受,大概记一下数据的分布、范围、意义。

  7. 查看Kernels中fork别人然后改进的代码,找一下哪里的代码变了,分析一下为什么好,是否会过拟合。

  8. 尝试自己想一些预处理方法,或者是特征工程,看效果。

  9. 然后再手工调参,注意观察Discussion里大家的讨论,有时候会有一些灵感,也可以直接根据提示写代码执行。

  10. 在觉得排名还可以时,可以使用多折平均,分数一般都会好一些,而且减少过拟合的概率。

  11. 调参可以使用Grid或者Bayesian Optimization。

  12. 使用不同方法得到相似分数的结果进行平均,通常分数可以高一截。

  13. 尝试stacking,方式很多,有时会过拟合,处理得好可以提高非常多,融合多个方法,多层stacking。

  14. 手工平均可以根据验证集的分数选择合适的权重,也可以根据测试集分数选择权重。注意在选择哪些结果进行平均时,可以计算一下相关系数corr,选择相关系数小并且在测试集表现不错的结果进行平均。

  15. 有些情况下伪标签效果不错。

  16. 选择最终的两个提交很重要,如果测试数据非常多,分布也很均匀(比如正例只有1%就是不均匀),基本上可以尽情过拟合。根据一定逻辑进行后处理风险很大。小测试数据对stacking很敏感,不过直接平均的方法在小数据上一般都还行。

  17. 可以看到这里用的很多方法,在工作环境中是没有的,我猜测优化单模型是主流,而且我在参与过程中花时间最多的也是优化单模型,融合水平很低。如何根据Kaggle中学到的知识解决实际问题,是我非常想知道的。

机器学习路径

我接触机器学习的入门书籍是:《机器学习实践指南:案例应用解析》,在这本书上学了python和R的基本语法,还有少量机器学习基础知识。然后是在学校图书馆借了几本AI相关书籍,这些书的最后一章是介绍决策树的,都比较老,具体是哪些书已经找不到了,看完就搁置了一段时间。

再次看机器学习是从Andrew Ng的视频开始,顺便看了台大林轩田机器学习基石的视频,看得云里雾里,顺便翻了一下李航的统计学习方法,无法确定看懂了多少,然后又搁置了很久。

再次看机器学习相关是第一次偶然看到CNN的时候,顺便了解了相关知识,比如CNN原理,用Keras框架CNN进行图像分类,看了很多遍Keras文档,使用预训练模型等。发现R-CNN、Fast R-CNN、Faster R-CNN系列,做了一个Faster R-CNN Caffe版本的PyQt5可视化界面,可以训练、测试、查看每张图像的标注和识别结果,然后又搁置了一段时间。

再次看机器学习相关是参加Kaggle竞赛,第一个参加的竞赛可以不用机器学习,可以转化为最小费用最大流,是在论坛里面学到的,学到之前是采用暴力搜索加优化做的。接下来做了很久的Kaggle竞赛,比如第一个图像分类的竞赛,当时写了一个融合常见预训练模型的框架,可惜那时候除了全连接层的参数都冻结了,试了各种预处理方法,统统效果很差。在接下来的图像分类竞赛,学到了Random Crop,多进程预处理,类别平衡,Test Time Augmentation等方法,离顶尖队伍还有很大的距离,想要提高技巧得查看很多图像竞赛的前几名的解题思路,例如模型的修改和损失函数自定义可能也会有用。然后是一个比较少见的文字分类的竞赛,学习方法就是Kernels里面他人的代码和Discussion里他人提到的思路,需要研究一些预处理的方法,还有word2vec,预训练词向量模型和训练词向量的方法,SpatialDropout1D、BiLSTM、BiGRU,N-Fold平均。

这里有个问题是我比较好奇的,就是假设我自己得到一个还可以的结果,但是公开的Kernels里也有一些还不错的结果,他采用的方法和我不同,分数差不多,这种情况只要和他平均,就可以得到更高的分数,而且过拟合的概率也很小。从规则上来说,这是允许的,私下分享但不组队才是违反规则。假设某人A凭借融合公开的结果,得到某个分数,某人只靠自己得到和A相同的分数,另外一个团队分工合作使用各个方法得到和A相同的分数,这三种情况的数量不同会导致成绩的含金量不同,不过一般公开的结果最终都不会进前10%,据我猜测使用公开Kernel的情况是比较普遍的,不过事实是怎样呢?

在一个竞赛里体验了一下Mask R-CNN,顺便体验了一下2阶段比赛的风险,1阶段小测试集,结束时要上传代码,然后发放大测试集,1星期后2阶段结束。假设在1阶段时经验不足,一味提高分数,没有考虑测试集变化的一些情况(图像尺寸、识别目标大小、图像颜色分布等等),就有可能跌落几百名。

在一个竞赛里发现了LightGBM和它的前身,曾经我以为很弱的决策树竟然可以这么强。文档里参数好多,数据集好大,作为新手依然在公开Kernels里学会了不少东西。可惜有人在最后12小时发布了一个分数和我差不多的Kernel,然后有人用它和一些公开Kernels融合了一下发布了,分数就比我高了一些,导致排名下降了300名,嘿嘿这次我就没有融合公开Kernel,所以说邪恶无法阻止,除非能碾压邪恶。

到这里基本上常见比赛都见过了,后面看到的比赛很多都可以直接用以前的代码来跑了,不过还是有一些新型的比赛出没。比如一个可以用DBSCAN的比赛,预测粒子轨迹,我一开始看到这个比赛的时候第一反应就是不做这个比赛,可惜有一些多余的时间,我就看了它好几次,作为学习聚类的一个途径了解一下,这题的最优解不是聚类。大概就是瞎构造一些已有变量的组合,用贝叶斯优化找线性组合的参数,有时手工调整一下参数看看效果,多看Discussion找方法,时间不多,自己没想出什么思路。还有比如说目标检测的竞赛,刚好是个大数据集,谷歌还提供了一笔赠金跑谷歌云,体验了一下多卡训练的感觉。

我总觉得我在面临重要选择的时候,都会做出错误的决定,就比如说我两个月多前面临做一些准备去找工作的问题,当时有一些备选:1.打比赛得好成绩去找,2.刷leetcode中等难度的题,3.用以前学过的知识做一个靠谱小应用,4.复习和学习机器学习基本知识。只能说我水平确实有限,基础知识不牢,没有办法取得前十的成绩,表面Kaggle银牌已经没啥用了,硬实力才是关键,似乎现在大家要求都挺高。我花了10天去试了一下天池的比赛,感觉有一批人很强,不过实际认真参与的大概是300人,说明很多人不需要参加竞赛,直接就可以去实际应用,想靠竞赛找到工作得进天池决赛。很多公司喜欢考算法题,听说leetcode刷完中等难度就行,可惜我没有选择全刷leetcode,这应该就是一个错误,leetcode我只试了前50题中等难度的,不参考资料会45题,间隔的做花了10天,不过不是一整天都在刷,比较难的一些知识我现在肯定不会,如果多刷一些可能才能看到更多的不足,补完应该会强一些。想做一个完整的小应用至少得花1个月,风险不小,做了不够好人家肯定看不上。机器学习基础知识感觉挺难,想在短时间内灌输进去也不知道有没有用,不过这些基础知识学起来挺快的,暂时不清楚学会了有多大用,可惜了少了论文的积累,估计只能做一些边角的工作。