sklearn学习笔记(一)——数据预处理 sklearn.preprocessing

https://blog.csdn.net/zhangyang10d/article/details/53418227

数据预处理 sklearn.preprocessing

  • 标准化 (Standardization)
  • 规范化(Normalization)
  • 二值化
  • 分类特征编码
  • 推定缺失数据
  • 生成多项式特征
  • 定制转换器

1. 标准化Standardization(这里指移除均值和方差标准化)
标准化是不少数据分析问题的一个重要步骤,也是不少利用机器学习算法进行数据处理的必要步骤。html

1.1 z-score标准化
z-score标准化指的是将数据转化成均值为0方差为1的高斯分布,也就是一般说的z-score标准化,可是对于不服从标准正态分布的特征,这样作效果会不好。python

在实际应用中,咱们常常忽视分布的形状,将数据进行z-score标准化。若是不将数据进行标准化处理,在利用机器学习算法(例如SVM)的过程当中,若是目标函数中的一个特征的方差的阶数的量级高于其余特征的方差,那么这一特征就会在目标函数中占主导地位,从而“淹没”其余特征的做用。算法

Python中的scale函数是一种快速进行z-score标准化的方法,可以处理相似于数组结构的数据。Z-score标准化后的数据的均值为0,方差为1。数组

>>> from sklearn import preprocessing >>> x = [[1., -1., 2], # 每一行为[feature1, feature2, feature3] ... [2., 0., 0.], ... [0., 1., -1.]] >>> x_scaled = preprocessing.scale(x) >>> x_scaled array([[ 0. , -1.22474487, 1.33630621], [ 1.22474487, 0. , -0.26726124], [-1.22474487, 1.22474487, -1.06904497]]) >>> x_scaled.mean(axis=0) array([ 0., 0., 0.]) >>> x_scaled.std(axis=0) array([ 1., 1., 1.])
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13

preprocessing模块还提供了一个实用类StandardScaler,这个类实现了一个叫作Transformer的应用程序接口,可以计算训练数据的均值和标准差,从而在训练数据集上再次使用。浏览器

>>> scaler = preprocessing.StandardScaler().fit(x) >>> scaler StandardScaler(copy=True, with_mean=True, with_std=True) >>> scaler.mean_ array([ 1. , 0. , 0.33333333]) >>> scaler.scale_ array([ 0.81649658, 0.81649658, 1.24721913]) >>> scaler.transform(x) array([[ 0. , -1.22474487, 1.33630621], [ 1.22474487, 0. , -0.26726124], [-1.22474487, 1.22474487, -1.06904497]]) >>> scaler = preprocessing.StandardScaler().fit(x) >>> scaler StandardScaler(copy=True, with_mean=True, with_std=True) >>> scaler.transform([[-1., 1., 0.]]) # 在其余数据集上使用 array([[-2.44948974, 1.22474487, -0.26726124]])
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16

1.2 将特征数据缩放到一个范围 scale to a range
利用最大值和最小值进行缩放,一般是将数据缩放到0-1这个范围,或者是将每一个特征的绝对值最大值缩放到单位尺度,分别利用MinMaxScaler和MaxAbsScaler实现。
使用这一方法的状况通常有两种:
(1) 特征的标准差较小
(2) 可使稀疏数据集中的0值继续为0机器学习

>>> x [[1.0, -1.0, 2], [2.0, 0.0, 0.0], [0.0, 1.0, -1.0]] >>> min_max_scaler = preprocessing.MinMaxScaler() >>> x_scaled_minmax = min_max_scaler.fit_transform(x) >>> x_scaled_minmax array([[ 0.5 , 0. , 1. ], [ 1. , 0.5 , 0.33333333], [ 0. , 1. , 0. ]]) >>> #这个transformer的实例还可以应用于新的数据集,此时的缩放比例与以前训练集上的缩放比例是相同的。 >>> x_test = np.array([[3., 1., 4.]]) >>> min_max_scaler.transform(x_test) array([[ 1.5 , 1. , 1.66666667]]) 
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13

能够查看缩放算子的一些属性:函数

min_, scale_, data_min_, data_max_, data_range_, 
>>> min_max_scaler.scale_ # 缩放比例=1/(max-min) array([ 0.5 , 0.5 , 0.33333333]) >>> min_max_scaler.min_ # (x-min)/(max-min), 这里min_表明min/(max-min) array([ 0. , 0.5 , 0.33333333]) 
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6

MaxAbsScaler与上述用法类似,可是标准化后的数据的取值范围为[-1, 1]。这对于稀疏数据或者是数据中心已经为0的数据颇有意义。学习

>>> x=[[1., -1., 2.], [2., 0., 0.], [0., 1., -1.]] >>> max_abs_scaler = preprocessing.MaxAbsScaler() >>> max_abs_scaler.fit_transform(x) array([[ 0.5, -1. , 1. ], [ 1. , 0. , 0. ], [ 0. , 1. , -0.5]]) >>> x_test = [[-2., 4., 2.]] >>> max_abs_scaler.transform(x_test) array([[-1., 4., 1.]]) >>> max_abs_scaler.scale_ array([ 2., 1., 2.])
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11

1.3 缩放稀疏数据
将稀疏数据置中有可能破坏数据的稀疏结构。可是将稀疏数据进行缩放是有意义的,特别是对于量纲不一样的特征输入。编码

MaxAbsScalermaxabs_scale特别适用于缩放稀疏数据。此外,scale和StandardScaler可以处理scipy.sparse矩阵做为输入的状况,此时须要将with_mean设置为False。不然默认的置中操做将会破坏数据的稀疏型,会抛出一个ValueError的错误,并且内存可能会被大量占用形成内存溢出。RobustScaler不适用于稀疏数据的处理,可是它的transform方法能够做用于稀疏数据。spa

注意,缩放器(scaler)容许输入压缩的稀疏行和稀疏列数据(见scipy.sparse.csr_matrix和scipy.sparse.csc_matrix)任何其余的稀疏输入都会被转化成压缩的稀疏行表示。为了不没必要要的内存占用,建议使用CSR或者CSC表示法。
最后,若是但愿置中的数据足够小,可使用sparse matrices的toarray方法将稀疏的输入数据转化为一个数组。
sklearn.preprocessing.maxabs_scale(X, axis=0, copy=True)
class sklearn.preprocessing.MaxAbsScaler(copy=True) # 这是一个Transformer API

1.4 缩放带有outlier的数据
若是数据中含有异常值,那么使用均值和方差缩放数据的效果并很差。这种状况下,可使用robust_scale和RobustScaler。
sklearn.preprocessing.robust_scale(X, axis=0, with_centering=True, with_scaling=True, quantile_range=(25.0, 75.0), copy=True)[source]
class sklearn.preprocessing.RobustScaler(with_centering=True, with_scaling=True, quantile_range=(25.0, 75.0), copy=True) # 这是一个Transformer API

这两种方法计算的数据的均值和范围更加可靠。
Scale和StandardScaler可以用于一维数组,这对于缩放回归过程当中的的目标/响应变量十分有用。

1.5 置中核矩阵
若是有一个核矩阵(在函数phi定义的特征空间上计算点积获得),那么KernelCenterer可以转移核矩阵,使得在函数phi定义的特征空间中的内积构造的核矩阵可以转移到移除均值后的空间中。

2. 规范化(Normalization)
规范化是指将样本缩放成单位向量。若是须要使用二次方程,好比点积或者其余核方法计算样本对之间的类似性,那么这一过程很是有用。
这一假设是经常使用于文本分类和内容聚类的向量空间模型的基础。
normalize函数提供了一个处理单个结构相似数组的数据集的快速简单的方法,可使用1范数l1或者2范数l2。

>>> x=[[1., -1., 2.], [2., 0., 0.], [0., 1., -1.]] >>> x_normalized = preprocessing.normalize(x, norm='l2') >>> x_normalized array([[ 0.40824829, -0.40824829, 0.81649658], [ 1. , 0. , 0. ], [ 0. , 0.70710678, -0.70710678]])
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6

相似的,preprocessing模块也提供了一个实体类Normalizer,可以利用Transformer API执行相同的操做(虽然fit方法这里是没有意义的,由于规范化是对于每一个样本独立进行的)。

>>> x=[[1., -1., 2.], [2., 0., 0.], [0., 1., -1.]] >>> normalizer = preprocessing.Normalizer().fit(x) >>> normalizer Normalizer(copy=True, norm='l2') >>> normalizer.transform(x) array([[ 0.40824829, -0.40824829, 0.81649658], [ 1. , 0. , 0. ], [ 0. , 0.70710678, -0.70710678]]) >>> normalizer.transform([[1., -1., 0]]) array([[ 0.70710678, -0.70710678, 0. ]])
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10

对于稀疏的输入数据,normalize和Normalizer能够接受非稀疏数组类型和稀疏矩阵类型左右的输入。稀疏数据将被转化为压缩的稀疏行表示法。

3. 二值化
3.1 特征二值化
这一过程就是定义一个阈值,而后获得数值特征的布尔值。这对于假设输入数据服从多元伯努利分布的几率估计量很是有用。这在文本处理过程当中也很是常见。
实力类Binarizer能够实现这一过程。一样的,fit函数没有意义。

>>> x=[[1., -1., 2.], [2., 0., 0.], [0., 1., -1.]] >>> binarizer = preprocessing.Binarizer().fit(x) >>> 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.]])
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13

