页面树结构

2017-11-09 ApacheCN 开源组织,第二期邀请成员活动,一起走的更远 : http://www.apachecn.org/member/209.html


MachineLearning 优酷地址 : http://i.youku.com/apachecn

转至元数据结尾
转至元数据起始

sklearn.preprocessing软件包提供了几种常见的效用函数和变换器类,以将原始特征向量更改为更适合下行估计器的表示。

标准化或平均去除和方差缩放

数据集的标准化是在scikit-learn实现的许多机器学习估计器常见要求 ; 如果个别特征不是或多或少地看起来像标准正态分布的数据,那么它们可能会表现不好:具有零均值和单位方差的高斯。

实际上,我们经常忽略分布的形状,只是通过去除每个特征的平均值将数据转换为中心,然后通过将非常数特征除以其标准偏差进行分类。

例如,用于学习算法(例如支持向量机的RBF内核或线性模型的l1和l2正则化器)的目标函数中使用的许多元素假定所有特征都以零为中心并且具有相同顺序的方差。如果特征的方差大于其他数量级,则可能主导目标函数,使得估计器无法按预期正确地学习其他特征。

该函数scale提供了一种快速简单的方法来在单个阵列数据集上执行此操作:

>>> 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...]])

缩放数据的平均值和单位方差为零:

>>> X_scaled.mean(axis=0)
array([ 0.,  0.,  0.])

>>> X_scaled.std(axis=0)
array([ 1.,  1.,  1.])

preprocessing模块进一步提供一个实用程序类 StandardScaler,它实现TransformerAPI来计算训练集上的平均值和标准偏差,以便能够稍后在测试集上重新应用相同的变换。因此,这个课程适合在早期的一个步骤中使用 sklearn.pipeline.Pipeline

>>> scaler = preprocessing.StandardScaler().fit(X)
>>> scaler
StandardScaler(copy=True, with_mean=True, with_std=True)

>>> scaler.mean_                                      
array([ 1. ...,  0. ...,  0.33...])

>>> scaler.scale_                                       
array([ 0.81...,  0.81...,  1.24...])

>>> scaler.transform(X)                               
array([[ 0.  ..., -1.22...,  1.33...],
       [ 1.22...,  0.  ..., -0.26...],
       [-1.22...,  1.22..., -1.06...]])

然后,缩放器实例可以用于新数据,以与在培训集上所做的相同的方式进行转换:

>>> scaler.transform([[-1.,  1., 0.]])                
array([[-2.44...,  1.22..., -0.26...]])

可以通过传递with_mean=Falsewith_std=False构造函数来禁止对中或缩放StandardScaler

将功能扩展到范围

替代的标准化是将特征缩放到给定的最小值和最大值之间,通常在零和一之间,或者使得每个特征的最大绝对值被缩放到单位大小。这可以分别使用MinMaxScalerMaxAbsScaler分别实现。

使用此缩放的动机包括对特征的非常小的标准偏差的鲁棒性,以及在稀疏数据中保留零条目。

以下是将玩具数据矩阵缩放到范围的示例:[0, 1]

>>> 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.        ]])

然后,变压器的相同实例可以应用于拟合调用期间看不到的一些新的测试数据:相同的缩放和移位操作将被应用于与在列车数据上执行的变换一致:

>>> X_test = np.array([[ -3., -1.,  4.]])
>>> X_test_minmax = min_max_scaler.transform(X_test)
>>> X_test_minmax
array([[-1.5       ,  0.        ,  1.66666667]])

可以对缩放器属性进行内省,以了解训练数据上学到的转换的确切性质:

>>> min_max_scaler.scale_                             
array([ 0.5       ,  0.5       ,  0.33...])

>>> min_max_scaler.min_                               
array([ 0.        ,  0.5       ,  0.33...])

如果MinMaxScaler给出一个明确的全部公式是:feature_range=(min, max)

X_std = (X - X.min(axis=0)) / (X.max(axis=0) - X.min(axis=0))

X_scaled = X_std / (max - min) + min

MaxAbsScaler以非常相似的方式工作,但是以训练数据位于范围内,通过划分每个特征中最大的最大值来缩放。它是针对已经以零或稀疏数据为中心的数据。[-1, 1]

以下是使用这个缩放器的上一个示例中的玩具数据的方法:

