携程客户流失概率预测 赛后总结

这次和一群好友在科赛网上参加了携程的客户流失概率预测比赛,最终33名完赛,虽然依然是渣渣成绩,但又认识了好多大神,学到了不少东西。

 

这次这个比赛其实难点还不少,首先就是评分规则与众不同,本来以为会用AUC或者F1 score之类的,但官方用的是precision≥97%下,recall的最大值。起初也不知道如何自定义metric,只能用一些默认的,跟线上完全对应不起来,很摸瞎。

 

一开始只觉得是简单的分类问题,也没太多想,处理一下特征,先跑个分类器吧。自从上次在天池吃瘪了之后,这次在特征处理上算是好好下了些功夫,比如一些离散特征这回知道用哑变量处理了,当年真是naïve啊……有一些离散特征,比如decisionhabit_user(用户行为类型)这种,有成百上千种,如果每个都对应一个dummy似乎不太实际,于是先观察一下数据,发现>40的只占很少的比例,所以>40的都指定为50(这个值其实无所谓,你指定成10000都没事),然后用0来填充nan(原来的decisionhabit_user里没有0这个值),再用pd.get_dummies来转化为哑变量矩阵。除此之外,诸如酒店价格、客户的星级偏好、消费能力这些虽然都是连续特征,但可以通过分段来转化为离散变量,比如0-20一段,20-40一段诸如此类。

 

此外,这个比赛另一个很蛋疼的地方就是数据缺失很多,填充这件事情真是让人绞尽脑汁。搁以前估计我就全填0了,但这几个月还是略有所学,知道填0 too simple!还是得观察数据先。主要通过观察每个特征的分布情况,比如值域,形态神马的。Pandas里可以写一句

df.a.value_counts().sort_index().plot()

 

来简单地画个图了解一下特征的情况。有些填0明显不合理,可以考虑用均值或中值填充(中值跟适合偏倚严重的数据)。后来又听高手说了拉格朗日插值法来填充nan,顿感高大上,scipy里可以掉包,但似乎运行速度比较慢(时间复杂度貌似是平方级还是立方级来着),但发现可以尝试一下简单的线性插值

from scipy.interpolate import interp1d

 

这样可以用不含nan的A特征来填充含有nan的B特征,前提当然是两者要强相关啦。像消费能力和用户价值这种就可以互相填充。

最后实在想不出办法的就填0吧……另外第一次知道原来一行里na的数量也可以作为一个特征。

 

特征处理完差不多275个,想想以前只能做出几个特征来,原来是打开方式不对啊……由于特征数量不算太多,所以也没有用PCA之类的进行特征选择,用MinMaxScaler缩放了一下之后(考虑到万一要用线性模型)就直接放进算法里滚。一开始用了RF,但效果并不好,后来转用xgboost,才发现原来大家都在用嘛~此间也在国外网站上找到了xgboost中自定义metric的方法,详细可见:

http://www.cnblogs.com/silence-gtx/p/5812012.html

 

经过一波调参之后发现怎么也上不了0.05,线下似乎可以做到0.30+,感觉不是很科学,后来经世超大神指点才知道原来是不收敛了……训练集和验证集都在不断上升,但线下不错线上却很差。之后又遇到一位朋友来交流,说可以用参数换特征,想想我特征也做得不好,换就换吧~得到了两个很重要的信息,一个是训练集和验证集的划分不能随机抽样,而是要按天来划分,因为原题中有这样一句话:如果用户小王在2016年5月20日按照顺序访问了A,B,C,D四家酒店,最后选择了D下单。则对应我们的数据,他会产生4条记录(即4个sampleId),四条记录的label都会为1。如果随机抽样的话,会割裂这样的记录,使准确性大幅下降。另外一个重要的信息就是xgb有个参数scale_pos_weight,这个参数可以均衡你结果中0与1的比例,他给了我一个值,虽然这下xgboost训练时收敛了,但结果并不理想……后来还是世超大神告诉我要保证xgb预测训练集和验证集的0-1比例与它们真实的0-1比例非常接近。比如说,原来验证集0-1比例是3:1,那你的分类器训练完之后再预测验证集,其0-1比例也应当非常接近3-1。通过调节这个参数再搭配上其他参数终于上了0.06,也发现原来这个参数根据特征的不同其取值是不同的(有人是0.50+,而我的是1.80)。最后几天尝试了一下模型融合,但效果并不理想,最后也就停留在33了。

 

这次比赛感觉把自己三个月来学到的大招全都放完了,却又学到了很多新的大招~感谢这一路上一起交流的朋友们,感谢乐于分享的各位大神,没有你们我还是个战五渣,现在好歹是战六渣了~

posted @ 2016-09-04 17:43  SilenceGTX  阅读(5328)  评论(8编辑  收藏  举报