Day3
sklearn中的数据预处理和特征工程
1概述
1.1数据预处理与特征工程
1.2sklearn中的数据预处理和特征工程
2 数据预处理 Preprocessing & Impute
2.1数据无量纲化
2.2缺失值
2.3处理分类型特征:编码与哑变量
2.4处理连续型特征:二值化与分段
3特征选择 feature_selection
3.1Filter过滤法
3.1.1方差过滤
3.1.1.1VarianceThreshold
3.1.1.2方差过滤对模型的影响
3.1.1.3选取超参数threshold
3.1.2相关性过滤
3.1.2.1卡方过滤
3.1.2.2选取超参数K
3.1.2.3F检验
3.1.2.4互信息法
3.1.2过滤法总结
3.2Embedded嵌入法
3.3Wrapper包装法
3.4特征选择总结
1 概述
1.1 数据预处理与特征工程
想象一下未来美好的一天,你成为一个精通各种算法和调参调库的数据挖掘工程师了。某一天你从你的同事,一位药物研究人员那里,得到了一份病人临床表现的数据。药物研究人员用前四列数据预测一下最后一数据,还说他要出差几天,可能没办法和你一起研究数据了,希望出差回来以后,可以有个初步分析结果。于是你就看了看数据,看着很普通,预测连续型变量,好说,导随机森林回归器调出来,调参调呀调,MSE很小,跑了个还不错的结果。
几天后,你同事出差回来了,准备要一起开会了,会上你碰见了和你同事在同一个项目里工作的统计学家。他问起你的分析结果,你说你已经小有成效了,统计学家很吃惊,他说:“不错呀,这组数据问题太多,我都分析不出什么来。”
你心里可能咯噔一下,忐忑地回答说:“我没听说数据有什么问题呀。”
统计学家:“第四列数据很坑爹,这个特征的取值范围是1~10,0是表示缺失值的。而且他们输入数据的时候出错,很多10都被录入成0了,现在分不出来了。”
你:”. “
统计学家:”还有第二列和第三列数据基本是一样的,相关性太强了。“
你:”这个我发现了,不过这两个特征在预测中的重要性都不高,无论其他特征怎样出错,我这边结果里显示第一 列的特征是最重要的,所以也无所谓啦。“
统计学家:“啥?第一列不就是编号吗?” 你:“不是吧。”
统计学家:“哦我想起来了!第一列就是编号,不过那个编号是我们根据第五列排序之后编上去的!这个第一列和 第五列是由很强的联系,但是毫无意义啊!”
老血喷了一屏幕,数据挖掘工程师卒。
这个悲惨又可爱的故事来自《数据挖掘导论》,虽然这是故事里的状况十分极端,但我还是想把这段对话作为今天这章的开头,博大家一笑(虽然可能听完就泪流满面了)。在过去两周,我们已经讲了两个算法:决策树和随机森林,我们通过决策树带大家认识了sklearn,通过随机森林讲解了机器学习中调参的基本思想,现在可以说,只要上过前面两堂课的,人人都会调随机森林和决策树的分类器了,而我呢,也只需要跟着各大机器学习书籍的步伐,给大家一周一个算法带着讲解就是了。如果这样的话,结果可能就是,大家去工作了,遇到了一个不那么靠谱的同事,给了你一组有坑的数据,最后你就一屏幕老血吐过去,牺牲在数据行业的前线了。
数据不给力,再高级的算法都没有用。
我们在课堂中给大家提供的数据,都是经过层层筛选,适用于课堂教学的——运行时间短,预测效果好,没有严重缺失等等问题。尤其是sklearn中的数据,堪称完美。各大机器学习教材也是如此,都给大家提供处理好的数据,这就导致,很多人在学了很多算法之后,到了现实应用之中,发现模型经常就调不动了,因为现实中的数据,离平时上课使用的完美数据集,相差十万八千里。所以我决定,少讲一两个简单的算法,为大家专门拿一堂课来讲解建模之前的流程,数据预处理和特征工程。这样大家即可以学到数据挖掘过程中很重要但是却经常被忽视的一些步骤,也可以不受课堂的限制,如果自己有时间,可以尝试在真实数据上建模。
数据挖掘的五大流程: |
数据预处理是从数据中检测,纠正或删除损坏,不准确或不适用于模型的记录的过程 可能面对的问题有:数据类型不同,比如有的是文字,有的是数字,有的含时间序列,有的连续,有的间断。也可能,数据的质量不行,有噪声,有异常,有缺失,数据出错,量纲不一,有重复,数据是偏态,数据量太大或太小 数据预处理的目的:让数据适应模型,匹配模型的需求
特征工程是将原始数据转换为更能代表预测模型的潜在问题的特征的过程,可以通过挑选最相关的特征,提取特征以及创造特征来实现。其中创造特征又经常以降维算法的方式实现。 可能面对的问题有:特征之间有相关性,特征和标签无关,特征太多或太小,或者干脆就无法表现出应有的数据现象或无法展示数据的真实面貌 特征工程的目的:1) 降低计算成本(例如删除对模型毫无贡献的特征)2) 提升模型上限
|
1.2 sklearn中的数据预处理和特征工程
sklearn中包含众多数据预处理和特征工程相关的模块,虽然刚接触sklearn时,大家都会为其中包含的各种算法的广度深度所震惊,但其实sklearn六大板块中有两块都是关于数据预处理和特征工程的,两个板块互相交互,为建模之前的全部工程打下基础。
模块preprocessing:几乎包含数据预处理的所有内容
模块Impute:填补缺失值专用
模块feature_selection:包含特征选择的各种方法的实践
模块decomposition:包含降维算法
2 数据预处理 Preprocessing & Impute
2.1 数据无量纲化
在机器学习算法实践中,我们往往有着将不同规格的数据转换到同一规格(比如都属于0-10),或不同分布的数据转换到某个特定分布(比如都正态分布)的需求,这种需求统称为将数据“无量纲化”。譬如梯度和矩阵为核心的算法中,譬如逻辑回归,支持向量机,神经网络,无量纲化可以加快求解速度;而在距离类模型,譬如K近邻,K-Means聚类中,无量纲化可以帮我们提升模型精度,避免某一个取值范围特别大的特征对距离计算造成影响。(一个特例是决策树和树的集成算法们,对决策树我们不需要无量纲化,决策树可以把任意数据都处理得很好。)
数据的无量纲化可以是线性的,也可以是非线性的。线性的无量纲化包括中心化(Zero-centered或者Mean- subtraction)处理和缩放处理(Scale)。
中心化的本质是让所有记录减去一个固定值,即让数据样本数据平移到某个位置。(例如将数据平移后使得图像以Y轴为对称轴)
缩放的本质是通过除以一个固定值,将数据固定在某个范围之中,取对数也算是一种缩放处理。(将图像压缩或变扁,可以改变取值范围)
·preprocessing.MinMaxScaler
当数据(x)按照最小值中心化后,再按极差(最大值 - 最小值)缩放,数据移动了最小值个单位,并且会被收敛到[0,1]之间,而这个过程,就叫做数据归一化(Normalization,又称Min-Max Scaling)。注意,Normalization是归一化,不是正则化,真正的正则化是regularization,不是数据预处理的一种手段。
归一化之后的数据服从正态分布(一种概率分布),归一化的具体作用是归纳统一样本的统计分布性
公式如下:
在sklearn当中,我们使用preprocessing.MinMaxScaler来实现这个功能。MinMaxScaler有一个重要参数,feature_range,控制我们希望把数据压缩到的范围,默认是[0,1]。(例如可以MinMaxScaler(feature_range=[5,10]) 将数据压缩范围改为[5,10])
当X中的特征数量非常多的时候,fit会报错并表示,数据量太大了我计算不了
此时使用partial_fit作为训练接口--->scaler = scaler.partial_fit(data)
#导入库 from sklearn.preprocessing import MinMaxScaler data = [[-1,2],[-0.5,6],[0,10],[1,18]] #大列表包含小列表 #不太熟悉numpy的小伙伴,能够判断data的结构吗? #如果换成表是什么样子 import pandas as pd pd.DataFrame(data) #4行2列 -->
#实现归一化(压缩后发现分布一致) #归一化的具体作用是归纳统一样本的统计分布性 #归一化按每列计算(x-min(x)/max(x)-min(x) 结果属于[0,1,例如第一列(-0.5)-(-1)/1-(-1) = 0.25 ) scaler = MinMaxScaler() #实例化 scaler = scaler.fit(data) #fit,在这里本质是生成min(x)和max(x) result = scaler.transform(data) #通过接口导出结果 result -->array([[0. , 0. ], [0.25, 0.25], [0.5 , 0.5 ], [1. , 1. ]]) #归一化(一步到位代码) result_ = scaler.fit_transform(data) #训练和导出结果一步达成 result_ -->array([[0. , 0. ], [0.25, 0.25], [0.5 , 0.5 ], [1. , 1. ]]) #归一化数据还原 scaler.inverse_transform(result) #将归一化的结果逆转 --> array([[-1. , 2. ], [-0.5, 6. ], [ 0. , 10. ], [ 1. , 18. ]]) #使用MinMaxScaler的参数feature_range实现数据归一化到[0,1]以外的范围中 data=[[-1,2],[-0.5,6],[0,10],[1,18]] scaler = MinMaxScaler(feature_range=[5,10]) #依然实例化 result = scaler.fit_transform(data) #fit_transform一步导出结果 result --> array([[ 5. , 5. ], [ 6.25, 6.25], [ 7.5 , 7.5 ], [10. , 10. ]]) #当X中的特征数量非常多的时候,fit会报错并表示,数据量太大了我计算不了 #此时使用partial_fit作为训练接口 #scaler = scaler.partial_fit(data) |
BONUS: 使用numpy来实现归一化
import numpy as np X = np.array([[-1, 2], [-0.5, 6], [0, 10], [1, 18]]) #对每一列归一化公式:x-min(x)/max(x)- min(x) X.min(axis=0) #返回每一列的最小值 -->array([-1., 2.]) X.max(axis=0) #返回每一列的最大值 -->array([ 1., 18.]) #归一化 X_nor = (X - X.min(axis=0)) / (X.max(axis=0) - X.min(axis=0)) X_nor -->array([[0. , 0. ], [0.25, 0.25], [0.5 , 0.5 ], [1. , 1. ]]) #逆转归一化 X_returned = X_nor * (X.max(axis=0) - X.min(axis=0)) + X.min(axis=0) X_returned -->array([[-1. , 2. ], [-0.5, 6. ], [ 0. , 10. ], [ 1. , 18. ]]) |
·preprocessing.StandardScaler
当数据(x)按均值(μ)中心化后,再按标准差(σ)缩放,数据就会服从为均值为0,方差为1的正态分布(即标准正态分布),而这个过程,就叫做数据标准化(Standardization,又称Z-score normalization),公式如下:
#导入库 from sklearn.preprocessing import StandardScaler data=[[-1,2],[-0.5,6],[0,10],[1,18]] scaler = StandardScaler() #实例化 scaler.fit(data) #此处fit本质是生成均值和方差 scaler.mean_ #查看均值的属性mean_(两列数据分别的均值) -->array([-0.125, 9. ]) scaler.var_ #查看方差的属性var_ (两节数据分别的方差) -->array([ 0.546875, 35. ]) x_std = scaler.transform(data) #通过接口导出结果 x_std -->array([[-1.18321596, -1.18321596], [-0.50709255, -0.50709255], [ 0.16903085, 0.16903085], [ 1.52127766, 1.52127766]]) x_std.mean() #mean()查看均值,此时已为0 -->0 x_std.std() #std()查看方差,此时为1 -->1.0 scaler.inverse_transform(x_std) ##使用inverse_transform逆转标准化 -->array([[-1. , 2. ], [-0.5, 6. ], [ 0. , 10. ], [ 1. , 18. ]]) |
对于StandardScaler(标准化)和MinMaxScaler(归一化)来说,空值NaN会被当做是缺失值,在fit的时候忽略,在transform的时候 保持缺失NaN的状态显示。并且,尽管去量纲化过程不是具体的算法,但在fit接口中,依然只允许导入至少二维数组,一维数组导入会报错(因为默认处理特征矩阵,通常来说输入特征矩阵都是一维以上)。通常来说,我们输入的X会是我们的特征矩阵,现实案例中特征矩阵不太可能是一维所以不会存在这个问题。
·StandardScaler和MinMaxScaler选哪个?
看情况。大多数机器学习算法中,会选择StandardScaler(标准化)来进行特征缩放,因为MinMaxScaler对异常值(例如大多数为1-10,但有一个100,MinMaxScaler取最大值时会选100,从而会导致很大的误差)非常敏感。在PCA,聚类,逻辑回归,支持向量机,神经网络这些算法中,StandardScaler往往是最好的选择。
MinMaxScaler在不涉及距离度量、梯度、协方差计算以及数据需要被压缩到特定区间时使用广泛,比如数字图像处理中量化像素强度时,都会使用MinMaxScaler将数据压缩于[0,1]区间之中。
建议先试试看StandardScaler,效果不好换MinMaxScaler。
除了StandardScaler和MinMaxScaler之外,sklearn中也提供了各种其他缩放处理(中心化只需要一个pandas广播一下减去某个数就好了,因此sklearn不提供任何中心化功能)。比如,在希望压缩数据,却不影响数据的稀疏性时(不影响矩阵中取值为0的个数时),我们会使用MaxAbsScaler;在异常值多,噪声非常大时,我们可能会选用分位数来无量纲化,此时使用RobustScaler。更多详情请参考以下列表。
2.2缺失值
机器学习和数据挖掘中所使用的数据,永远不可能是完美的。很多特征,对于分析和建模来说意义非凡,但对于实际收集数据的人却不是如此,因此数据挖掘之中,常常会有重要的字段缺失值很多,但又不能舍弃字段的情况。因此,数据预处理中非常重要的一项就是处理缺失值
import pandas as pd #index_col=0即把第一列当作索引,否则第一列(0,1,2...)会 |