此外,在不必使用Transformer API时,也提供了binarize方法进行转化。binarize和Binarizer均可以处理稀疏输入。

4. 分类特征编码
当某些特征不是连续取值而是分类数据时,就须要对分类特征进行编码,好比人的性别有[“男”, “女”]之分,国籍能够是[“中国”, “英国”, “美国”],使用的浏览器可能为[“FireFox”, “Chrome”, “Safari”, “IE”]。这样的特征能够分别用不一样的整数进行标记,好比[“男”, “女”]分表表示成[0, 1],[“中国”, “英国”, “美国”]分别表示成[0, 1, 2],[“FireFox”, “Chrome”, “Safari”, “IE”]表示为[0, 1, 2, 3]

可是,这种整数表示方法不能直接用于scikit-learn估计量,由于这一算法包但愿输入是连续的变量,所以就会将不一样的种类理解成不一样的大小。解决这一问题的一个方法是使用one-of-K或者one-hot编码,经过OneHotEncoder实现。这一估计量将每一个含有m个取值的分类特征转化为m个二值特征,其中只有一个处于active状态。

>>> enc = preprocessing.OneHotEncoder() >>> enc.fit([[0,0,3],[1,1,0],[0,2,1],[1,0,2]]) OneHotEncoder(categorical_features='all', dtype=<class 'float'>, handle_unknown='error', n_values='auto', sparse=True) >>> enc.transform([[0,1,3]]).toarray() array([[ 1., 0., 0., 1., 0., 0., 0., 0., 1.]]) # 一共9位 >>> # feature1只有0,1两个取值,所以是两位 >>> # feature2有0,1,2三个取值,所以是三位 >>> # feature3有0,1,2,3四个取值,所以是四位
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9

