2014年是阿里巴巴集团移动电商业务快速发展的一年,例如2014双11大促中移动端成交占比达到42.6%,超过240亿元。相比PC时代,移动端网络的访问是随时随地的,具有更丰富的场景数据,比如用户的位置信息、用户访问的时间规律等。
本次大赛以阿里巴巴移动电商平台的真实用户-商品行为数据为基础,同时提供移动时代特有的位置信息,而参赛队伍则需要通过大数据和算法构面向建移动电子商务的商品推荐模型。希望参赛队伍能够挖掘数据背后丰富的内涵,为移动用户在合适的时间、合适的地点精准推荐合适的内容。
比赛网址:http://tianchi.aliyun.com/competition/introduction.htm?spm=5176.100066.333.9.SCMy5t&raceId=1
第一次参赛,比赛成绩不好,都不好意思贴出来,但是为了留作纪念,说不定以后还能回味一番,遥想当年参赛的种种苦B回忆,还是把成绩贴出来…
说到阿里的比赛,去年我就有听说,当时实验的一个小伙伴(后来成了今年这次比赛我的队友)兴致勃勃的向我介绍了阿里的比赛,当时听起来感觉很高大上,但是还不敢参加比赛,原因是当时我还只是看了一部分Andrew Ng的机器学习视频,算是对机器学习有了一个初步的了解,断不敢贸然参加如此高大上的比赛。所以第一次与阿里比赛的邂逅到此为止,后来小伙伴和其他人组队参加比赛了,而我暗自下决心来年无论如何也要参加比赛。今年依然在小伙伴的鼓舞下,我决定参加比赛。经过三个多月的厮杀,我们的成绩停留在113名。这个名次对我们来说有一些失望,作为对数据挖掘领域的第一次尝试,虽有遗憾,但是对我个人来说还是有很大意义的。也是因为名次的原因,加之三个月的比赛历程,让我多少失去了写比赛总结的勇气。后来,我看了队友写的一篇总结,感觉很受触动,同时也很感动,感动的是在比赛中他的不离不弃,坚持到最后。另一个原因是找工作的需要,自己对机器学习方面有浓厚的兴趣,想要在将来从事一些与数据挖掘相关的工作。本人的硕士研究方向跟机器学习关系不大,也没有做过相关的项目,所以这次比赛的经历是唯一与我想要从事的工作关系最大的一件事。基于以上两点,我又重新拾起写比赛总结的勇气。这里是我的队友写的总结,着重记录了当时比赛的感受,现在看看还能回味无穷,连接是:https://www.zybuluo.com/frank-shaw/note/123193。鉴于我的队友已经对比赛做了一部分总结,我主要从技术的角度来写这次比赛的总结。
CSDN中有一篇文章总结了去年阿里比赛前十支(部分队伍)的解题思路,文章的连接是http://www.csdn.net/article/2014-08-27/2821403-the-top-9-of-ali-bigdata-competition/8。他们中有的队伍的做法很新颖也很独到,而我和我的队友在机器学习方面的经验并不是太丰富,因此选择了与一般人一致的做法,即把这个问题看成是一个二分类问题,目标天里面有购买行为就标记为正样本,否则就是负样本。我们需要根据用户以前的行为预测目标天他是否会有购买行为。
由于我们拿到的数据是原始数据,里面有很多噪声数据,因此第一步需要做数据清洗,清理掉无用的数据,用干净的数据做预测。第一赛季的数据量很少,只有10000个用户的5000万条数据,可以在本地计算机上做预测。第二赛季数据量是56亿条,500万个用户,1243万个商品(商品子集),只能在阿里云的御膳房平台上进行,我们的数据清洗策略是:去掉不在商品子集中商品的数据,去掉浏览量大于5000但是购买量小于20的用户,去掉只有购买行为的用户,去掉只在双12浏览、购买的用户,去掉只在双12被浏览、被购买的商品。去掉只有购买行为的用户,是因为这部分数据是缺失的数据(其他行为可能发生在PC上,移动端并没有记录)。因为原始数据中包含双12当天的数据,通过数据统计,我们发现双12当天的4种行为量明显高于其他天的行为量,呈现一个尖峰状,如下图所示。因此我们需要去掉那些只在促销当天才有浏览和购买行为的用户,以及因为促销才被浏览和被购买的商品。经过处理之后,剩余4158006个用户,3亿3千万条用户数据和132万个商品(商品子集)。
尽管经过处理之后,双12当天的尖峰依然很明显,从上图可以看出(图片中的数据是经过数据清洗后的数据)。因此我们曾经花了很多时间(几乎一个月)在想办法将双12的尖峰平滑掉,具体的做法是在当天的行为次数上乘以一个衰减系数,使双12当天的4种行为次数与其他天的平均水平相当,但是从最后的测试结果来看,并没有太大的帮助,这是这次比赛给我们留下的最大的教训之一。我们之所以花大量的时间在处理双12的数据上,是因为我们是以7天为一个时间单位来构建样本的(原因在后面有解释),我们想要突破这个7天的限制,充分利用数据,但是事与愿违,血淋淋的教训。
在数据分析的基础上,我们可以很明显的看出双12当天的数据波动很大,可能对模型有很大影响,因此我们一直是避开双12来构建训练集和测试集。双12之后有12月13~12月18日总共6天的数据,这些数据可以用来提取特征,作为线上预测集,在这个数据集上的预测结果便是最终提交的结果。因此,自然而然我们选择以7天(前6天用来提取特征,用第7天的数据来标记正负样本)为一个时间单位来构建样本,这样我们可以构建很多样本,实际上我们总共构建了8个样本,将前3个merge起来用来作为训练集,剩余四个中选一个作为测试集,最后一个样本(12月13~12月18日)用来作为线上预测集。一般来说,我们需要至少两个测试集来验证模型是否会发生过拟合,当模型在两个测试集上的测试结果接近时,产生过拟合的可能性越小。实际上,在第一赛季的时候,我们也是这样做的,4个样本merge起来作为训练集,两个样本用作测试集。但是到第二赛季的时候,御膳房的速度实在太慢了,因为比赛的数据量很大,资源严重不够用,所以我们没有更多的时间在两个测试集上做预测,这里可能存在一些问题。
特征提取在这次比赛中应该是最重要的部分,因为无论是第一赛季还是第二赛季,我们都可以用现成的机器学习工具,这些工具中都包含有常用的机器学习算法,因此特征好不好直接影响到比赛的成绩。第一赛季我们用到了libsvm中的SVM算法,scikit-learn中的Logistic Regression和Random Forest算法。第一赛季,据说用模型做比赛可能没有比用规则做比赛更有效果,这个也是第一赛季结束的时候我们才看到交流群中有人在讨论这方面的问题。当然,好的规则可以转化为特征。第二赛季用规则效果就不明显了,因为数据量很大,模型才能预测的更为准确。当时御膳房的平台还不是很完善,能用的算法有LR,线性SVM,RF和GBDT,这些模型我们都有尝试过,而且每一种模型在不同的正负样本比下的预测能力也有差别(LR的最佳正负样本比是1:11,GBDT的最佳正负样本比是1:9)。这些模型中GBDT的效果最为明显,但是缺点是训练速度很慢,模型参数太多。去年比赛的第一名基于ODPS实现了神经网络算法,确实很厉害,今天的参赛队伍,我还没看到用Mapreduce实现其他的算法,后续如果看到再来更新。另外一个问题是正负样本不平衡问题,我们的样本中正样本数是4万多,负样本数是2300万左右,正负比超过1:500。因此必须对负样本进行随机采样(欠采样),也可以对正样本过采样(直接复制一份正样本,以增加正样本数)。在比赛结束以后,我看见有一支队伍在写总结的时候说他们的做法是用商品全集中的数据训练模型,这样正样本不至于太少,而且他们最后的排名很靠前,貌似在首页,这个地方值得我们借鉴,因为我们的正样本太少,拿商品全集中的数据训练也许会有更好的成绩。
第一赛季的时候,我们的特征主要是自己构思想出来的,包括最直观的行为次数特征,转化率特征(次数转化率),时间序列的统计量特征(最大最小行为时间,均值,方差,偏度,斜度),主要包含三大类,即UI对特征、用户特征和商品特征,第一赛季我们并没有考虑地理位置,因为数据量较少,大部分数据缺失,所以我们没有把精力放在这上面。第一赛季快结束的时候,也就是结束前一天,我们用40多维特征,用RF模型得到做好的成绩,顺利的进入第二赛季。
第二赛季才是真正的实力较量,因为参赛队伍都很厉害。我们参考去年一些参赛队伍的一些经验,将我们的特征扩展到了将近500维。分为4类特征:UI对特征,用户特征,商品特征和类目特征。这四类特征在粒度上又分为:天粒度特征,半天粒度特征,小时粒度特征和行为统计特征。天粒度特征主要有:最后一天、最后两天、最后三天的行为量以及转化率特征,行为天数在总天数的比例,行为天数除以购买天数,平均每天的行为次数。半天粒度的特征包括行为总半天数占总行为半天数的比例。小时粒度特征包括:最大最小行为时刻,行为时间平均跨度,行为时间方差。行为统计特征包括:行为次数,行为标志位特征(有过这种行为则为1,否则为0),行为次数占总行为次数比例,购买前的行为次数,购买前的平均行为天数,第一次购买前的行为次数,最后一次购买后的行为次数。我们还参考Marvel队伍对行为衰减做了曲线拟合(如下图所示),计算行为次数的时候乘以这个衰减系数。
当四大类特征中也有各自不同的部分,如UI对特征中与衰减因子相关的特征、第一次购买前的行为次数和最后一次购买后的行为次数是其他三类没有的特征。用户独有的特征是购买的商品总数、购买商品占总浏览商品的比例、购买商品的类目占总浏览类目的比例。商品独有的特征有购买次数超过1次的用户数、重复购买的用户数百分比。下图是我们在提取特征过程中用到的思维导图
在第二赛季后期,我们也考虑到要加入地理位置(用geohash编码的形式给出)特征。经过统计我们发现,在经过数据清理之后的数据中,只有802202条用户数据中用户和商品的地理位置都不缺失(总共3.3亿条用户数据),有地理位置的商品数是11705个(总共1058291个商品),因此可以说地理位置的信息非常稀疏。有27.9%的商品有两个以上的位置信息,有72.1%的商品只有一个位置信息。用户距离商品最远距离是19454192米,用户距离商品最近距离是0。商品的地理位置不唯一,因此我们不能确切的知道用户操作的商品在哪个位置(用户数据和商品数据是两个分开的文件,用户数据中只有用户的地理位置,商品数据中只有商品的位置)。最后我们提取的地理位置特征有:用户4中行为与商品的最近距离、最远距离、平均距离,所有行为与商品距离的平均距离,用户行为地理位置标志位特征(有地理位置则为1,否则为0),商品地理位置标志位特征(有地理位置则为1,否则为0),用户的平均活动范围,商品的平均分布范围。
在提取特征的过程中,我们可能也存在一个很严重的问题。我们一次性加入了很多特征,而并没有分批次的评估这些特征是否有用。比较正确的做法是一批一批的加特征,在加的过程中评估这些特征的重要性,去掉没有用的特征。在比赛的后期,我们也尝试了特征选择,去掉某一维特征看看效果如何,但是由于我们的特征有500多维,这样做非常耗时。并且在去特征的过程中,预测成绩跟参数有很大关系。我们有去掉一批特征看效果如何,但是通常调节模型参数之后,去掉和没去掉这些特征预测成绩并没有太大的波动。我也有尝试过用包含一棵树的随机森林来选择特征,因为有相关的研究表明越靠近树的根部的特征越重要,但是尝试过后效果依然不是很明显,可能的原因是随机森林存在一定的随机性,每一次训练都跟之前的结果有差异,不能保证两次训练结果完全一样。而且由于是在御膳房的平台上进行比赛,一般的模型评估方法如相关系数、皮尔逊系数法都很难实现,因此在特征选择方面我们确实做的不够好。
在比赛的后期,想要有很大的改变已经不可能,因为平台实在太卡,比赛的最后几天,甚至是一个简单的Sql查询都要相当长的时间。因此这个阶段只能在模型融合上轻微提升成绩。我们有试过单级模型融合,即用三种模型LR,RF和GBDT分别预测一个结果,然后取交集,也有试过投票的方式。我们也尝试过两级融合,即第一级用LR,第二级用LR,RF和GBDT。第一级的训练数据用前三个样本,用训练好的LR模型拿来预测另外的3个样本,将这3个样本的预测结果merge起来作为训练集分别训练第二级的3个模型,最后将这两级训练好的模型串联起来,形成一个串级的模型。
另外我们也尝试了不对数据做归一化处理,看看预测结果如何。我们也尝试了对训练集和测试集进行聚类,去掉小于总数1%的类中的实例,因为有相关的理论解释聚类可以去掉异常数据点。总之,我们尝试了一切可能的做法。
这次比赛中的教训:
[1] https://www.zybuluo.com/frank-shaw/note/123193
[2] http://www.noveltyday.com/?p=411
[3] http://weibo.com/p/1001603865213605651756
[4] http://wuchong.me/blog/2014/06/23/the-days-in-the-pit/
[5] http://tech.meituan.com/machinelearning-data-feature-process.html?utm_term=18410.cps.731895&utm_campaign=AffProg&urpid=18410.143874139831.731895.0&_rdt=1&source=wandie&utm_content=(none)&utm_source=(none)&utm_medium=wandie
[6] http://www.csdn.net/article/2014-08-27/2821403-the-top-9-of-ali-bigdata-competition/8
[7] http://chaoslog.com/te-zheng-xuan-ze.html
[8] http://blog.csdn.net/litoupu/article/details/38350157