首页 > sklearn 阅读数:4

Sklearn数据预处理方法汇总

预处理指对数据进行清洗、转换等处理,使数据更适合机器学习的工具。Scikit 提供了一些预处理的方法,分别是标准化、非线性转换、归一化、二值化、分类特征编码、缺失值插补、生成多项式特征等,如图 1 所示。

sklearn数据预处理
图1:预处理相关方法

1. 标准化

为什么要对数据进行标准化处理呢?在表 2 中可以看到收入这一列的数字特别大,而年龄这一列数字相比之下就特别小。因此,在某些机器学习过程中,收入特征就会表现得比较“抢眼”,而影响最终的模型效果。

标准化前的收入与年龄
图2:标准化前的收入与年龄
 
所以我们要将这种差距去除,让大家在同一起跑线上。因此,将该表转换成另一种形式,如表 3 所示,转换方法为 scale 方法。

标准化后的收入与年龄
图2:标准化后的收入与年龄

在 Scikit 中提供了 scale 方法对数据进行标准化,处理流程如下:

1) 导入相关模块

In [1]: from sklearn import preprocessing
   ...: import numpy as np

2) 导入相关数据

下面我们都将以上述表格的数据为例:
In [2]: X= np.array([[7688,32],
   ...:              [5788,29],
   ...:              [4600,25],
   ...:              [8900,35]]) 

3) 将数据标准化

In [3]: X_scaled = preprocessing.scale(X)

4) 查看标准化结果

In [4]: X_scaled
Out[4]: 
array([[ 0.56796035,  0.47301616],
       [-0.57518019, -0.33786869],
       [-1.28994385, -1.41904849],
       [ 1.29716369,  1.28390102]])

5) 查看标准化后的均值

In [5]: X_scaled.mean()
Out[5]: -5.551115123125783e-17

6) 查看标准化后的标准差

In [6]: X_scaled.std()
Out[6]: 1.0 

2. 非线性转换

非线性转换类似于标准化处理,是将数据映射到 [0,1] 的均匀分布上。非线性转换将每个特征转换到相同的范围内或者分布内,使异常的数据变得平滑,受异常值的影响就会变小,但是这在一定程度上改变了特征内部和特征之间的距离和

1)导入相关模块

In [1]: from sklearn import preprocessing
   ...: import numpy as np
2) 创建非线性转换对象
In [2]: quantile= preprocessing.QuantileTransformer(random_state=0)

3) 导入相关数据

In [3]: X= np.array([[7688,32],
   ...:              [5788,29],
   ...:              [4600,25],
   ...:              [8900,35]])

4)进行线性转换

In [4]: X_trans=quantile.fit_transform(X)

5) 查看线性转换的结果

所有的数值都被转换为[0,1]区间内的数字
In [5]: X_trans
Out[5]: 
array([[6.66666667e-01, 6.66666667e-01],
       [3.33333333e-01, 3.33333333e-01],
       [9.99999998e-08, 9.99999998e-08],
       [9.99999900e-01, 9.99999900e-01]]) 

3 .归一化

归一化的作用是缩放单个样本,使其具有单位范数。归一化有两种方式,分别是范数“L1”和范数“L2”。

1) 导入相关模块

In [1]: from sklearn import preprocessing
   ...: import numpy as np

2) 导入相关数据

In [2]: X= np.array([[7688,32],
   ...:              [5788,29],
   ...:              [4600,25],
   ...:              [8900,35]])

3) 归一化数据


In [3]: X_norm = preprocessing.normalize(X, norm='l2')

4. 查看的结果

要注意归一化针对的是每一行
In [4]: X_norm
Out[4]: 
array([[0.99999134, 0.00416229],
       [0.99998745, 0.0050103 ],
       [0.99998523, 0.0054347 ],
       [0.99999227, 0.00393255]])

4. 二值化

二值化的作用是将数值型的特征值转换为布尔型。

1) 导入相关模块

In [1]: from sklearn import preprocessing
   ...: import numpy as np

2) 导入相关数据

In [2]: X= np.array([[7688,32],
   ...:              [5788,29],
   ...:              [4600,25],
   ...:              [8900,35]])

3) 查看最后的编码结果

可以看到所有大于 100 的数字都被编码为 1,所有小于 100 的数字都被编码为0。
In [3]: binary = preprocessing.Binarizer(threshold=100)

4) 查看相关结果

