O2O优惠券使⽤预测
⼀、背景
李维嘉暴瘦通过分析⽤户线上线下的消费⾏为,建⽴模型,预测现阶段⽤户是否会在规定时间内使⽤相应优惠券,以便商家个性化投放,提⾼优惠券核销率。
数据为⽤户在2016年1⽉1⽇⾄2016年6⽉30⽇之间真实线上线下消费⾏为,预测⽤户在2016年7⽉领取优惠券后15天以内的线下使⽤情况。
我们的⽬标是要预测⽤户优惠券的线下使⽤情况,线上数据我们重点关注与⽤户相关的特征(是作为线下数据的⼀个辅助),线下我们关注的特征数据就⽐较多了:⽤户特征、商户特征、优惠券特征、
⽤户商户组合特征、⽤户优惠券组合特征。
数据分析:
1、预测集中的⽤户,是线下训练数据集⾥出现过的⽤户,也就是⽼⽤户。
2、根据经验,我们知道活跃⽤户更可能使⽤优惠券,活跃商家所发出的优惠券更可能被使⽤,⽤户对某个商家的喜爱程度越⾼越可能使⽤这个商家发的优惠券
李靓蕾照片3、⽤户在周末更有时间更可能使⽤优惠券
4、预测集中的商家,⼏乎都是线下训练数据集中出现过的商家。
⼆、数据预处理
本题所有数据记录的时间区间是2016.01.01⾄2016.06.30,需要预测的是线下2016年7⽉份⽤户领取优惠劵后15天内是否核销。根据这两份数据表,我们⾸先需要对数据集进⾏划分(采⽤滑窗的⽅式),特征区间为3.5个⽉,预测区间为⼀个⽉。要保证滑到最后,测试集的预测区间正好是7⽉。也可以⽤其他的⽅式划分,特征区间越⼩,得到的训练数据集越多。
特征区间(提取feature)预测区间(预测label)训练集20160101~2016041320160414~20160514
验证集20160201~2016051420160515~20160615
测试集20160315~2016063020160701~20160731
为什么要这样划分呢?第⼀,划分训练集和验证集,⽅便我们交叉验证;第⼆,我们的训练和预测是与时间有关系的,如果是⽤
train_test_split随机划分,可能会导致训练数据是6⽉份,⽽预测数据却是5⽉份,这与现实是不符合的,这就是数据泄露:
数据泄露就是说⽤了不该⽤的数据,⽐如
(1)在训练模型时,利⽤了测试集的数据、信息
(2)在当前使⽤了未来的数据
(3)在交叉验证进⾏调参时,使⽤了验证集的信息参与模型建⽴
具体说下第三点,⽐如对特征进⾏标准化,正确的⽅法应该是在训练集上标准化,然后应⽤到验证集上,⽽⾮先标准化,再划分验证集。再⽐如说,要对数据进⾏pca降维,应该是在训练集上pca,然后作⽤到验证集上,⽽⾮对整个数据集进⾏pca。通常都忽略了这⼀点。
如果数据集划分的不好,可能会导致在训练数据上效果很好,线下测试也还不错,但是在线上表现却不好。
注意数据集的划分是不能只根据Date_Received(优惠券领取⽇期)来划分,否则划分出来的数据都是有优惠券的⽤户,没有领取优惠券的⽤户数据都被丢弃了。
因为我们要预测的是⽤户领取优惠券之后的使⽤情况,所以,预测区间可以根据⽤户领取优惠券时间来划分,特征区间⿇烦⼀点,如果消费时间不为空,通过消费时间划分;如果消费时间为空,则根据优惠券领取时间划分。(不能单纯的⽤领取时间或消费时间划分,因为这两个时间都可能是空)
测试集的预测区间的划分是从ccf_offline_stage1_test_revised.csv中读取的。
#划分特征区间数据集,通过领取时间和消费时间
def filter_feature_data(data,start_time,end_time):
return data[((data['Date']> start_time)&(data['Date']< end_time))|((data['Date']=='null')&(data['Date_received']> start_time)&(data['Date_received']< end_time))]
#划分预测区间数据集,根据领取时间
def filter_label_data(data,start_time,end_time):
return data[(data['Date_received']> start_time)&(data['Date_received']< end_time)]
#划分线下数据集
def offline_data_split(origin,test_data):
#训练集
train_feature_data=filter_feature_data(origin,train_feature_start_time,train_feature_end_time)
train_label_data=filter_label_data(origin,train_label_start_time,train_label_end_time)
#验证集
validate_feature_data = filter_feature_data(origin, validate_feature_start_time, validate_feature_end_time)
validate_label_data = filter_label_data(origin, validate_label_start_time, validate_label_end_time)
#测试集
predict_feature_data = filter_feature_data(origin, predict_feature_start_time, predict_feature_end_time)
predict_label_data = filter_label_data(test_data.astype(str), predict_label_start_time, predict_label_end_time)
return train_feature_data,train_label_data,validate_feature_data,validate_label_data,predict_feature_data,predict_label_data
# 划分线上数据集
def online_data_split(origin):
# 训练集
train_feature_data = filter_feature_data(origin, train_feature_start_time, train_feature_end_time)
# 验证集
validate_feature_data = filter_feature_data(origin, validate_feature_start_time, validate_feature_end_time)
# 测试集工作鉴定范文
predict_feature_data = filter_feature_data(origin, predict_feature_start_time, predict_feature_end_time)
return train_feature_data, validate_feature_data,predict_feature_data
查看哪些列有空值:
ad_csv('data/ccf_offline_stage1_train.csv')
print(data.isnull().any())
输出(True为有空值):
User_id False
Merchant_id False
Coupon_id True
Discount_rate True
Distance True
刑法236条的内容是什么Date_received True
Date True
dtype: bool
最好玩的网络游戏三、特征⼯程
特征区间的特征提取
我们的预测⽬标是七⽉份⽤户领券使⽤情况,即⽤或者不⽤,转化为⼆分类问题,然后通过分类算法预测结果。
因此通过Date和Date_received两个列来⽣成target。
然后是特征提取,包括⽤户特征、商户特征、优惠券特征、⽤户商户组合特征、⽤户优惠券组合特征。
每⼀条消费记录,除了本条提取出来的组合特征,还有结合训练集数据计算出来的特征(⽐如⽤户领
取优惠券到消费的等待时间,这是⼀条的,⽽⽤户优惠券的核销率,这是通过整个数据集计算出的)。
注意我们预测七⽉份⽤户领取优惠券的使⽤情况,就要根据⽤户的历史消费使⽤优惠券的情况,然后当该⽤户七⽉份领取了优惠券之后,来判断⽤户是否会⽤掉这张优惠券。
⽤户相关的特征(以User_id为基准统计)
1、Date和Date_received两列---->⽤户领取优惠券消费次数、⽤户⽆优惠券消费次数、⽤户领取优惠券但没有消费、⽤户优惠券的核销率、优惠券领取到使⽤的时间等待,以15天为界,⼩于15天:。等待时间越短,这个值越⼤;⼤于15天:0.
2、Discount_rate分为两种:直接折扣消费和满减----->⽤户直接折扣消费、⽤户使⽤优惠券的满减类别(以1234表⽰)、折扣率、⽤户优惠券消费的各个满减档次的次数、⽤户优惠券消费平均消费折率、限时低价消费次数(线上+线下)
3、Merchant_id、Coupon_id、Date三列:⽤户优惠券消费过的不同商家数量
4、Coupon_id、Date两列:⽤户优惠券消费过的不同优惠券数量
5、Action:点击⾏为分三种,点击、购买、领取优惠券,每个类型的点击率。(线上)
商家相关的特征(以Merchant_id为基准统计)
1、Coupon_id、Date两列:⽆优惠券消费次数、获得优惠券但没有消费次数、优惠券消费次数、优惠券被领取后的核销率
2、Discount_rate分为两种:直接折扣消费和满减----->⽤户直接折扣消费、⽤户使⽤优惠券的满减类别(以1234表⽰)、折扣率、商家优惠券消费的各个满减档次的次数、⽤户优惠券消费平均消费折率、
3、Date和Date_received两列:领取到使⽤的时间等待
4、User_id、Coupon_id、Date三列:使⽤本商家优惠券消费过的不同⽤户数量
5、User_id、Coupon_id、Date三列:⽤户在本商家消费过的不同优惠券数量
⽤户-商家相关的特征(以User_id、Merchant_id为基准统计groupby([‘User_id’, ‘Merchant_id’])
Coupon_id、Date两列:⽤户对商家⽆优惠券消费次数、⽤户对商家获得优惠券但没有消费次数、⽤户对商家优惠券消费次数、⽤户对商家优惠券被领取后的核销率、⽤户对每个商家的不消费次数占⽤户不消费的所有商家的⽐重、⽤户对每个商家的优惠券消费次数占⽤户优惠券消费所有商家的⽐重、⽤户对每个商家的普通消费次数占⽤户普通消费所有商家的⽐重
这三类特征提取完成之后保存在user_features.csv、merchant_features.csv、user_merchant_features.csv三个⽂件中,注意,在每个⽂件中的User_id是唯⼀的。预测区间的特征提取
这⼀部分就是结合预测区间的数据(1个⽉)和前⾯特征区间提取出来的特征数据(3.5个⽉)⽣成训练数据。这个训练数据就是⽤来训练模型的。
因此这⼀部分依然需要提取特征数据,除了特征数据外,还要⽣成每⼀条记录的target(除了最后的测试集的预测区间,它没有label,是需要我们预测的)。
(1−)15x −y
预测区间的特征抽取:
1、距离。[0,10]范围内的数字,/10,如果是空则设为-1.
2、优惠券类型:折扣0,满减1(满减档次不同,也要考虑),⽆优惠券-1.
3、优惠券折率(主要是计算满减的折率,折扣的不⽤计算,可以直接⽤)
4、⽤户和优惠券之间的关系汇总:⽤户领取的优惠券数量、⽤户领取的每种优惠券的数量、商家被领取的优惠券的数量、商家被领取的每种优惠券的数量、⽤户领取每个商家的优惠券数量。
初一周记大全5、⽤户和商家的关系汇总:每个⽤户相关的商家数量(或领取了优惠券、或购买了东西)、#每个商家相关的⽤户数量(或领取了本商家的优惠券、或购买了本商家的东西)
预测区间⽣成target:
Coupon_id、Date两列⾮空且领取优惠券时间到消费时间<15天,这样的target标为1,其余的为0.
训练数据:train_features.csv、
标签数据:labels.csv
在train、validate、predict下各有⼀份。predict⽬录下只有train_features.csv
四、模型训练
1、xgboost模型训练。
结果:
model.best_score:0.868995, model.best_iteration:91, model.best_ntree_limit:92
output offline model data
Average auc of train matrix:0.751128208956236
Average auc of validate matrix 0.6841286615724935
[[1136705071]
[49483357]]
⽂件执⾏顺序:
1、data_split.py 划分数据集,线上数据集产⽣六个⽂件,分别是:offline_train_feature_data.csv、offline_train_label_data.csv、offline_validate_feature_data.csv、offline_validate_label_data.csv、
offline_predict_feature_data.csv、offline_train_label_data.csv
线下数据集产⽣3个⽂件:online_train_feature_data.csv、online_validate_feature_data.csv、online_predict_feature_data.csv 2、feature_extract.py 特征提取,针对训练集、验证集、测试集的特
征区间进⾏特征提取,产⽣各⾃的特征⽂件:user_features.csv、merchant_features.csv、user_merchant_features.csv
3、gen_data.py 产⽣训练模型⽤的数据,仍然是针对训练集、验证集、测试集,其中训练集和验证集各产⽣两个⽂件:
train_features.csv(第2步产⽣的特征.merge(预测区间的特征))、labels.csv(预测区间的标签),测试集只产⽣⼀个⽂件:
train_features.csv
4、利⽤第3步产⽣的训练数据,进⾏模型的训练,计算AUC值、best_score、混淆矩阵等,训练好之后,进⾏test数据集的预测,将结果放在submission.csv中。
随⼿记:
1、把常量提取出来在config.py中定义。
2、把数据集划分后的结果分别写在csv⽂件中,把提取出的特征DataFrame也写在csv⽂件中,这样在调试的时候,后期训练模型就不⽤重复前⾯的操作了,直接读取⽂件就可。
3、pd.read_csv读取⽂件时,⼀定要注意keep_default_na=False属性,这会影响后续的⼀系列数据处理和⽐较。
参数调优(使⽤交叉验证):
1. XGBoost内置交叉验证“cv”,这个函数可以在每⼀次迭代中使⽤交叉验证,并返回理想的决策树数量(迭代的轮数)。
2. 对于给定的学习速率和决策树数量,使⽤GridSearchCV进⾏决策树特定参数调优(max_depth, min_child_weight, gamma,
subsample, colsample_bytree)。
3. xgboost的正则化参数的调优。(lambda, alpha)。这些参数可以降低模型的复杂度,从⽽提⾼模型的表现。
4. 降低学习速率,确定理想参数。
发布评论