Kaggle之路,与强者为伍——记Santander交易预测
Kaggle——Santander Customer Transaction Prediction 原题链接
题目 Description
预测一个乘客在未来会不会交易,不计交易次数,只要有交易即为1,否则为0.
Identify which customers will make a specific transaction in the future, irrespective of the amount of money transacted.
You are provided with an anonymized dataset containing numeric feature variables, the binary target
column, and a string ID_code
column.
The task is to predict the value of target
column in the test set.
Data
提供了 \(200k \times 202\) 的数据,200维的特征,通过EDA发现特征向量基本服从高斯分布,且各个变量之间是独立的,疑似经过 PCA 处理后的特征。target为0 和 1,其中处于1的占比为 0.1117,不平衡现象明显。
测试集为 \(200k \times 201\),含有一行ID,与200维数据。目标为预测该用户的target(0/1)
1nd 解决方法
discussion链接
共使用600个特征,使用agumentation技巧扩充数据集,2.1NN/1LGBM融合。
magic特征为unique特征,作者称其通过EDA观察 LGB 树发现其只使用unique特征,从而注重挖掘数据的unique信息。并根据其出现次数构建了5个类别:
- value在 target=1 的train data中出现多次
- value在 target=0 的train data中出现多次
- value在 target=0和target=1 的 train data中都出现多次
- value在train data中只出现一次
- value在train data和test data(仅包含真实数据) 中都是unique
由此可以构建200个特征(对每个原始特征transform),另外200个特征是数值特征,其将test+data中的unique数据替换为特征的均值。在没有处理掉fake时,作者用前200个特征用LGBM取得了0.910LB(大致前进0.09),增加后200个特征后取得0.914LB。处理掉fake之后,用LGBM取得0.921LB。
具体来说:作者使用10折交叉验证,并用不同的seed并在最后进行融合。采用augmentation技巧,即将同样target的行的特征进行shuffle后作为新的数据进行预测,对target=1的数据进行16次shuffle,对target=0的行进行4次shuffle,同时相应打上伪标签(test数据也被加入到里面进行训练,其中前2700个被设为1,后2000个作为0),用LGBM预测,0.92522 LB。
作者同时训练了一个NN模型,将 val 特征的原始value,unique类与数值特征先映射到embedding,可以构建200个embeddings,然后将200个embedding加权平均在输入到一串全连接网络中导出最终输出。加权的思想类似与attention,加权权重为前置的一个独立NN模块,这样保证最终每个特征用同样的方式训练。训练时对每个batch进行独立的augmentation,结果为0.92497PB,再把 test 加入训练后,0.92546PB。大致扫了下作者的源码,NN的全连接为32层,频繁使用小量的dropout(0.08)和 BN 层。NN的好处是可以提取到特征之间的关系,以及特征内部数据之间的group关系,同时NN需要训练的超参数更少。
2nd 解决方法
discussion链接
1. 移除fake测试集,保留100k的真实测试集,真实测试集的定义为其存在仅出现 1 次的特征,fake行是真实行拼凑起来的,会对结果造成影响。
2. 同时对训练集与测试集的各个特征进行标准化处理
3. 构建频率特征,按照小数点精度,构建4种频率特征
4. 将每一个原始特征与其频率特征取出来进行拼接,并增加类别特征(200个类别),构成新的训练集,在这种情况下相当于仅用原始一个特征来进行训练,而原始每个特征都是均等的(独立性假设)
5. 用 lightgbm 训练和预测
6. 将200个预测结果进行拼接,拼接公式见公式5
7. join真测试集的预测结果,将假测试集的结果置为0,进行提交
该参赛队伍代码链接
对 #1 解释: magic之一,在查看训练集与测试集的unique计数分布时,发现二者存在较大差距,所以测试集由真的测试集与假的测试集组成,假的测试集是防止用户进行LB Probe,真的测试集用来评分。假的测试集是真测试集拼凑的,所以特征不唯一,以此来排除它。运用该magic,大致可以从0.901提升到 LB 0.91,PB 0.907
对 #4 解释:用单个特征来进行预测,可以有更多的训练数据(\(200k \times 200\) 行),训练时对单个特征的关注度也更高,个人理解该方式与比赛期间的augmentation技巧类似。
原始的单个特征为 value
通过 round+计数 扩展特征,最后再加上 特征类别(200个类别),形成的新的train数据为:
value, count_org, count_2, count_3, count_4, varnum ---> target
test数据集做同样处理
对 #6 解释:假设单个特征是依 target 独立的,也即满足下述假定:
\]
我们的目标是由 \(P(y=1 \,|\, x_i)\) 导出 \(P(y=1 \,|\, {\bf x})\),其中 \({\bf x} = \{x_1, x_2,\dots,x_{200}\}\)
\]
按照训练集的统计,可设
\]
同时由朴素贝叶斯可知:
&P(x_i \,|\, y=1) = \frac {P(y=1 \,|\, x_i) \cdot P(x_i)}{P(y=1)} \tag 4 \\
\zeta & =\frac 1 9 \cdot \prod_i \frac {P(y=1 \,|\, x_i) \cdot P(y=0)} {P(y=0 \,|\, x_i) \cdot P(y=1)} \\
& =\frac 1 9 \cdot \prod_i \frac {9 \cdot P(y=1 \,|\, x_i)} {P(y=0 \,|\, x_i)} \tag 5
\end{align}
\]
3nd 解决方法
先取出测试集fake 数据,再把train和fake拼接在一起,然后做特征工程,其使用了unique计数、密度(count平滑后的结果)、前二者相除,故共800维特征。用LGBM训练,取得0.9225 LB,作者观察到单用一些特征训练的auc接近0.5,对最终的结果没有什么帮助,所以采用 Lasso 来自动削减该类特征。CV时优化了reg_alpha, max_bin, learning_rate, num_leaves 4个参数。
作者关键性的操作是用 CNN 进行二阶段的训练。将LGBM的预测结果作为一个特征加入到CNN中,对每个特征列保持相同的卷积核,最后再连一个全连接层,在NN里使用BN避免过拟合。最终平均7个CNN的结果作为最终结果。
其它magic
有看到可以通过将特征列 groupby 后求 方差var,并将方差加减原特征构成新的特征,400维统一放入到 lgb 中训练,当同时考虑加减并消去 fake 后可以取得 0.922的成绩。其实是变相的count,因为在groupby之后,unique的数据方差为0,只有count数较大的值才会有方差,anyway,也是一个比较有趣的思路。
收获
第一次尝试参赛,在末尾几天开始入场,自然没打算去取得好成绩,主要是疯狂去追 kernels 和看 Discussion,在比赛时段看和在结束之后看是两种不同的心态。在比赛结束之前,大部分人是比较焦虑的,Discussion 里有很多人发言,但是你也不能确定他们的idea是不是对的,只能用自己的知识和实践去推断,在这一期间,务必要保证自己的理智,多尝试与创新,而不要被误导到去钻牛角尖!在比赛后要做好比赛的回顾,因为比赛后有很多人会公布他们的思路和代码,这个时候就要去潜心学习下比你做的好的人的做法,反思不足,这样才能争取在之后的比赛中更进一步。
最后推荐几个kernels:
- 第一名的 kernel链接
- 号称actual winner的最早fake test提出者:kernel链接 ,可以说比赛时注意到这个kernel,银牌不是问题了
- 参赛期间看得一个kernel ,里面包行augmentation,代码风格不错,读起来挺舒服,可以在此基础上做自己的修改与尝试
- 第三名的 kernel链接
Kaggle之路,与强者为伍——记Santander交易预测的更多相关文章
- Kaggle比赛冠军经验分享:如何用 RNN 预测维基百科网络流量
Kaggle比赛冠军经验分享:如何用 RNN 预测维基百科网络流量 from:https://www.leiphone.com/news/201712/zbX22Ye5wD6CiwCJ.html 导语 ...
- python之路第二天 随便记记 今天主要很郁闷
为何要有操作系统 为了让程序员更轻松的完成命令电脑工作而存在的,控制硬件,服务于软件. 操作系统的位置 操作系统位于软件和硬件之间.操作系统由内核(运行于内核态,控制硬件)和系统调用(运行于用户态,为 ...
- 机器学习之路: python 朴素贝叶斯分类器 MultinomialNB 预测新闻类别
使用python3 学习朴素贝叶斯分类api 设计到字符串提取特征向量 欢迎来到我的git下载源代码: https://github.com/linyi0604/MachineLearning fro ...
- 《Python机器学习及实践:从零开始通往Kaggle竞赛之路》
<Python 机器学习及实践–从零开始通往kaggle竞赛之路>很基础 主要介绍了Scikit-learn,顺带介绍了pandas.numpy.matplotlib.scipy. 本书代 ...
- 数据分析-kaggle泰坦尼克号生存率分析
概述 1912年4月15日,泰坦尼克号在首次航行期间撞上冰山后沉没,2224名乘客和机组人员中有1502人遇难.沉船导致大量伤亡的原因之一是没有足够的救生艇给乘客和船员.虽然幸存下来有一些运气因素,但 ...
- HDU 6201 transaction transaction transaction(拆点最长路)
transaction transaction transaction Time Limit: 4000/2000 MS (Java/Others) Memory Limit: 132768/1 ...
- kaggle——绝地求生游戏最终排名预测
绝地求生游戏最终排名预测 知识点 数据读取与预览 数据可视化 构建随机森林预测模型 导入数据并预览 先导入数据并预览.本次实验同样来源于 Kaggle 上的一个竞赛: 绝地求生排名预测 ,由于原始数据 ...
- (十二)Maven生命周期和插件
除了坐标.依赖以及仓库之外,Maven的另外两个核心概念是生命周期和插件.在有关Maven的日常使用中,命令行的输入往往就对应了生命周期,如mvn package就表示执行默认生命周期阶段packag ...
- SPFA和FLOYD算法如何打印路径
早晨碰到了一题挺裸的最短路问题需要打印路径:vijos1635 1.首先说说spfa的方法: 其实自己之前打的最多的spfa是在网格上的那种,也就是二维的 一维的需要邻接表+queue 以及对于que ...
随机推荐
- #ifdef __cplusplus extern "C" { #endif 的解释
好多程序中都会遇到下列代码段: #ifdef __cplusplus extern "C" { #endif /****************** C语法代码段 ******** ...
- SQLServer中数据加密方法
对SQLServer中的数据进行加密,有三种方法, 1. 在程序语言中先对数据进行加密后再把加密后的数据保存在SQLServer数据库中: 2. 利用SQLServer未公开的加密密码函数,在SQ ...
- HTML5、CSS3与响应式Web设计入门(2)
HTML5的宽泛含义开拓了Web开发的视野,增加了开发方案的多样性,同时也带给很多Web开发者不小的困惑,就是HTML5在涉及到Web某个应用领 域的开发时,到底代表了什么?本篇文章的目的就在于跟大伙 ...
- LeeDUT个人WEB作品
*****目前大三前端狗一只,听说博客里写点记点能求OFFER***** 1.微云盘upan.oureda.cn 2013.10 微云盘是基于分布式系统.提供文件分享的校园存储站点,上传文件之后随即 ...
- system.data.oracleclient 需要 8.17 需要oracle客户端问题
1.下载 2.程序引用 Oracle.DataAccess.dll 其他引用放在debug下
- netcore中使用bower还原出错的解决方法
近期BitAdminCore框架在创建时,还原bower包出现502错 打开地址,发现原为是因为bower服务调整导致的. 果断处理: 1.通过管理员模式,启动命令行 2.进入npm所在目录 3.执行 ...
- MySQL多线程备份工具mydumper 之 RDS外部实例迁移平台
此文已由作者温正湖授权网易云社区发布. 欢迎访问网易云社区,了解更多网易技术产品运营经验. 1.Format_description_event问题: BINLOG ' kTXkUxMKAAAALQA ...
- 201621123023《Java程序设计》第8周学习总结
一.本周学习总结 二.书面作业 1. ArrayList代码分析 1.1 解释ArrayList的contains源代码 由图可知,传入参数后调用indexOf函数来判断是否存在,会循环整个eleme ...
- java中-的流-与操作
/* 字节输出流 OutputStrema: * OutputStream抽象类 * write(int b); 将指定的字节写入此流中 * write(byte[] b); ...
- Python数据采集处理分析挖掘可视化应用实例
距离上一次发Python的技术贴已经过去两年了,这两年大法初成,并在知乎谢了相关技术专栏.现在搬运如下,均为原创,转载需注明出处哦! https://zhuanlan.zhihu.com/p/2957 ...