阿里大数据比赛心得
~~~~~~····最终比赛还是结束了,想说研一一半的青春奉献给了阿里,最后艰难挤进了前五十,一路过来真心不easy,每天早上醒来的第一件事就是查成绩,三个月来天天如此,晚上熬夜提交预測,那样的日子想说爱你不easy。。。回想一路走来的艰难历程,回味当中的付出和收获,谨以此文献给一路走来一起奋斗的小伙伴,么么哒···~~~~~~
(一)初识阿里大数据比赛
一次偶然的机会,在去实验室的路上见到了阿里天猫推荐算法的比赛海报,对近来炒得非常火的大数据有非常浓的好奇心,点开报名网址,大数据比赛,便踏上了接近四个月的阿里竞赛之路。
比赛大概的描写叙述是:第一赛季阿里官方提供少量的某年4-15到8-15这段时间离线的天猫真实行为数据,參赛者利用机器学习的方法,预測8.15-9-15的用户购买情况,详细评分方式为:依据预測的正确率和召回率计算出调和平均得分来考量參赛者的成绩,例如以下图所看到的:
接触第一赛季的时候,比赛已经进行了半个多月,因为非CS出生,机器学习方面仅仅学习过皮毛,做过一两个实验。。。能够说经验匮乏,草草的和实验室队友组队了(草率的决定让自己后来说不出的心酸...无力吐槽),第一次胡乱的提交了一次成绩,第二天就有了成绩啦,看到了成绩以及排名,当时还有点小兴奋,尽管成绩不好,总算有个成绩啦。。。
接下来几天成绩都有小幅度上涨,详细的做法是利用学习过的逻辑回归LR和加一些简单的统计规则进行推荐,一些简单的规则有:利用用户对品牌的点击、购买、收藏、增加购物车这四种基本操作给品牌打分,将得分较高的品牌推荐给用户,做了半个多月,成绩一路上涨
最后还是稳稳的进入了前500名,得到了接触第二赛季的机会,赛季结束的时候,官方组织确定了终于的參赛队伍信息,第一赛季差点儿是一个人战斗的我,选择了又一次组队,和室友新组建了一个2人小队,心血来潮搞了个队名,,挤进第二赛季,当时定下的目标,冲击一百万,赢取白富美,出任CEO,走上人生巅峰,小小兴奋了一把(~纯属自娱自乐~)
(二)第二赛季“血拼”
休整了几天之后,阿里开放了第二赛季的天池大数据计算平台ODPS供參赛者使用,对于第一次接触大数据分析平台的我们来说,真是啥都不会。。。三个月的奋斗,我们组大概用了纯规则、LR、RF、GBRT四种方法,其它的一些SVM、贝叶斯等方法效果甚微,浅尝辄止。
2.1、SQL纯规则
第一时间打开了提供的ODPS用户手冊,看了简单的入门之后,就開始弄了,再次从0開始学习,这次提供的用户操作记录数比第一赛季高了几个数量级,达到了5亿的规模,直接依照手冊提供的sql语句加入的简单规则(给用户推荐热门的10个商品)进行了一次的提交,结果就有了成绩,小激动啊:
接下来的几天,依照第一赛季的流程,对数据进行预处理,删除未购买过品牌的用户记录(不删除近期一周才出现的新用户),删除未被购买过的品牌记录,删除疯狂点击可是从不购买的刷钻用户记录等,利用一些简单规则:定义热门品牌集合,交互时间记录统计,活跃用户集合,近期新出现的品牌集合,周期品牌集合,用户的品牌忠诚度,用户对品牌的操作加权打分等规则,每加一条规则,成绩都蹭蹭蹭往上涨(毕竟我们的baseline还非常低),幸福洋溢的感觉有木有:
提升了几天,丝毫没有察觉到规则带来的局限,依靠纯规则推荐,挖掘不出用户购买行为深层次的关系注定有提升上限,做了接近10天的规则成绩涨到3.9左右,无论怎么加入规则,我们的成绩也始终上涨不了了。
2.2、LR模型
考虑转到LR模型,要想利用模型训练,首先得在与处理之后的数据之上,划分好线上和线下数据集,參考阿里讨论群和BBS上面的数据集划分,因为题目是利用4个月交互数据预測第5个月购买,故我们线下也是将已知的四个月数据平均分为5部分,利用前4部分数据预測第5部分购买情况,构建的线下数据集和线上数据集详细为:
2.2.1、线下:
训练:筛选出4月15号到7月02号的有过交互记录的,而且在7月03号到7月21号发生购买的用户品牌对作为正样本,将4月15号到7月02号剩下的记录作为负样本,构建好特征后,训练到线下的LR模型;
预測:利用4-15号到7月21号的全部数据,构建好特征后,带入线下训练好的LR模型进行验证;
2.2.2、线上:
训练:筛选出4月15号到7月21号的有过交互记录的,而且在7月22号到8月15号发生购买的用户品牌对作为正样本,将4月15号到7月21号剩下的记录作为负样本,构建好特征后,训练到线上的LR模型;
预測:利用4-15号到8月15号的全部数据,构建好特征后,带入线上训练好的LR模型进行推荐;
数据集划分好后,我们组花了大量的时间构建特征,从三个角度出发,用户品牌交互特征类,用户特征类和品牌特征类,到第二赛季结束的时候,累计构建了715个特征(真的是一个比拼特诊构建的比赛了),仅仅罗列出我们组最后用上的效果比較好的一组特征,具体例如以下:
2.2.3、用户品牌交互特征类
构建用户与品牌之间交互的统计特征,体现用户与品牌之间的交互特性,大致反映出用户与品牌之间满足某种映射下会发生购买行为,大概有:
<pre name="code" class="objc">click_count :用户A对品牌B的总PV数
buy_count :用户A对品牌B的总购买数
collect_count :用户A对品牌B的总收藏数
cart_count :用户A对品牌B的总增加购物车数
avg_buy_day_count :用户A对品牌B的各次购买离如今的平均天数
variance_buy_day_count :用户A对品牌B的各次购买离如今的时间的方差
least_click_day_count :用户A对品牌B的近期一次点击离如今的天数
least_buy_day_count :用户A对品牌B的近期一次购买离如今的天数
least_collect_day_count :用户A对品牌B的近期一次收藏离如今的天数
least_cart_day_count :用户A对品牌B的近期一次购物车离如今的天数
click_count_before_firstbuy :用户A对品牌B的第一次购买前的PV数
collect_count_before_firstbuy :用户A对品牌B的第一次购买前的收藏数
cart_count_before_firstbuy :用户A对品牌B的第一次购买前的购物车数
avg_click_day_interval :用户A对品牌B的平均点击天数间隔
avg_buy_day_interval :用户A对品牌B的平均购买天数间隔
first_operator_day_count :用户A对品牌B的第一次交互离如今的天数
last_operator_day_count :用户A对品牌B的最后一次交互离如今的天数
max_operator_Day_count :用户A对品牌B的交互次数最多那天离如今的天数
user_buy_brand_rate :用户A对品牌B的购买次数占用户A总购买次数的比例
user_click_brand_rate :用户A对品牌B的点击次数占用户A总点击次数的比例
click_buy_rate :用户A对品牌B的点击购买比
click_2_count :用户A对品牌B的PV数的平方
buy_2_count :用户A对品牌B的购买数的平方
brand_is_bought_rate :用户A对品牌B的购买次数占品牌B被购买的总次数的比例
brand_is_clicked_rate :用户A对品牌B的点击次数占品牌B被点击的总次数的比例
last_31_day_click_buy_rate :用户A对品牌B的近期31天的点击购买比
click_day_count :用户A对品牌B的点击总天数
buy_day_count :用户A对品牌B的购买总天数
buy_last_week_count :用户A对品牌B购买了多少周
avg_click_rate_before_buy :用户A对品牌B最后一次购买后的PV数/用户A对品牌B每次购买前的平均点击
avg_collect_rate_before_buy :用户A对品牌B最后一次购买后的收藏数/用户A对品牌B每次购买前的平均收藏
click_delete_user_avg_rate :(用户A对品牌B的PV数-用户A对操作过的品牌的平均PV数)/用户A对操作过的品牌的平均PV数
buy_delete_user_avg_rate :(用户A对品牌B的购买数-用户A对操作过的品牌的平均购买数)/用户A对操作过的品牌的平均购买数
collect_delete_user_avg_rate :(用户A对品牌B的收藏数-品牌B被平均收藏数)/品牌B被平均收藏数
before_0_day_last_5_day_click_count :用户A对品牌B离如今5天之内的PV数
before_0_day_last_5_day_buy_count :用户A对品牌B离如今5天之内的购买数
before_0_day_last_5_day_collect_count :用户A对品牌B离如今5天之内的收藏数
before_0_day_last_5_day_cart_count :用户A对品牌B离如今5天之内的增加购物车数
before_0_day_last_10_day_click_count :用户A对品牌B离如今10天之内的PV数
before_0_day_last_10_day_buy_count :用户A对品牌B离如今10天之内的购买数
before_0_day_last_10_day_collect_count :用户A对品牌B离如今10天之内的收藏数
before_0_day_last_10_day_cart_count :用户A对品牌B离如今10天之内的增加购物车数
before_10_day_last_10_day_click_count :用户A对品牌B离如今10天之前的10天之内的PV数
before_10_day_last_10_day_buy_count :用户A对品牌B离如今10天之前的10天之内的购买数
before_10_day_last_10_day_collect_count:用户A对品牌B离如今10天之前的10天之内的收藏数
before_10_day_last_10_day_cart_count :用户A对品牌B离如今10天之前的10天之内的增加购物车数
before_20_day_last_10_day_click_count :用户A对品牌B离如今20天之前的10天之内的PV数
before_20_day_last_10_day_buy_count :用户A对品牌B离如今20天之前的10天之内的购买数
before_20_day_last_10_day_collect_count:用户A对品牌B离如今20天之前的10天之内的收藏数
before_20_day_last_10_day_cart_count :用户A对品牌B离如今20天之前的10天之内的增加购物车数
before_30_day_last_10_day_click_count :用户A对品牌B离如今30天之前的10天之内的PV数
before_30_day_last_10_day_buy_count :用户A对品牌B离如今30天之前的10天之内的购买数
before_30_day_last_10_day_collect_count:用户A对品牌B离如今30天之前的10天之内的收藏数
before_30_day_last_10_day_cart_count :用户A对品牌B离如今30天之前的10天之内的增加购物车数
before_0day_last_10_day_click_day_count:用户A对品牌B离如今10天之内的总点击天数
before_0day_last_10_day_buy_day_count :用户A对品牌B离如今10天之内的总购买天数
2.2.4、用户特征类
构建体现用户特性的特征,尽量挖掘处用户购物行为习惯,大致有例如以下特征:
user_buy_count :用户A总购买的次数
user_click_count :用户A总点击的次数
user_collect_count :用户A总收藏的次数
user_cart_count :用户A总购物车的次数
user_click_buy_rate :用户A总的点击购买比
user_avg_buy_day_count :用户A全部购买发生的时间离如今的平均天数
user_least_buy_day_count :用户A近期一次购买离如今的天数
user_variance_buy_day_count :用户A全部购买发生的时间离如今的时间方差
user_last_5_day_click_count :用户A近期5天的点击总数
user_last_5_day_buy_count :用户A近期5天的购买总数
user_last_5_day_collect_count :用户A近期5天的收藏总数
user_last_5_day_cart_count :用户A近期5天的增加购物车总数
user_click_day_count :用户A点击的总天数
user_buy_day_count :用户A购买的总天数
user_collect_day_count :用户A收藏的总天数
user_cart_day_count :用户A增加购物车的总天数
user_buy_brand_count_for_1_week:用户A仅仅购买1周的商品有多少种
user_buy_brand_count_for_2_week:用户A仅仅购买2周的商品有多少种
user_buy_brand_count_for_3_week:用户A仅仅购买3周的商品有多少种
user_buy_brand_count_for_4_week:用户A仅仅购买4周的商品有多少种
2.2.5、品牌特征类
构建体现品牌特性的特征,尽量挖掘处什么样的品牌受用户追捧,会被用户购买,大致有例如以下特征:
brand_click_count :品牌B被点击的总次数
brand_buy_count :品牌B被购买的总次数
brand_collect_count :品牌B被收藏的总次数
brand_cart_count :品牌B被增加购物车的总次数
brand_click_buy_rate :品牌B的点击购买比
brand_last_3_day_click_count :品牌B近期3天之内的点击总数
brand_last_3_day_buy_count :品牌B近期3天之内的购买总数
brand_last_5_day_click_count :品牌B近期5天之内的点击总数
brand_last_5_day_buy_count :品牌B近期5天之内的购买总数
brand_last_11_day_click_count :品牌B近期11天之内的点击总数
brand_last_11_day_buy_count :品牌B近期11天之内的购买总数
brand_least_operator_day_count:品牌B近期一次被操作离如今的天数
brand_first_operator_day_count:品牌B第一次被操作离如今的天数
brand_hot_level :品牌B的热门度(PV数*0.1+购买数*5+购物车数+收藏数)
user_count_buy_brand_morethan_2week :购买品牌B超过两周的用户数
user_count_buy_brand_morethan_3week :购买品牌B超过三周的用户数
user_count_buy_brand_morethan_4week :购买品牌B超过四周的用户数
user_count_buy_brand_equal_1week :购买品牌B为1周的用户数
user_count_buy_brand_equal_2week :购买品牌B为2周的用户数
user_count_buy_brand_equal_3week :购买品牌B为3周的用户数
user_count_buy_brand_equal_4week :购买品牌B为4周的用户数
brand_hot_ave_level :品牌B的热门度(PV数*0.1+购买数*5+购物车数+收藏数)/(品牌B第一次被操作和最后一次被操作的时间间隔天数)
2.2.6特征计算
利用天池平台的分布式计算,具体资料见天池平台资料分享。我们组写了三个MapReduce程序,Map阶段分别依据userbrandgroup、usergroup、brandgroup进行拆分,Reduce阶段分别计算出三类特征的数值,后面就是简单的多张特征表的合并操作,线下的训练和预測的特征总表的MR处理是一样的,仅仅有输入时间不一样,例如以下所看到的:
<pre name="code" class="sql"><pre name="code" class="sql">//线下训练特征总表
create resource jar C:\TOOLS\mapReduce-getCharacter.jar -f
jar --resources mapReduce-getCharacter.jar --classpath C:\TOOLS\mapReduce-getCharacter.jar com.mr.userbrandgroup.MyDriver LR_Offline_Train_Table LR_Offline_Train_Feature_1_Table '04-15' '07-02' '1';
create resource jar C:\TOOLS\mapReduce-getCharacter.jar -f
jar --resources mapReduce-getCharacter.jar --classpath C:\TOOLS\mapReduce-getCharacter.jar com.mr.usergroup.MyDriver LR_Offline_Train_Table LR_Offline_Train_Feature_2_Table '04-15' '07-02';
create resource jar C:\TOOLS\mapReduce-getCharacter.jar -f
jar --resources mapReduce-getCharacter.jar --classpath C:\TOOLS\mapReduce-getCharacter.jar com.mr.brandgroup.MyDriver LR_Offline_Train_Table LR_Offline_Train_Feature_3_Table '04-15' '07-02';
//线下预測特征总表
create resource jar C:\TOOLS\mapReduce-getCharacter.jar -f
jar --resources mapReduce-getCharacter.jar --classpath C:\TOOLS\mapReduce-getCharacter.jar com.mr.userbrandgroup.MyDriver LR_Offline_Validate_Table LR_Offline_Validate_Feature_1_Table '04-15' '07-21';
create resource jar C:\TOOLS\mapReduce-getCharacter.jar -f
jar --resources mapReduce-getCharacter.jar --classpath C:\TOOLS\mapReduce-getCharacter.jar com.mr.usergroup.MyDriver LR_Offline_Validate_Table LR_Offline_Validate_Feature_2_Table '04-15' '07-21';
create resource jar C:\TOOLS\mapReduce-getCharacter.jar -f
jar --resources mapReduce-getCharacter.jar --classpath C:\TOOLS\mapReduce-getCharacter.jar com.mr.brandgroup.MyDriver LR_Offline_Validate_Table LR_Offline_Validate_Feature_3_Table '04-15' '07-21';
在进行LR模型的时候,我们依据文本检索里面的对数处理准则,对计算到的特征总表进行了总体对数化处理,之后便是对正负样本进行单独抽样得到一个较小的数据集进行训练,抽样总数为330W,抽样比例为10:1(后面改到8:1有小幅度提高),LR模型因为构建数据集和特征,熟悉MR,所以上手的时间非常长,做了一周左右,提交的成绩不好
不断加入和測试新的特征,两三天的时间,成绩就有了起色,之前规则的得分上线被LR打破,停滞的F1最终開始涨了,这段时间因为做的有点疲倦,加的特征不够多,成绩上涨的断断续续,F1上涨到接近5的时候又出现了瓶颈,再怎么加入特征都不怎么涨了:
这段时间,LR的瓶颈让我们放弃了对它的执念,看到竞赛群里火热的讨论着RF,我们决定转投RF。。。
2.3RF
感觉我们组好悲催,别的组都能直接从LR过渡到RF上面来,我们又要又一次測试一下特征,不能直接转过来,花了两天的时间,成绩略微正常了一点,可是离LR不妨差了一大截啊,怀疑我们的方法哪里出问题了,这段时间又是考试周临近,真真的头疼啊(看到别的组天天都在上升,饥饿游戏,滋味不好受,还是每天抽出两三个小时来做比赛)排错排除了一周左右的时间,成绩上涨到和LR差点儿相同的水平了,当时那个开心啊,呵呵,回味无穷
然后,就正式进入考试周了,比赛的时间压缩到极致,两人都忙于复习,比赛做的比較水了,中途不知道哪里出问题了,提交的成绩创历史之最了。。。商议之后决定,决定临时不搞了,差点儿相同停了两周左右
考完试也就基本是6月底了,和队友也差点儿相同忙完了,每天空暇时间相对多了起来,决定重操旧业,”享受早上起来看成绩兴奋的那一瞬间“,我们花了两天时间又一次排查了一遍程序,决定临时先不正确数据做预处理,利用选好的特征,最终得到了超过LR最好得分的成绩,一举破5,停滞的baseline最终開始上涨啦,(果然是预处理影响了我们的模型型。。。当时猜想是数据清洗的过度了,后来也试过删除一些刷砖用户,可是效果甚微)基本上方法对了之后,我们就不断加入新的特征,这几天基本实现两天一个大提升,特征总数也达到了500多,实际用上的特征从30多个,到了接近70个了。
我们RF训练用的方法基本上是界面的方式实现的,详细做法见之前发的一篇博文阿里大数据比赛sesson2 RF上手篇,成绩上涨到5.66这个水平就不太好上升了,试了两三天效果都不好了,正好碰到群里又在火热的讨论gbrt,对于我们来说又是一个新的模型,我们商议之后,没有犹豫,立刻决定转到GBRT,继续马拉松。。。
2.4GBRT
学习了两天的GBRT界面操作(由于一直没注意看BBS的更新资料,导致我们知道7月中旬都一直还在用界面训练预測,耗时耗力。。。),便開始实战了,果不其然,直接RF最好特征转过来,效果又是差的离奇,(奇了怪了,这也太悲催了吧),这两天和哈工大队的大帅交流了下GBRT的使用心得,最终还是步入了正轨,成绩又開始欢快的涨了,涨了。。。
成绩上了5.8之后,上涨的就有点吃力了,不断加入新的特征,不断换数据预处理,经过一周的操作,成绩上涨到了
还是没能上5.9,我们这段时间尝试过RF和GBRT模型融合,加入规则辅助推荐都效果不好,详细的GBRT方法见博文阿里大数据比赛sesson2 GBRT上手篇,20号左右的时候,最终看到了脚本实现的文档。。。再也不用手动训练预測了。。。
2.5最后一周奋战
24号阿里更新了一批等量的数据,当天晚上,赶在凌晨4点之前,在新数据集上跑完了第一次成绩,当晚的成绩最终破5.9啦
好景不长,接下来的一天,线下在提升,线上却下降了,反思线下特征过拟合了,在讨论组里大家都在议论着提升的问题,我们又又一次梳理了特征,再次加入了一批特征,惊喜的发现线下提升了0.06达到了5.39,着实兴奋了一把,果然,第二天成绩怒破6.0,排名稳定在了前50名,激动不已。。。
接下来的几天,我们继续线下调试新特征和试着融合,可是线下效果好,到了线上效果却低于6.02:
最后一天,我们改变了正负样本抽样比例,换到了8:1,线下提升了0.02,线上定格在了6.03:
写博客的一天,再现了四个月来的一路”厮杀“,几个月来就基本没有1点钟之前睡过觉的,尽管辛苦,可是还是认为收获挺多,感谢阿里提供的这个平台,让我们对大数据不再一无所知,感谢队友朱凌云的陪伴,感谢我们队伍一路走来帮助过我们的哈工大-王帅同学和姚继涛同学,感谢USTC的Cara、Closure、陈朝才和陈诚、李悦、以及宁波大学丁石磊同学,以及一些路见不平拔刀相助的壮士,么么哒O(∩_∩)O~