>>> X_train = np.array([[ 1., -1.,  2.],
...                     [ 2.,  0.,  0.],
...                     [ 0.,  1., -1.]])
...
>>> max_abs_scaler = preprocessing.MaxAbsScaler()
>>> X_train_maxabs = max_abs_scaler.fit_transform(X_train)
>>> X_train_maxabs                # doctest +NORMALIZE_WHITESPACE^
array([[ 0.5, -1. ,  1. ],
       [ 1. ,  0. ,  0. ],
       [ 0. ,  1. , -0.5]])
>>> X_test = np.array([[ -3., -1.,  4.]])
>>> X_test_maxabs = max_abs_scaler.transform(X_test)
>>> X_test_maxabs                 
array([[-1.5, -1. ,  2. ]])
>>> max_abs_scaler.scale_         
array([ 2.,  1.,  2.])

与此同时scale,该模块还提供了便利功能 minmax_scalemaxabs_scale如果您不想创建一个对象。

缩小稀疏数据

居中的稀疏数据将破坏数据中的稀疏结构,因此很少是一件明智的事情。然而,缩放稀疏投入是有意义的,特别是如果特征在不同的尺度上。

MaxAbsScaler 并且maxabs_scale专门用于缩放稀疏数据,并且是推荐的方法。然而,scaleStandardScaler可以接受scipy.sparse 的矩阵作为输入,只要with_mean=False明确地传递给构造函数。否则,ValueError将会提出一个默默的中心将打破稀疏性,并且经常会无意中分配过多的内存而使执行崩溃。 RobustScaler不能适应稀疏输入,但可以使用transform稀疏输入的方法。

请注意,缩放器接受压缩稀疏行和压缩稀疏列格式(参见scipy.sparse.csr_matrix和 scipy.sparse.csc_matrix)。任何其他稀疏输入将被转换为压缩稀疏行表示。为了避免不必要的内存复制,建议在上游选择CSR或CSC表示。

最后,如果预期中心数据足够小,则使用toarray稀疏矩阵的方法将输入显式转换为数组是另一种选择。

用异常值缩放数据

如果您的数据包含许多异常值,则使用数据的均值和方差进行缩放可能无法正常工作。在这种情况下,您可以使用 robust_scaleRobustScaler替换为替换。他们对您的数据的中心和范围使用更强大的估计。

参考文献:

关于定位和缩放数据的重要性的进一步讨论可以在这个常见问题解答中:我应该规范化/标准化/重新调整数据?

缩放与美白

由于下游模型可以进一步对特征的线性独立性进行一些假设,因此有时不能独立地对中心和缩放特征。

为了解决这个问题,你可以使用sklearn.decomposition.PCA 或sklearn.decomposition.RandomizedPCAwhiten=True 进一步去除跨功能的线性相关。

在回归中缩放目标变量

scaleStandardScaler与1d阵列一起开箱即用。这对于缩放用于回归的目标/响应变量非常有用。

围绕核矩阵

如果你有一个内核的内核矩阵ķ来计算由函数定义的特征空间中的点积披,那么KernelCenterer可以转换内核矩阵,使其包含在定义的特征空间中的内部乘积,披然后删除该空间中的均值。

 

规范化

规范化是将单个样本缩放为具有单位规范的过程。如果您打算使用诸如点积或任何其他内核的二次形式来量化任何样本对的相似度,则此过程将非常有用。

这个假设是经常在文本分类和聚类上下文中使用的向量空间模型的基础。

该函数normalize提供了一种快速简单的方法来在单个数组类数据集上执行此操作,无论是使用l1l2 规范:

>>> 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使用TransformerAPI 实现相同操作 的实用程序类 (尽管fit在这种情况下该方法是无用的:该类是无状态的,因为该操作独立地对待样本)。

因此,这个课程适合在早期的一个步骤中使用 sklearn.pipeline.Pipeline

>>> normalizer = preprocessing.Normalizer().fit(X)  # fit does nothing
>>> normalizer
Normalizer(copy=True, norm='l2')

然后,归一化器实例可以用作样本向量作为任何变压器:

>>> 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.  ...]])

稀疏输入

normalizeNormalizer接受来自scipy.sparse的密集数组和稀疏矩阵作为输入

对于稀疏输入,将数据转换为压缩稀疏行表示(见scipy.sparse.csr_matrix),然后再将其提供给高效的Cython例程。为避免不必要的内存复制,建议在上游选择CSR表示。

 

二值化

特征二值化 

