Story 1---O2O优惠券使用预测---part1
在前几天终于看完了Andrew的Machine Learning课程, 但是实际上自己并没有完成那门课的各种编程作业,因为我觉得那里涉及较多的算法细节,而对于我现在这个阶段,可能更重要的是更加懂得数据以及模型,所以我规划的路线是学完概念后进行各种比赛的训练。
那么这里,就是第一个我看的比赛,来自阿里云天池新人赛的一道题目,即“O2O优惠券使用预测”,题目很早之前已经结束了,这里我会以看懂大神代码的方式进行自己的学习与总结。这里感谢这篇博客进行的资料整理。
所以,我们开始第一个故事:
1.审题阶段(提高对于“题目”,“ 数据”的认识)
引言:之前我参加过几次比赛,但是最基本的思路都没有,究其原因还是因为我没有好好研究题目就开始搞,这真的是大忌。那么我们来看看题目:
小结一下:我们想要实现的其实就是怎么最大化优惠券的价值,避免无意义的发放,赋予商家更强的营销能力。
题目已经将背景说的很清楚了,接下来看看数据,我们一共有四个数据:
ccf_offline_stage1_test_revised.csv # 线下数据测试集 3m
ccf_offline_stage1_train.csv # 线下训练集 68m
ccf_online_stage1_train.csv # 线上训练集 460m(这么大的数据pandas跑起来会很艰难,但是我们可以通过改变数据类型等方式减少内存)
sample_submission.csv # 提高结果样例 364B
Q:这里我产生了第一个疑问,我们貌似要预测的是用户优惠券的线下消费行为,那么给我们线上的数据的意义是什么?
A:参考大神的代码后总结如下:线上数据可以提供与用户相关的特征,而线下数据可以提取到更加丰富的特征:用户相关的特征,商家相关的特征,优惠劵相关的特征,用户-商家交互特征。
这里还要注意的是,预测的不是新的一批人的使用情况,而是训练数据里出现过的用户,也就是老用户,我在第一次尝试做这个题的时候竟然忽略了这个。2.数据预处理
a.数据划分:
本题所有数据记录的时间区间是2016.01.01至2016.06.30,需要预测的是2016年7月份用户领取优惠劵后15天内是否核销。根据这两份数据表,我们首先需要对数据集进行划分
大神把数据分成了上面这样:就是将我们有的数据分成了三个特征区间,并把各自对应的预测区间都设置为特征区间的后一个月。这样,对于测试集,刚好能够预测七月的情况。
这部分的代码如下:
import pandas as pd # 线下训练集共有1754884条数据,1053282条优惠券,9738种优惠券 领取日期在20160101~20160615,消费日期在20160101~20160630, # 539438个用户, 8415个商家 off_train = pd.read_csv('data/ccf_offline_stage1_train.csv',header=None) off_train.columns = ['user_id','merchant_id','coupon_id','discount_rate','distance','date_received','date'] # 线下测试集合有2050种优惠券 领取日期在20160701~20160731, 有76309个用户(76307个在线下训练集, 35965个在线上训练集), # 1559家商铺(1558家在线下训练集) off_test = pd.read_csv('data/ccf_offline_stage1_test_revised.csv',header=None) off_test.columns = ['user_id','merchant_id','coupon_id','discount_rate','distance','date_received'] # 11429826条数据(872357有优惠券ID,也就是有消费),762858个用户(267448在线下训练集里) on_train = pd.read_csv('data/ccf_online_stage1_train.csv',header=None) on_train.columns = ['user_id','merchant_id','action','coupon_id','discount_rate','date_received','date'] # 按照上图划分方式来划分数据 dataset3 = off_test feature3 = off_train[((off_train.date>='20160315')&(off_train.date<='20160630'))|((off_train.date=='null')& (off_train.date_received>='20160315')&(off_train.date_received<='20160630'))] dataset2 = off_train[(off_train.date_received>='20160515')&(off_train.date_received<='20160615')] feature2 = off_train[(off_train.date>='20160201')&(off_train.date<='20160514')|((off_train.date=='null')& (off_train.date_received>='20160201')&(off_train.date_received<='20160514'))] dataset1 = off_train[(off_train.date_received>='20160414')&(off_train.date_received<='20160514')] feature1 = off_train[(off_train.date>='20160101')&(off_train.date<='20160413')|((off_train.date=='null')& (off_train.date_received>='20160101')&(off_train.date_received<='20160413'))]
划重点:第一,对于测试集的数据我们要去看该数据在训练集出现的次数;第二:这里划分数据只用了线下训练集;第三:因为我们要dataset中Date的情况,所以划分数据时不会对其Date做限制,但是对于feature来说,我们就需要让消费日期在我们规定范围内,或是没有消费但领取日期在我们规定范围内。
现在划分好数据了,我们准备进行特征提取,一个一个来。
3.特征工程
我们要从数据集中提取以下这些特征
具体提取的代码,大家可以见这里,因为其实就是用pandas对几个数据集的各种操作,这里不详述,不然篇幅就过长了,但是大家要注意的是pandas的操作是很重要的!用好了事半功倍!还有一点是,我们不可能开始就想得出这么多特征,这是需要慢慢积累的。而特征的提取,对于模型效果来说,是非常重要的!
4.上模型
关于模型,我们将从回归树说起,之后看看GBDT,最后谈谈大神用的XGBoost。这部分内容会在part2中详细说明!