Scikit-learn 之 预处理模块

一、预处理的作用
在机器学习任务中,学习器都会对数据有一定的要求,比如在最近邻算法中,我需要寻找与中心点最近邻的点,假设我们使用欧式距离度量,如果有一个属性值是千万量级,而另一个属性是100以内,那么如此计算的距离会严重依赖于大量级的属性,这对最后模型结果是有很大的影响的。总之,预处理的目的就是为了能够让学习器得到“干净”的数据。
二、Sklearn有哪些预处理方案
2.1. 标准化
2.1.1. 作用
对于很多学习器,一般都比较喜欢符合正态分布的数据,特别是标准正态分布(零均值单位方差),所以对此我们独立的对数据中的各个属性通过StandardScaler进行处理,从而符合近似标准正态分布。但并不是所有的数据这样处理是最合适的,针对有些数据其属性值的标准差很小,或者对于一些稀疏数据,可能通过MinMaxScaler或者MaxAbsScaler处理更合适。在机器学习任务中,会经常出现稀疏数据,对于稀疏数据一般采用的是CSR(Compressed Sparse Rows)或者CSC(Compressed Sparse Columns)进行存储,针对这类数据,采用MaxAbsScaler或者RobustScaler进行处理是非常合适的,因为它们并不会破环源数据的稀疏性,当然你也可以使用StandardScaler方法,但是必须传入参数with_mean=False,从而保证处理后的数据的稀疏性,同时也不会不经意间增加过大的内存占用。
2.1.2. Example及原理
[1]. StandardScaler
<1>. Example
在这里插入图片描述
在这里插入图片描述
<2>. 原理
均值
在这里插入图片描述方差
在这里插入图片描述
标准化后的数值为:
在这里插入图片描述
PS:此时计算的方差其实是有偏的,当数据量较大时,影响不大,但是当数据量较小时,需要转为无偏形式,也就是需要除以 (N-1)而非(N)。
[2].MinMaxScaler
<1>. Example
在这里插入图片描述
在这里插入图片描述
<2>. 原理
在这里插入图片描述
[3].MaxAbsScaler
<1>. Example
在这里插入图片描述
<2>. 原理
在这里插入图片描述
[4].RobustScaler
<1>. Example
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
<2>. 原理
(1)首先对各个属性中的数值进行升序排序
(2)如果with_centering参数为True,取各个属性的中值,即center_ = median
(3)如果with_scaling参数为True,根据参数quantile_range,计算各个属性的四分位数,最后scale_ = Q3 - Q1,即第三四分位数减去第一分位数
(4)最后标准化的数值
在这里插入图片描述
PS:RobustScaler中的quantile_range参数(Q1, Q3)指定了第一及第三四分位数的位置,默认为(25, 75),其计算公式为:
在这里插入图片描述
如果得到的结果为整数,那么该数对应的位置就是其相应四分位数(从1开始编号),如果不是整数,假设其在S和T位数值之间,那么越靠近某个数,则该数的权重越大。例如2.75在排序后的序列中的第2和第3个位置之间,且离第3个位置更近,其权重为0.75,则离第2个位置的权重为(1-0.75=0.25)。所以最终的四分位数为:0.25 V(2)+0.75 V(3),其中V(x)表示第x位置的数值。如果是2.25,那么离第2个位置更近,所以最终的四分位数为:0.75 V(2)+0.25 V(3)。
2.2. 非线性转换
2.1.1. 作用
将各个属性值转换到某个范围或者某一个分布上,因此适合对离群值的处理,但是因为是一个非线性转换,所以也改变了属性之间的距离及相关性特性。
2.1.2. Example
[1]. QuantileTransformer
2.3. 正规化
2.1.1. 作用
正规化是作用在一个样本上的,并非属性上,这对于计算属性之间的某些度量的情况下,是非常有作用的,比如计算样本之间的距离时。在正规化方法中,应用最广泛的时L1和L2范式。因为Normalizer方法是独立针对每个样本进行处理的,所以其fit方法是没有效果的。
2.1.2. Example及原理
[1]. Normalizer
<1>. Example
在这里插入图片描述
在这里插入图片描述
<2>. 原理
当norm=’max’ 时,则对每条样本取最大值,然后每条样本与其最大值相除即可
当norm=’l1’ 时,则对每条样本取其L1范数,然后每条样本与其相除即可
当norm=’l2’ 时,则对每条样本取其L2范数,然后每条样本与其相除即可
2.4. 二值化
2.1.1. 作用
二值化对每条样本中各个属性进行处理,当值大于设定的一个阈值threshold是,即为1,否则为0,其fit方法也不起作用,直接使用transform即可进行二值化处理,其作用主要是满足对下游的某些学习器的样本先验概率符合多变量Bernoulli Distribution的情况。
[1]. Binarizer
2.5. 编码类别特征
2.1.1. 作用
对于一些类别指标,本身是无序的,例如性别、国籍、城市等,如果我们直接从0开始依次编号,便不可避免的引入了有序的信息,这对下游的某些学习器是不利的,而OneHotEncoder便可以对其无序编码。
2.1.2. Example及原理
[1]. OneHotEncoder
<1>. Example
在这里插入图片描述
在这里插入图片描述
<2>. 原理
从上面的Example可以看出:
当不带参数n_values时,fit方法会得到各个属性的类别,当最后transform中的属性值在类别区间内,但是并不是某个类别,那么其编码后的值都为0,例如Example-2中的第二个属性,2在类别0和3之间,但是并不是其中某一个类别;如果transform中的属性值不在类别区间内,那么就会出现ValueError错误,例如Example-3。
当带参数n_values时,那么类别信息将通过n_values中的值确定,例如Example-4中,即使fit中的第二个属性有类别3,但是因为n_values的第二个属性类别数量为3,即只有三个类别{0,1,2},所以当transform中的第二个属性值为3时,将出现ValueError错误。
2.6. 缺失值处理
2.1.1. 作用
现实情境中,数据通常都会有缺失的情况,不管是对数据类似标准化、正则化或是喂给学习器,这都是不合理的,因此首先需要基于当前数据的信息对缺失值进行补充,而Imputer便可以解决该类问题,当前有基于均值、中值及众数来进行缺失值的补充。
PS: 在版本0.20之后,Imputer类将会废弃,并在0.22版本将其删除
2.1.2. Example
[1]. Imputer
在这里插入图片描述
在这里插入图片描述
2.7. 生成多项式特征
2.1.1. 作用
在一些场景中,我们需要构建更复杂的属性,或者我们需要了解属性之间的信息,或者属性数过少,为了更好构建模型,我们需要增加属性数,那么通过PolynomialFeatures便可以达到这个目的。
2.1.2. Example及原理
[1]. PolynomialFeatures
<1>. Example
在这里插入图片描述
在这里插入图片描述
<2>. 原理
假设一个样本含有两个属性[a, b],对其进行扩充,根据参数degree、interaction_only和include_bias进行控制
若include_bias为True,则会增加一列全为1的列
若interaction_only为True,则只会在属性之间进行构建
参数degree控制着属性构造数量,当degree=n,interaction_only=False,include_bias=True时,构造的属性为:
在这里插入图片描述
2.8. 定制Transformer
2.1.1. 作用
在数据清洗或者预处理过程中,针对具体业务场景,我们可能需要定制化一个预处理方案,那么就可以通过FunctionTransformer实现定制化
2.1.2. Example
在这里插入图片描述
在这里插入图片描述
三、重要概念
3.1. fit、transform和fit_transform
fit方法得到的还是一个预处理器,只有再进行transform后才表示按照指定的预处理器对数据进行了真正的处理,其返回预处理后的结果,而fit_transform将fit和transform两个操作都进行了,所以返回的是预处理后的结果。在机器学习任务中,我们一般会划分训练集和测试集,为了能够保证不同数据集的分布一致,其中需要注意的是我们需要对训练集及测试集采用的预处理方法应该保证一致,所以我们一般会对训练进行fit并保存此时的预处理器,然后用同一个预处理器对训练集及测试集进行transform。
PS:对于某些预处理器,fit方法并不起作用,例如Normalizer。

3.2. 稀疏数据的标准化
对于稀疏化数据,首先需要保证标准化后的数据仍然具有稀疏性,所以MaxAbsScaler可以应用在稀疏数据,对于StandardScaler,必须传入with_mean = False从而保证标准化后的数据稀疏性。

3.3. 预处理一般流程
1.缺失值处理
2.异常值处理
3.标准化
4.正则化
5.数据稀疏问题
6.是否降维处理
7.属性是否扩充

PS:本模块包含程序都在0.19.2版本的scikit-learn库中进行测试 Sklearn预处理模块都在sklearn.preprocesssing包中