特征二值化是对数值特征进行阈值处理以获取布尔值的过程。这对于下述概率估计器来说是有用的,它们假设输入数据根据多变量伯努利分布分布。例如,情况就是这样sklearn.neural_network.BernoulliRBM

即使归一化计数(也称术语频率)或TF-IDF值特征在实践中经常表现稍好一些,文本处理社区中也常常使用二进制特征值(可能简化概率推理)。

至于这个Normalizer,这个效用类 Binarizer是在早期阶段使用的 sklearn.pipeline.Pipeline。该fit方法不做任何事情,因为每个样品都是独立于其他样品进行处理的:

>>> X = [[ 1., -1.,  2.],
...      [ 2.,  0.,  0.],
...      [ 0.,  1., -1.]]

>>> binarizer = preprocessing.Binarizer().fit(X)  # fit does nothing
>>> binarizer
Binarizer(copy=True, threshold=0.0)

>>> binarizer.transform(X)
array([[ 1.,  0.,  1.],
       [ 1.,  0.,  0.],
       [ 0.,  1.,  0.]])

可以调整二值化器的阈值:

>>> binarizer = preprocessing.Binarizer(threshold=1.1)
>>> binarizer.transform(X)
array([[ 0.,  0.,  1.],
       [ 1.,  0.,  0.],
       [ 0.,  0.,  0.]])

对于类StandardScalerNormalizer类,预处理模块提供了binarize 在不需要变压器API时使用的协同功能。

稀疏输入

binarizeBinarizer接受来自scipy.sparse的密集数组和稀疏矩阵作为输入

对于稀疏输入,数据将转换为压缩稀疏行表示(见scipy.sparse.csr_matrix)。为避免不必要的内存复制,建议在上游选择CSR表示。

 

编码分类特征 

通常,功能不是连续值,而是分类。例如,一个人可能具备的功能, , 。这样的功能可以有效地编码为整数,例如 可以表示为 ,而将。["male", "female"]["from Europe", "from US", "from Asia"]["uses Firefox", "uses Chrome", "uses Safari", "uses Internet Explorer"]["male", "from US", "uses Internet Explorer"][0, 1, 3]["female", "from Asia", "uses Chrome"][1, 2, 1]

这样的整数表示不能直接与scikit-learn估计器一起使用,因为它们期望连续输入,并且将将类别解释为被排序的,这通常是不需要的(即,该组浏览器被任意排序)。

将分类功能转换为可与scikit-learn估计器一起使用的功能的一种可能性是使用实现的K或一热编码OneHotEncoder。该估计器将具有m可能值的每个分类特征转换为m二进制特征,只有一个活动。

继续上面的例子:

>>> enc = preprocessing.OneHotEncoder()
>>> enc.fit([[0, 0, 3], [1, 1, 0], [0, 2, 1], [1, 0, 2]])  
OneHotEncoder(categorical_features='all', dtype=<... 'numpy.float64'>,
       handle_unknown='error', n_values='auto', sparse=True)
>>> enc.transform([[0, 1, 3]]).toarray()
array([[ 1.,  0.,  0.,  1.,  0.,  0.,  0.,  0.,  1.]])

默认情况下,每个功能可以从数据集自动推断多少值。可以使用参数明确指定n_values。我们的数据集中有两个性别,三个可能的大陆和四个网络浏览器。然后我们拟合估计器,并转换一个数据点。结果,前两个数字编码性别,下一组三个数字的大陆和最后四个网络浏览器。

请注意,如果训练数据有可能缺少分类特征的可能性,则必须明确设置n_values。例如:

>>> enc = preprocessing.OneHotEncoder(n_values=[2, 3, 4])
>>> # Note that there are missing categorical values for the 2nd and 3rd
>>> # features
>>> enc.fit([[1, 2, 3], [0, 2, 0]])  
OneHotEncoder(categorical_features='all', dtype=<... 'numpy.float64'>,
       handle_unknown='error', n_values=[2, 3, 4], sparse=True)
>>> enc.transform([[1, 0, 0]]).toarray()
array([[ 0.,  1.,  1.,  0.,  0.,  1.,  0.,  0.,  0.]])

 

请参阅特征中加载功能,以表示为dict的分类特征,而不是整数。

 

缺失值的插补

