作者:章华燕
编辑:徐松
Scikit-learn实战之数据预处理
——Data Preprocessing
各位看官,我们又见面了,
今天我们继续学习开源包
Scikit-learn
功能之数据预处理
一、数据预处理之重要性和必要性:
对于Scikit-learn中实现的许多机器学习估计来说,对数据集进行规范化是一个通用的需求。如果个别的特征或多或少的不服从与通常的数据分布:例如标准正态分布(均值为0,方差为1),这时算法的效果可能会表现得很差。 实际应用中,我们经常忽略数据分布的形状而仅仅将数据在每个维度特征的均值去除以使其数据集中,然后通过除以某个非常量的方差进行比例化。 例如,在一个机器学习的目标函数中使用的许多元素被假设为以零为中心并且在相同的阶上具有相同的方差。如果某一特征的幅值方差大于其它的特征,他可能会支配目标函数并且使得算法不能够按照我们期望的从其他的特征维度进行学习。
在Scikit-learn中的sklearn.preprocessing包提供了一些公共的实用函数和转换类来将特征行向量转换成更适合于接下来的估计的表示。那么具体如何实现的呢?接着往下看。
二、数据标准化的常用几种方法:
2.1 标准化预处理:
又叫正态化处理,使处理后的样本数据,均值为0方差为1.
具体代码
代码语言:javascript复制>>> from sklearn import preprocessing
>>> import numpy as np
>>> X = np.array([[ 1., -1., 2.],
... [ 2., 0., 0.],
... [ 0., 1., -1.]])
>>> X_scaled = preprocessing.scale(X)
>>> X_scaled
array([[ 0. ..., -1.22..., 1.33...],
[ 1.22..., 0. ..., -0.26...],
[-1.22..., 1.22..., -1.06...]])
标准化后:
代码语言:javascript复制>>> X_scaled.mean(axis=0)
array([ 0., 0., 0.])
>>> X_scaled.std(axis=0)
array([ 1., 1., 1.])
2.2 将特征缩放到一个范围:
一个可供选择的标准化方法是缩放特征到一个给定最大值和最小值之间,经常这个给定的最大值和最小值取值为 0 和 1,或者对每个特征的最大值得绝对值进行归一化。这两种操作可以由MinMaxScaler 和 MaxAbsScaler 来实现。
具体代码
代码语言:javascript复制>>> X_train = np.array([[ 1., -1., 2.],
... [ 2., 0., 0.],
... [ 0., 1., -1.]])
>>> min_max_scaler = preprocessing.MinMaxScaler()
>>> X_train_minmax = min_max_scaler.fit_transform(X_train)
>>> X_train_minmax
array([[ 0.5 , 0. , 1. ],
[ 1. , 0.5 , 0.33333333],
[ 0. , 1. , 0. ]])
如果 MinMaxScaler 被指定一个确切的范围 [ min , max ],完整的计算公式如下:
X_std = (X - X.min(axis=0)) / (X.max(axis=0) - X.min(axis=0))
X_scaled = X_std / (max - min) min
2.3 稀疏矩阵的缩放:
中心化稀疏数据将会破坏数据的稀疏性,因此这是一件敏感的事情。然而,缩放稀疏输入是有意义的,尤其是特征在不同的尺度上时。
MaxAbsScaler 和 maxabs_scale 是专门为缩放稀疏数据设计的,并且这是被推荐的方法。然而, scale 和 StandardScaler可以接受scipy.sparse矩阵作为输入,只要with_mean=False显试的传递给了构造函数。否则一个ValueError异常将会被抛出。注意,缩放类既接受被压缩的行稀疏矩阵又接受被压缩的列稀疏的矩阵结构(参看scipy.sparse.csr_matrix 和 scipy.sparse.csc_matrix)。任何其它的稀疏输入都会被转化成压缩的行表示。为了避免不必要的内存复制,推荐选择CSR 或者 CSC 表示输入流。
最后,如果希望中心化的数据足够小,那么一个可选的方案就是可以使用稀疏矩阵的toarray方法来将输入转化成一个矩阵。
2.4 缩放具有异常点的数据:
如果你的数据包含很多异常点,那么使用均值和方差来缩放数据似乎效果不是很好。在这种情况下,你可以使用 robust_scale 和 RobustScaler 来替代。他们使用更鲁棒的方法来估计数据的中心和范围。
三、归一化:
归一化是将单个的样本缩放到统一规范的处理过程。如果你想使用二次形式例如点积或者任何其他的核来度量两个样本的相似性的话,这个处理过程非常有用。 这个假设是基于向量空间模型经常被使用于文本分类或者聚类的环境中。函数 normalize提供了一个快速和简单的方法在一个类数组的数据集上来执行该操作,使用 L1 或者L2 范式。
具体代码
代码语言:javascript复制>>> X = [[ 1., -1., 2.],
... [ 2., 0., 0.],
... [ 0., 1., -1.]]
>>> X_normalized = preprocessing.normalize(X, norm='l2')
>>> X_normalized
array([[ 0.40..., -0.40..., 0.81...],
[ 1. ..., 0. ..., 0. ...],
[ 0. ..., 0.70..., -0.70...]])
preprocessing 模块进一步提供了一个有用的类 Normalizer 来使用 Transformer API(尽管它的fit方法在这种情况下是没有用的)来实现相同的操作。因此该类适合于在 sklearn.pipeline.Pipeline 之前的步骤使用。
代码语言:javascript复制>>> normalizer = preprocessing.Normalizer().fit(X) # fit does nothing
>>> normalizer
Normalizer(copy=True, norm='l2')
这个归一化实例可以在后续的样本向量中作为任何转换器来使用:
代码语言:javascript复制>>> normalizer.transform(X)
array([[ 0.40..., -0.40..., 0.81...],
[ 1. ..., 0. ..., 0. ...],
[ 0. ..., 0.70..., -0.70...]])
>>> normalizer.transform([[-1., 1., 0.]])
array([[-0.70..., 0.70..., 0. ...]])