In [4]: binary
Out[4]: 
array([[1, 0],
       [1, 0],
       [1, 0],
       [1, 0]])

5. 分类特征编码

在机器学习过程中,我们经常会遇到字符串形式的特征。这时就需要将这些字符串类型的特征转换为数值型的特征。例如,“老师”“学生”“主任”,我们需要将这些字符串转换为整数,比如将“老师”转换为 0,将“学生”转换为 1,将“主任”转换为 2。

这样的转换会提高机器学习的计算效率,但是这样连续数值的输入会被分类器认为类别之间是有序的,然而实际上“老师”“学生”“主任”之间是无序的,而且没有大小的区别,这时就需要将这些数值进一步转换。

对此的解决思路就是将某个特征的 n 个可能转换为 n 个特征,转换后的特征是 0/1 二值数据。

1) 导入相关模块

In [1]: from sklearn import preprocessing 
 ...: import numpy as np

2) 创建One-Hot编码对象

In [2]: enc = preprocessing.OneHotEncoder()
3) 导入模拟的数据
In [3]: X= np.array([[0,4],
   ...:              [1,5],
   ...:              [2,6],
   ...:              [3,7]])

4) 训练One-Hot编码对象

In [4]: enc.fit(X)
Out[4]: 
OneHotEncoder(categorical_features='all', dtype=<class 'numpy.float64'>,
       handle_unknown='error', n_values='auto', sparse=True)

5) 查看编码后的结果


从 In[3] 中可以看到第一列有 4 种情况,分别为 0、1、2、3,所以第一列会被分为4列。
0表示为[1,0,0,0],

1表示为[0,1,0,0],

2表示为[0,0,1,0],

3表示为[0,0,0,1]。
同样的道理,第二列也被分为 4 列:4 表示为 [1,0,0,0],5 表示为 [0,1,0,0],6 表示为 [0,0,1,0],7 表示为 [0,0,0,1]。
In [5]: enc.transform(X).toarray()
Out[5]: 
array([[1., 0., 0., 0., 1., 0., 0., 0.],
       [0., 1., 0., 0., 0., 1., 0., 0.],
       [0., 0., 1., 0., 0., 0., 1., 0.],
       [0., 0., 0., 1., 0., 0., 0., 1.]])

6. 缺失值插补

直接获得的数据不一定是完整的数据,里面可能存在缺失的情况。需要对这些有缺失的数据做一些处理,以补全它们。

1) 导入相关模块

In [1]: import numpy as np
   ...: from sklearn.preprocessing import Imputer

2) 创建插值对象

In [2]: imp = Imputer(missing_values='NaN', strategy='mean', axis=0)

3) 导入相关数据

In [3]: X= np.array([[0,4],
   ...:              [np.NaN,5],
   ...:              [np.NaN,6],
   ...:              [3,7]])

4) 训练插值模块

In [4]: imp.fit(X)
Out[4]: Imputer(axis=0, copy=True, missing_values='NaN', strategy='mean', verbose=0)

5) 进行转换

在 axis=0 的情况下,第一列有两个非空值,他们的均值是 1.5,所以空值全部都用 1.5 填充。
In [5]: imp.transform(X)
Out[5]: 
array([[0. , 4. ],
       [1.5, 5. ],
       [1.5, 6. ],
       [3. , 7. ]])

7. 生成多项式特征

在机器学习中,有些时候数据集的特征很少,这时就需要自己根据已有的特征构造一些新的特征。

1) 导入相关模块

In [1]: import numpy as np
   ...: from sklearn.preprocessing import PolynomialFeatures

2) 创建多项式特征对象

In [2]: poly = PolynomialFeatures(2)

3) 导入相关数据

In [3]: X= np.array([[0,4],
   ...:              [1,5],
   ...:              [2,6],
   ...:              [3,7]])
4) 训练多项式特征对象
In [4]: poly.fit(X)
Out[4]: PolynomialFeatures(degree=2, include_bias=True, interaction_only=False)

5) 将原数据转换为多项式

X 的特征已经从 (x1,x2) 转换为如下所示:
转换结果
In [5]: poly.transform(X)
Out[5]: 
array([[ 1.,  0.,  4.,  0.,  0., 16.],
       [ 1.,  1.,  5.,  1.,  5., 25.],
       [ 1.,  2.,  6.,  4., 12., 36.],
       [ 1.,  3.,  7.,  9., 21., 49.]])