每一个特征的分类个数默认上根据输入数据集自动计算。可是也能够经过设置参数n_values进行人为设定。在上述例子中,三个分类属性的可选值数量分别为2,3,4。特别是当训练数据集在某个可能取值上没有训练样本时,须要人为制定分类数量。例如:

>>> enc = preprocessing.OneHotEncoder(n_values=[2, 3, 4]) >>> enc.fit([[1,2,3],[0,2,0]]) OneHotEncoder(categorical_features='all', dtype=<class 'float'>, 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.]])
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6

5. 推定缺失数据
不少状况下,真实的数据集中会存在缺失值,此时数据集中会采用空格、NaNs或者其余占位符进行记录。可是scikit-learn的输入变量应该为数值型,此时须要对缺失值进行处理。一种策略是将存在缺失值的整条记录直接删除。可是这样作可能会丢失一部分有价值的信息。更好的一种方法是推定缺失数据,例如根据已经数据推算缺失的数据。

Imputer类可以提供一些处理缺失值的基本策略,例如使用缺失值所处的一行或者一列的均值、中位数或者出现频率最高的值做为缺失数据的取值。下边举一个使用缺失值所处行的均值做为缺失值的例子:

>>> 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. ]]
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10

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. ]]
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10

6. 产生多项式特征
在输入数据存在非线性特征时,这一操做对增长模型的复杂度十分有用。一种常见的用法是生成多项式特征,可以获得特征的高阶项和相互做用项。利用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.]])
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12

此时,特征向量X=(X1, X2)被转化为(1, X1, X2, X1^2, X1X2, X2^2)。
在有些状况下,咱们只须要相互做用项,此时能够经过设定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.]])
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10

这里,X=(X1, X2, X3)被转化为to (1, X1, X2, X3, X1X2, X1X3, X2X3, X1X2X3)。

多项式特征常常用于使用多项式核函数的核方法(好比SVC和KernelPCA)。

7. 定制转换器
咱们常常但愿将一个Python的函数转变为transformer,用于数据清洗和预处理。可使用FunctionTransformer方法将任意函数转化为一个Transformer。好比,构建一个对数log的Transformer:

>>> 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]])
相关文章
相关标签/搜索