Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
36 changes: 9 additions & 27 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,37 +1,35 @@
赛题地址:[https://tianchi.shuju.aliyun.com/competition/introduction.htm?spm=5176.100065.200879.2.6r6s4g&raceId=231587](https://tianchi.shuju.aliyun.com/competition/introduction.htm?spm=5176.100065.200879.2.6r6s4g&raceId=231587 "O2O优惠券使用预测赛题地址")

[第一赛季数据](https://pan.baidu.com/s/1c1NkUn2)

-------------------
**目录**


[TOC]

-------------------
正式开始做是从十月底开始的,之前参加了新手赛,而这一次正式赛可以说是真正认真做的一次,中间和队友一起学习了很多,也有小小的收获,不管这次成绩如何,以后还有机会

![我的成绩](http://img.blog.csdn.net/20170103160645251?watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQvc2hpbmUxOTkzMDgyMA==/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/SouthEast)
# **引言**
这是我尝试性参加新手赛的最完全的一次实践,期间看了《Python机器学习及实践》、《Python科学计算》、《统计学系方法》等,当然其中只有第一本完全吃了,其他几本都是属于参考性质,还参考有西瓜书等就不一一列出了。其中自我感觉收获最大的就是接触了XGBoost模型,其次就是pandas的一些用法
整体是对来自北大和中科院的队伍“诗人都藏在水底”参赛代码的再现。最大的区别就是把基于比较低版本的pandas和python改为了高版本的代码。
非常非常感谢身为第一赛季榜首队伍的他们,公开了自己的代码,这里贴上地址:[GitHub地址](https://github.com/wepe/O2O-Coupon-Usage-Forecast)

-------------------
# **数据与评价方式**

赛题提供用户在2016年1月1日至2016年6月30日之间真实线上线下消费行为,预测用户在2016年7月领取优惠券后15天以内的使用情况。 使用优惠券核销预测的平均AUC(ROC曲线下面积)作为评价标准。 即对每个优惠券coupon_id单独计算核销预测的AUC值,再对所有优惠券的AUC值求平均作为最终的评价标准。

-------------------
# **解决方案**
提供数据的区间是2016-01-01~2016-06-30,预测七月份用户领券使用情况,即用或者不用,转化为**二分类问题**,然后通过分类算法预测结果。首先就是特征工程,其中涉及对数据集合的划分,包括提取特征的区间和训练数据区间。接着就是从特征区间中提取特征,包括用户特征、商户特征、优惠券特征、用户商户组合特征、用户优惠券组合特征。后期在测试区间提取了当天的前后7/3/1天的领券信息(这里面后七天的特征其实是不能应用于工业应用的,因为实际预测中你无法知道后7/3/1天的领券信息),提升较大。最后使用GBDT、RandomForest、LR进行基于rank的分类模型融合
提供数据的区间是2016-01-01~2016-06-30,预测七月份用户领券使用情况,即用或者不用,转化为**二分类问题**,然后通过分类算法预测结果。首先就是特征工程,其中涉及对数据集合的划分,包括提取特征的区间和训练数据区间。接着就是从特征区间中提取特征,包括用户特征、商户特征、优惠券特征、用户商户组合特征、用户优惠券组合特征。后期在测试区间提取了当天的前后7/3/1天的领券信息(这里面后七天的特征其实是不能应用于工业应用的,因为实际预测中你无法知道后7/3/1天的领券信息),提升较大。最后使用XGBoost模型进行拟合预测。

-------------------
# **数据划分**
最初没有使用数据划分,导致特征中产生数据泄露,以至于在训练数据上效果很好,线下测试也还不错,在线上表现确差强人意,后来划分了之后有明显提升。
最终还是采用原作者的划分方法,如下:

| 集合 | 预测区间 |特征区间|
| :------- | :--------| :-- |
| 测试集 |领券:20160701~20160731|领券&消费:20160101~20160630|
| 训练集 | 领券:20160515~20160615<br>消费:20160515~20160630 |领券:20160101~20160501<br>消费:20160101~20160515|

并没有划分多个训练集,这一点是要改进之处
有尝试划分多个训练集,但是结果并没有大的改观

-------------------
# **特征工程**
Expand Down Expand Up @@ -217,29 +215,13 @@
- 7/4/2天此用户在此商店领取的优惠券发放数目 uc16_i
- 用户前后2/4/7领取的优惠券优惠率排名 uc17_i

-------------------
# **算法及模型融合**
最初使用GBDT和RF两种模型,GBDT效果优于RF,后期使用了多个GBDT,分别使用不同的参数、不同的正负样本比例以rank的方式进行多模型的融合,效果有微小提升,但是由于计算量的限制没有进一步展开。
## **模型融合**

由于评估指标是计算每个coupon_id核销预测的AUC值,然后所有优惠券的AUC值平均作为最终的评估指标,而rank融合方式对AUC之类的评估指标特别有效,所以采用此方法,公式为:
<center>$\sum\limits_{i=1}^{n}\frac{Weight_i}{Rank_i} $</center>
XGBoost单模型,接下来会场时进行双模型的融合。

其中$n$表示模型的个数, $Weight_i$表示该模型权重,所有权重相同表示平均融合。$Rank_i$表示样本在第i个模型中的升序排名。它可以较快的利用排名融合多个模型之间的差异,而不需要加权融合概率。
## **应用**
基于参数,样本(采样率),特征获得多个模型,得到每个模型的概率值输出,然后以coupon_id分组,把概率转换为降序排名,这样就获得了每个模型的$Rank_i$,然后这里我们使用的是平均融合,$Weight_i=1$,这样就获得了最终的一个值作为输出。

----------
# **线下评估**
虽然这次比赛每天有四次评测机会,但是构建线下评估在早期成绩比较差的时候用处很大,早期添加特征之后线下评估基本和线上的趋势保持一致(例如在添加了Label区间的领券特征之后,线下提升十多个百分点,线上也是一致),对于新特征衡量还是有参照性的。后期差距在0.1%级别的时候,就没有参照性了。

线下评估在训练集中采样1/3||1/4||1/5做线下评估集合,剩下的做为训练集训练模型,并将评估集合中全0或者全1的优惠券ID去掉,然后使用训练的模型对评估集合预测,将预测结果和实际标签作异或取反(相同为1,不同为0),然后算出每个优惠券ID的AUC,最后将每个ID的优惠券AUC取均值就得到最终的AUC。

-------------------
# **回顾**
这一次比赛学习了很多,包括分布式平台ODPS和机器学习平台实现数据清洗,特征提取,特征选择,分类建模、调参及模型融合等,学习摸索了一套方法,使自己建立了信心,明白还有很多需要学习的地方,之前一直对于算法都是当做一个黑匣子,只会熟悉输入输出直接调用,要深入了解算法,才能突破目前的瓶颈有所提高。
同时我觉得大家一起探讨交流也很重要,一个人做着做着就容易走偏,纯属个人看法。

CSDN博客链接:[http://blog.csdn.net/shine19930820/article/details/53995369](http://blog.csdn.net/shine19930820/article/details/53995369)

自己的代码太乱,改自第一名[GitHub地址](https://github.com/wepe/O2O-Coupon-Usage-Forecast)
这一次参赛虽然历时并不久,但可以说是打开了新世界的大门,之前一直停留在看书自己实现算法的基础工作阶段,如今终于踏入了实践当中,希望自己在北大的学业结束之时能成为心目中不仅数学基础扎实而且技术实力雄厚的“计算机+数学大神”。
16 changes: 16 additions & 0 deletions blending.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
import pandas as pd

xgb = pd.read_csv('xgb_preds.csv')
xgb.columns = ['user_id','coupon_id','date','xgb_preds']
xgb.drop_duplicates(['user_id','coupon_id','date'],inplace=True)
# print(xgb.info())
gbdt = pd.read_csv('gbdt_preds.csv')
gbdt.columns = ['user_id','coupon_id','date','gbdt_preds']
gbdt.drop_duplicates(['user_id','coupon_id','date'],inplace=True)
# print(gbdt.info())

blending = pd.merge(xgb,gbdt,on=['user_id','coupon_id','date'],how='inner')
blending['preds'] = blending['xgb_preds']*0.6 + blending['gbdt_preds']*0.4
blending.drop(['xgb_preds','gbdt_preds'],axis=1,inplace=True)

blending.to_csv('blending_preds.csv',index=None,header=None)
Loading