由于各种原因,许多现实世界的数据集包含缺少的值,通常编码为空白,NaN或其他占位符。然而,这样的数据集与scikit-learn估计器不兼容,假设数组中的所有值都是数字,并且所有数据集都具有并具有意义。使用不完整数据集的基本策略是丢弃包含缺失值的整个行和/或列。然而,这是以丢失可能是有价值的数据(即使不完整)的代价。更好的策略是估算缺失值,即从已知部分的数据中推断它们。

Imputer类提供基本策略用于输入缺失值,或者使用平均数,中位数或其中缺失值所在的行或列的最频繁的值。该类也允许不同的缺失值编码。

以下代码段演示了如何np.nan使用包含缺失值的列(轴0)的平均值替换缺省值,并将其编码为:

>>> import numpy as np
>>> from sklearn.preprocessing import Imputer
>>> imp = Imputer(missing_values='NaN', strategy='mean', axis=0)
>>> imp.fit([[1, 2], [np.nan, 3], [7, 6]])
Imputer(axis=0, copy=True, missing_values='NaN', strategy='mean', verbose=0)
>>> X = [[np.nan, 2], [6, np.nan], [7, 6]]
>>> print(imp.transform(X))                           
[[ 4.          2.        ]
 [ 6.          3.666...]
 [ 7.          6.        ]]

 

Imputer班还支持稀疏矩阵:

>>> import scipy.sparse as sp
>>> X = sp.csc_matrix([[1, 2], [0, 3], [7, 6]])
>>> imp = Imputer(missing_values=0, strategy='mean', axis=0)
>>> imp.fit(X)
Imputer(axis=0, copy=True, missing_values=0, strategy='mean', verbose=0)
>>> X_test = sp.csc_matrix([[0, 2], [6, 0], [7, 6]])
>>> print(imp.transform(X_test))                      
[[ 4.          2.        ]
 [ 6.          3.666...]
 [ 7.          6.        ]]

 

请注意,在这里,缺失值由0编码,因此隐式存储在矩阵中。因此,当比观察值更多的缺失值时,此格式是合适的。

Imputer可以在管道中使用,以构建支持插补的复合估计器。在构建估计器之前,请参阅估算缺失值

 

生成多项式特征

通过考虑输入数据的非线性特征,常常增加模型的复杂性。一个简单而常用的方法是多项式特征,可以获得特征的高阶和交互项。它实现在PolynomialFeatures

>>> import numpy as np
>>> from sklearn.preprocessing import PolynomialFeatures
>>> X = np.arange(6).reshape(3, 2)
>>> X                                                 
array([[0, 1],
       [2, 3],
       [4, 5]])
>>> poly = PolynomialFeatures(2)
>>> poly.fit_transform(X)                             
array([[  1.,   0.,   1.,   0.,   0.,   1.],
       [  1.,   2.,   3.,   4.,   6.,   9.],
       [  1.,   4.,   5.,  16.,  20.,  25.]])

 

X的特点已经转变

在某些情况下,只需要功能之间的交互项,并且可以通过设置得到interaction_only=True

>>> X = np.arange(9).reshape(3, 3)
>>> X                                                 
array([[0, 1, 2],
       [3, 4, 5],
       [6, 7, 8]])
>>> poly = PolynomialFeatures(degree=3, interaction_only=True)
>>> poly.fit_transform(X)                             
array([[   1.,    0.,    1.,    2.,    0.,    0.,    2.,    0.],
       [   1.,    3.,    4.,    5.,   12.,   15.,   20.,   60.],
       [   1.,    6.,    7.,    8.,   42.,   48.,   56.,  336.]])

 

X的特点已经转变

注意,当使用多项式内核函数时,多项式特征在内核方法(例如sklearn.svm.SVCsklearn.decomposition.KernelPCA)中隐含使用。 

使用创建的多项式特征参见Ridge回归的多项式插值

 

自定义变压器

通常,您将需要将现有的Python函数转换为变压器,以协助数据清理或处理。您可以使用任意函数实现变压器FunctionTransformer。例如,要构建在管道中应用日志转换的变压器,请执行以下操作:

>>> import numpy as np
>>> from sklearn.preprocessing import FunctionTransformer
>>> transformer = FunctionTransformer(np.log1p)
>>> X = np.array([[0, 1], [2, 3]])
>>> transformer.transform(X)
array([[ 0.        ,  0.69314718],
       [ 1.09861229,  1.38629436]])

 

有关演示使用a FunctionTransformer 执行自定义功能选择的完整代码示例,请参阅使用FunctionTransformer选择列

 

  • 无标签