之前参加了kaggle的一个Santander Customer Transaction Prediction比赛,共有达9038支队伍参赛,一个号称寻找magic的比赛。参加比赛的的忘不了被magic这个词所支配的恐惧...
比赛链接 https://www.kaggle.com/c/santander-customer-transaction-prediction/overview
也算是第一次kaggle正式的做比赛吧,之前做了一个kaggle的Quora的文本分类的一个比赛,但是只做了几天,最后还没选成 Final Score,所以最后也不算成绩,也不知道排了多少名。
我是前期做了几天,后来就没做了,直到最后四天才又开始每天做10个小时大概...
然后自己的成绩是 top4% for 9038 teams 。 300/9038
很可惜最后一天模型融合没跑完比赛时间就截止了,跑完的话能再升100名.....
对自己的成绩还算满意吧。
最后感谢某位大佬的指点和带飞。
下面来总结一下这个比赛自己的收获。
这个比赛训练集给了20w条数据,共200个特征,都是数值型特征,都是匿名特征,并没有具体的每个特征的含义。测试集也是20w条数据。
根据这200个特征预测每个用户是否会发生交易。一个2分类问题,最后评估是ROC_AUC。
这个比赛最最重要的两个magic其实在讨论区和kernel区已经有hint了。
1、其中最重要的就是区分测试集中合成样本和真样本。下边的kernel是某大神提出区分合成样本和真样本的方法,通过判断特征的唯一值,如果一条样本中200个特征值中有一个特征值在这20w样本中是unique的,则该样本是真样本。通过这个方法划分出来了10w条真样本,和10w条合成样本。具体代码见下面的kernel。
https://www.kaggle.com/yag320/list-of-fake-samples-and-public-private-lb-split
2、第二个magic就是,frequency encoding 和 count encoding。当然是除去合成样本,即将train+test_true合起来做特征。
当然还有一个magic更神奇,只需要短短几行代码就能到150名。下面再说。
下面贴一下top解决方案
1 Solution
https://www.kaggle.com/c/santander-customer-transaction-prediction/discussion/89003#latest-515385
2nd place solution
可以看到这位大神用了NN和LGB的模型来融合。其实我看很多大神都用了NN模型,NN模型在这个比赛效果还不错,用的好的话,说不定能拿个金牌呢。
9 Solution
https://www.kaggle.com/c/santander-customer-transaction-prediction/discussion/88913#latest-515121
这位大神,首先将train+test_true合并,然后将unique的特征用NaN代替,他说能到0.917,后来我自己尝试分数能直接飙到0.919,什么概念呢,在100名左右。
然后他继续拿初始的200个特征,将count>1的用NaN替代,然后将这400个特征拼接起来,分数就能达到0.922,然后自己在改改参数,数据增强采样一下,模型融合我估计能到top50。
当然现在开源的都能达到0.925+了,可以直接去看开源kernel。我只是总结一下自己当时比赛的一些情况。
我也是基于train+test_true做的frenquence encoding特征,用lgb 十折LB在0.903,这个时候需要调调参数,把num_leaves调小点,结果会更好些。但是我当时没调..当时时间确实很仓促,很多实验都没来得及做,比如没有用XGB跑一下,用xgb跑的话,参数不改能直接提交达到0.91020.能在200名左右。。
然后最后也没用上数据采样增强..其实还是有用的。
最后我跑了lgb+ xgb + nn做stack可惜时间不够了,第二天5.30定了闹钟起来看结果...因为大概早上八点比赛就截止了,可惜kaggle的kernel只能跑9h,然后时间超了...遂fail...以后还是用服务器跑吧...血的教训。
比赛结束后,自己将模型融合的结果提交了一波,发现lgb+ xgb + nn做stack,stack第二层 采用十折的Ridge效果最好。可惜当时时间不够没能提交。但是我当时NN的效果不好,只有0.89754的score。所以结果也不是太好,如下图。
自己也尝试了stack第二层采用逻辑回归,效果差一点..尝试了xgb×0.7+lgb×0.3也只有0.909。
最好放一下stack的代码
from sklearn.ensemble import RandomForestClassifier, ExtraTreesClassifier, GradientBoostingClassifier from sklearn.linear_model import BayesianRidge from sklearn.model_selection import StratifiedKFold from sklearn.linear_model import LogisticRegression import numpy as np stack_train = np.vstack([sub_oof['lgboof'], sub_oof['xgboof'],sub_oof['nnoof']]).transpose() stack_test = np.vstack([sub_pred['lgb_target'],sub_pred['xgb_target'],sub_pred['nn_target']]).transpose() folds = StratifiedKFold(n_splits=10, shuffle=False, random_state=42) oof_stack = np.zeros(len(sub_oof)) pred_ = np.zeros(len(test)) target = sub_oof['target'] ## LR for fold_, (trn_idx, val_idx) in enumerate(folds.split(stack_train, target.values)): print("Fold :{}".format(fold_ + 1)) clf = LogisticRegression(random_state=42, n_jobs=8).fit(stack_train[trn_idx], target.iloc[trn_idx]) oof_stack[val_idx] = np.array(clf.predict_proba(stack_train[val_idx]))[:, 1] pred_ += np.array(clf.predict_proba(stack_test))[:, 1] / folds.n_splits print("Stackinglr_CV score: {:<8.5f}".format(roc_auc_score(target, oof_stack))) ## Ridge oof_stack2 = np.zeros(len(sub_oof)) pred_2 = np.zeros(len(test)) for fold_, (trn_idx, val_idx) in enumerate(folds.split(stack_train, target.values)): print("Fold :{}".format(fold_ + 1)) clf = BayesianRidge().fit(stack_train[trn_idx],target.iloc[trn_idx]) oof_stack2[val_idx] = clf.predict(stack_train[val_idx]) pred_2 += (clf.predict(stack_test)) / folds.n_splits print("StackingBayes_CV score: {:<8.5f}".format(roc_auc_score(target, oof_stack2)))
之前自己一直处于眼高手低...比如xgb、lgb只仅限看了看别人的总结原理看了看官方文档,并没有去深究原理论文,各有什么优点,但是参加了这个比赛,我去详细读了xgb、lgb的论文,哈哈主要是因为当时在讨论区大家都在讨论为什么这些特征有用,lgb能学到什么不能学到什么,怀着这样的好奇心去读了读论文。其实本来还想写一下GBDT、XGB、LGB各自的原理优缺点的,但是看了看网上这类文章很多...所以便没有去写了。。打算等之后空闲了可以在重复造个轮子写一写,也算是在复习一遍了。