前言
主要是过去一年做事情没有一个系统化的概念,今年就想就此改变一下。先从写笔记开始,将我这学期学习到的东西,参加的比赛,写出来,算是过路有痕。
比赛大部分应该不是我自己一个人参加的,分工合作嘛,那我就把自己做的写出来,详细点;了解了一点东西,写下来,以后就可以更加深入学习了。同学做的,写出来,简略一下,不过我也尝试了解一下他们的思想,下次去实现一下。
不一次性写完,尽量想写得详细一些。写完的就画勾勾,没写完就继续写,反正养成记录的习惯。(我的碎碎念
我写的代码后面也跟着整理出来(就算是辣鸡我也要整理出来!
文件导读
-
data_preprocessed.ipynb
数据预处理:1 先处理年龄,2 再去除重复列
-
data_visualization.ipynb
数据可视化,查看train与test数据集的各个特征的分布
- 导入包
- 导入数据
- 查看数据描述
- 打印现有的列(特征)
- 小牛初试:尝试将年龄分组,并且可视化,查看分布
- 编写函数
- 查看数据取值个数,使用unique, 取值 > 100 为连续,否则为离散。
- 离散可视化
- 连续可视化
- 抽出一个特征检测是否正确
-
oversampler.ipynb
因为正负样本不平衡,过采样数据,最后两类数据比例差不多
- 读取数据
- 拆分数据为X, y
- 随机采样数据
- 合并数据
- 导出数据
- 检查数据是否导入正确
-
feature_gene_overampled.ipynb
特征衍生:对过采样后的数据,进行变量衍生
这个是train数据的,还有一个test
test.gene.ipynb
,其实这个做的不好,应该在上面train
的文件一起完成的,TODO. -
RandomForest.ipynb
随机森林的粗调参,还被我打断了呜呜,简单记录。
主要流程(已修改)
-
获取数据,
官网下载即可。
-
EDA 探索性数据分析
-
数据预处理:缺失值、异常值
-
数据规约:数据转换,最大最小值,标准化,0-1标准化
俺们没做,可能是考虑到数据之间差异太大,有一个特征,只有两种取值99和999,暂时没有去想如何规约。
-
数据预处理:样本不平衡,
数据采样,欠采样/过采样/SMOTE
-
特征生成,
连续变量加减乘除
-
特征选择,
使用的相关系数和VIF筛选,尝试过随机选择,
-
模型选择,
主要是LightGBM,XGboost, RandomForest, SVM
-
调参-四种方法
1 手动调参,要有经验(自己,或者某一方面上网搜索),2 网格搜索(常用)3 随机搜索,4 贝叶斯调优
-
模型评估,
这方面没有多大的精进,主要还是之前了解到的四种,precision, accuracy, recall, auc, F1-score,混淆矩阵
多的可能是MSE,MAE(还仅仅是记住了名字)
交叉验证:Kfold,
路过有痕(我做的
1— 观察当前数据特征:无缺失数据,有异常值,年龄
本数据情况:
-
无缺失值
-
有异常值
我们:没有剔除train和test的异常值。
为什么?因为一些异常值,在test中也有,如果剔除了这些,不知道如何处理test中的**”新鲜“**的数据。
代码在data_preprocessed.ipynb
2—: 数据预处理:尝试处理了一下年龄
年龄需要转换为多少岁(pd.to_datetime
),在训练集中有一个异常值(pd.to_datetime
转换有问题的)。我们处理的,有两种,一种是将那个数除以100, 另一种情况,直接手动改成年月日,进行转换。
同在data_preprocessed.ipynb
3— EDA数据可视化,对比train, test数值分布
为什么要做这一步?
如果不同,我们可能要进行采样,保证训练的数据能够匹配到测试的数据。因为我们是想要更好地预测test的数据嘛。
代码在data_visualization.ipynb
4— 特征工程:连续变量(特征衍生)和离散变量的特征处理,离散的特征分箱、无序变量one-hot编码,WOE编码等(俺们没做,未深入了解,知道这个概念)
特征衍生,代码在feature_gene_oversampled.ipynb
(train 的变量) test_gene.ipynb
(test的变量)
特征筛选(按照相关系数,取50%),代码同上,俺放一起了。
连续变量需要进行规约(标准化、归一化、最大最小值),对于一般的传统基于数值计算分类的方法而言,不同的量纲对构造的模型影响很大,决策树除外。
无序变量如果之间差异值比较大的话,就一般的分类方法而言,最好进行one–hot编码,或者尝试其他的数据处理方法,将数据变成大小上无差异的数据,数据的不同仅仅用于比较数据之间的差异。
form sklearn import preprocessing
enc = preprossing.OneHotEncoder
enc.fit([[0,0,3],[1,1,0],[0,2,1],[1,0,2]])
array = enc.transform([[0,1,3]]).toarray()
print(array)
5— 数据采样
过采样,简单随机过采样(过采样,样本是有random获取的
什么情况下需要采样:比如说分类数据,两类或者多类之间数据不平衡,100:1这种就需要对数据进行采样处理,这样才能够避免有的模型为了提高模型的准确度而将所有的模型都预测为多的那一类。
6— 特征工程中的特征生成(特征衍生):
此处所写衍生方法为:1 数学运算。
还有2 二值化,将数据根据是否是某一规则分为0和1,3特征离散化,比如年龄连续变量,对其进行分箱。可以削弱异常值的影响。
对连续变量加减乘除,先找到变量之间的组合,再加减乘除,一个小细节:两个特征a/b, b/a是不一样的
以上是简单的特征生成。如果有对数据了解,提前知道数据之间的复杂的数据关系,可以先对这些数据进行数学运算,从而生成新的特征。
搜索关键词:(特征工程)变量衍生
其他:
特征衍生一般是对原有的特征进行转换,计算以及组合而产生的新的特征。
- 单一变量的基础转换,比如通过对单一变量进行平方,开根号,log转换等。
- 变量通过添加时间维度进行衍生,比如3个月交易数据,6个月交易数据等。
- 多变量的运算,比如两个变量相加,相乘或变量间计算一个比率后得到新变量。
当然特征衍生的方式各种各样,具体还是要看业务场景的需要,然后做相应的处理。
7— 特征选择:相关系数筛选特征,去除50%
这里考虑的是与你预测的标签之间的相关关系,
Pearson相关系数
Spearman等级相关系数
Kendall相关系数。
sklearn分别有相关的参数。
8— 随机森林调参
主要使用贝叶斯调优,还有其他1 人工调优(经验),2网格搜索法,3随机搜索。
我了解到的同学做的
-
数据预处理:关于年龄的处理,
当初我们得到的是出生年月,类似于
1038672000
这样的数据,需要使用pd.to_datetime
转换。转换过程也并不是那么顺利,有一个数据,报错说大致是当前数据并不是pd.to_datetime
能处理的,这里同学好像是直接对一场数据设定一个值。我自己尝试尝试,就对一个数据190,364,572,800
, 一般是1,330,531,200
. 前者是异常数据,后者是正常数据。我是将前者(异常数据)除以1000
来对应到正常数据的。说一下我处理的思路:首先根据数据的描述最大值
190,364,572,800
, 最小值31,507,200
,然后就随机想要往正常数据靠齐,我这种思想很正常吧… -
EDA 对比train中所有正负样本比例分布
-
XGboost模型、调参,catboost模型、调参尝试
-
模型 LightGBM模型拟合,调参
-
特征选择:模型拟合VIF来筛选20%的变量,剩下30%的变量
做的不好,还可以改进的:
- 开始尝试了使用嵌入法来进行特征筛选,但是最后在应用特征时,却没有使用当前数据,最后甚至就没管
- 因为模型的数据不平衡,在最后尝试了一次数据采样(随机过采样),但是在后来进行模型训练的时候却没有利用
- 数据不平衡,尝试采样方法简单,可以再采样的
- 调参:尝试的调参方法大多是网格搜索法
sklearn.model_selection
中的GridSearchCV
包,但是没有考虑其他三种调参的方法1 手动调参 2 随机搜索,3 贝叶斯优化
其他关于团队合作的:
- 队长很会分工任务,根据每个队员的特点分配任务,而且后来总结评价分配任务的能力不错
- 比赛是年前开始的,在快过年以及过年后10多天大家都没有再讨论比赛,导致对最开始的数据以及模型生疏,这是导致最后比赛效果很久没有提高的一个很重要的影响因素
- 但是在其他时间,队长都积极调动成员去完成分析任务。比如设置截至deadline,(这是提高我学习效率的最好办法了。
- 其实最后做的也不错。虽说最后为比赛结尾只用了差不多5天的时间,正是因为时间短,想要在短时间内提高学习效率,所以最后学习到的实操知识还是挺多的。就我自己而言,我捡起了之前分解任务,列点学习的习惯,这个习惯丢好久了,但是确实是很有用。
最后
不太系统的学习,一个团队的一小部分,但是也确实学习到了很多的东西,数据分析的流程,一些学习的方法,学习数据预处理、特征选择、模型选择、模型评估时,目标性更强,一个理论很重要,但同样它的实现(最好是有库可调用/可自主写python代码实现)是非常重要的。
还有需要补充的,我一点点写,写完了就将这段话删掉!