专访|今日头条2016 Byte Cup大赛实战经验分享
机器之心原创
作者:杜夏德
本次比赛的任务是建立模型,将头条问答中普通用户的问题更快更好地推送给专家。与以往比赛不同的是,这次比赛所用数据来自于头条问答真实的用户数据。
颁奖仪式结束后,机器之心对这三支得胜队伍代表成员进行了独家专访,分享了比赛过程中的心得。他们分别是西电战队的郭正肖和郝磊,天穹队的钱乾与 BrickMover 队的庞亮。
学科背景:
庞亮:deep leaning 文本匹配
郭正肖:计算机图形学
郝磊:通信网络
钱乾:数据挖掘工程
首先我们来看看这三支队伍的所用模型和比赛思路
第三名西电战队
他们使用的是 FM 算法,并从算法、协同过滤和模型融合三个方面进行考虑。据该队成员介绍,使用 FM 算法有两个考虑,首先是用一系列因变量模型特征之间的关系,更容易发现特征之间的隐藏,适用于解决推荐系统的问题,二是 FM 算法具有线性,时间复杂度低,运行速度较快。在模型融合上,他们选择 FM 算法预测结果协同过滤算法结果经过加权作为最终的结果。
第二名:天穹战队
第二名的选择算法的过程有些曲折。他们首先考虑了 SVD 与 SVD++模型。在验证了 SVD 对这个问题的效果之后,开始尝试用一个比较通用的 FM 算法来处理这个矩阵的分解问题,并在比赛后期为了满足自定义优化需求,重新实现了 fm 并在优化方法上做了修正,使得预测效果得到很大的提升。
第一名:BrickMover
他们在比赛的前半段都是在设计一个单模型,提升单模型的效果,后半段利用 Blendling 进行模型融合的。具体过程请看下图:
以下是专访内容
机器之心:比赛前你们对自己有什么预期?
郭正肖:我是属于跟着我的队友一起参加比赛。我自己也算是半路出家,实力并不强。我周围的同学都在看这方面的书,没有实践,但我的朋友告诉我可能参加比赛会更有好处。当时我就想参加什么样的比赛比较好?我发现这次比赛进度拉的比较长,从 8 月到 11 月一共是 3 个多月,时间一长我就能对这个比赛有更多的了解,学到更多的东西。当然我也是抱有一些小幻想的,能拿个奖什么的。在比赛过程中,我的两个队友给了我很大的帮助。
庞亮:我当时看了一下这个比赛的数据,与推荐系统相关的。其实与我的领域不是很相关。但是举办方给的数据是文本数据也是个匹配问题。所以最初的想法就是试一下我自己的模型能不能在比赛上 work 一下。我的模型就是那个 Match-SRNN。然后在做的过程中对这个数据有了更多的了解后,又试了一下其他的模型,因为要做一下 Baseline 和 SRNN 的比较。
钱乾:我一开始是跟着我朋友一起来做的,他想用 deep learning 的方法去做到。一开始我也是想能不能不用 deep learning 的方法也能把分数做上去。做着做着就越来越对 FM 这个模型感兴趣,最后用自己的代码去实现了一个自己写的 FM 模型。也算是一个学习的过程和一个验证的过程。然后还是要测试一下将图模型这种东西用在推荐领域上是否可行?那么最终验证出来也是可以接受的。这个基本上也是我的一个初衷吧
机器之心:那你(钱乾)对 FM 这个模型在这次比赛中的表现满意吗?
钱乾:我后来对比了一下自己写的 FM 与 C++写的 FM,在优化以后能够达到与原本用 C++写的 FM 能达到同样的一个精度吧。
机器之心:在参加比赛的三四个月的过程中,有没有一个关键的节点让你们觉得自己的模型有了很大的提升,有信心拿下这个比赛?
钱乾:有两次吧。第一次可能就是尝试使用了 neighbor 的一些数据。并且通过分析之后加了一些 IDF 的一些加权,这个给我的模型带来了一个很大的提升。这是第一个关键点。
第二个关键点是,在我采用 deepwalk 这个算法构建特征以后使用树模型,它也给我的模型带来的提升。
庞亮:我一开始是实现了一个 baseline,一个最基础的矩阵分解模型。发现效果挺不错,基本上可以进前 50 了。后面有提升的地方也是和他一样,加了一些 neighbor 的信息,就是一些 implicit 的 feedback,再加上两边的 implicit feedback,就是这样一点点提升上去的。在精简模型的方面用上一些非对称思路,让模型更加鲁棒。还有原来的 SVD++是不对称一种结构,然后就想怎么能把它变成一个对称的一个结构。
机器之心:ASVD++这个算法是你们自己提出来的吗?
庞亮:是的,但不是这一次比赛提出来的。之前在百度的推荐大赛上就使用过,发现它很有效果。这一次是把一部分的 ID 去掉之后,这是新的。
用完 blending 之后,我们又尝试了别的模型,想看看它效果怎么样,不仅仅是为了刷分。比较每一个算法的优劣。
机器之心:这次比赛中有没有对自己不太满意的地方?
庞亮:可能是数据上吧,隐藏掉了一些词的信息,虽然在数据量上的 entry 很多,词表也很大,很多时候我们没法用上我们已经训练好的 word-embeding 信息,这样就导致我直接拿它来用的话会有一些困难,性能上会有损失。但是我相信在文本上挖掘的信息是很有用的。但这次比赛都是用 ID 拿出来的,我们没法 pretrain 这些 ID 的 Word
钱乾:我们就用了一张表,也是没有用上。
(笔者注:据主办方介绍,所给数据本来应该是一个自然语言,但是主要考虑到有一些国外的参赛选手对中文并不熟悉,把文字进行 ID 化的处理,首先进行分词,每个词会有一个 ID,这是唯一标识,对每一字也给了一个 VID,用这种形式作为问题的表征)
庞亮:我们都是希望能把这些信息用全,每个信息都能带来一点提升,然后对比一下每个信息的提升。这一点比较遗憾。
机器之心你们的参赛经验是怎样的?
郝磊:我参加的比较少,也就三四次吧。
钱乾:我一般就参加 kaggle 吧,有六七次的经验。
机器之心:能分享一些比赛经验吗?
图:第二名天穹战队代表钱乾
钱乾:就我个人来说,一开始参加比赛不要特别急躁,不要一上手做到一定程度就想着要去做融合 ensemble,一开始就是要把数据看得特别清楚,到底这些数据代表了什么,隐藏了什么价值,包括怎么去做一些特征工程上的东西。这些东西有时候是需要灵感,但有时候通过一定的分析手段是能看出来的。比赛时一定要先弄清这些事情再去考虑后续的一些步骤。
庞亮:比赛就是一个兴趣吧,有时间就可以参加。借着比赛去实现自己的 Idea,看看它们的表现到底怎么样。而且只有在快结束的时候可能会比较忙,前面的过程不会占用你太多时间。
钱乾:我们做到一定程度以后就没有再动过了。
机器之心:请问第一名从始至终的思路是什么样的?你们是怎么思考问题的?
图:第一名 BrickMover 队代表庞亮
庞亮:我们第一个思路是把传统的模型先做一遍,我们试过 XGBoost 与 FM、还有 SVDfeature 这三个的对比,发现这个问题本身就是一个传统的推荐问题,像 XGBoost 这些都不奏效。然后我们就往那个方向走,你就要去改进模型本身。因为常用的模型大家都有,你能做到,别人也能做到,你能调参,别人也能调参,所以你就要深入到模型本身上去挖掘它剩下的一些信息,然后根据你挖掘到的东西来进行改进,比如说 SVD++,这个是已经成型的模型,你发现 SVD++本身很有效果,那就再继续往下挖嘛。我们有三个人嘛,每个人都有自己的分工,我这边是调理参数和 SVD++这一块,有一个同学是负责挖新的模型,比如说 deep learning 方面的模型,他会去搜索新的 paper,如果有源码实现的最好,如果没有,就 balance 一下,看看最后实现起来怎么样,如果太复杂就放弃了。还有一个同学专门攻 blending 这一块,做几个模型的融合。
不过他也是后面才做的 Blending,之前也在调整 SVDfeature 这块,我自己还试了一下新的模型。
郝磊:你们的模型融合是怎么融合的?
庞亮:我们把所有的分数拿来融合一下,就是结果融合,也就是线性模型嘛。然后用了 cross validation。
整体的思路有几个步骤:首先是分析数据,数据拿来之后,你需要把所有的分布都了解一遍,包括内部分布和特征分布。在专业一点就是你要画出两两 feature 之间的相关性。第二就是把不必要的 feature 和 item 给去掉,做好数据清洗工作。清洗完之后再用模型。先用基础模型,看一下效果,再用复杂的模型,再比较一下这两个模型的差异到底有多大。如果复杂模型表现不好就没必要用它了,直接在基础模型上加 feature 就可以了,这样你只要做 feature engineering 就可以了,完了之后就是 blending。
机器之心比赛过程中专业给你们带来了哪些帮助?
钱乾:对我来说就是编写代码的能力。像 SVD SVD++ MIF 我们都试验了一下,但是没有现成的模型,我们就必须从头开始,把这些东西写下来,还是比较考验编程功底的。
郭正肖:我没有太多,就是一些基础的线性代数。我学的是图形学,对向量的理解会有些不同,我考虑的是空间上的。而且我是计算机技术背景,更多偏向工程。但是参加完比赛之后有了经验就知道要多去看 paper,看看别人是怎么做的。
第三名西电战队代表郭正肖(中)
庞亮:我是学深度学习文本匹配的,在实验室做一些调参建模工作都会培养出对数据的敏感。有了数据敏感性,看一下这个数据的分布大概就知道它的分布了。