介绍

sklearn.preprocessing包为用户提供了多个工具函数和类,用于将原始特征转换成更适于项目后期学习的特征表示。

标准化、去均值、方差缩放

数据集的标准化,对于大部分机器学习算法来说都是一种常规要求。如果单个特征没有接近于标准正态分布(零均值和单位方差的高斯分布),那么它可能并不能在项目中表现出很好的性能。

例如, 许多学习算法中目标函数的基础都是假设所有的特征都是零均值并且具有同一阶数上的方差(比如径向基函数、支持向量机以及L1L2正则化项等)。如果某个特征的方差比其他特征大几个数量级,那么它就会在学习算法中占据主导位置,导致学习器并不能像我们说期望的那样,从其他特征中学习。

实战:

# 数据集的每一维特征处理成高斯分布(正态分布),即均值为0,方差为1
def Gaussian():
    X = np.array([[1., -1., 2.],
                  [2., 0., 0.],
                  [0., 1., -1.]])

    # X经过scale()处理后变成X_scaled,满足正态分布
    X_scaled = preprocessing.scale(X)

    # 每一列代表样本同一维度的特征
    X_mean = X_scaled.mean(axis=0)
    X_variance = X_scaled.std(axis=0)

    print(X_scaled)
    print(X.mean(axis=0))
    print(X.std(axis=0))
    print(X_scaled.mean(axis=0))
    print(X_scaled.std(axis=0))

结果:

[[ 0.         -1.22474487  1.33630621]
 [ 1.22474487  0.         -0.26726124]
 [-1.22474487  1.22474487 -1.06904497]]

[ 1.          0.          0.33333333]
[ 0.81649658  0.81649658  1.24721913]

[ 0.  0.  0.]
[ 1.  1.  1.]

实战:

# 数据集的每一维特征处理成高斯分布(正态分布),即均值为0,方差为1
def Gaussian1():
    X = np.array([[1., -1., 2.],
                  [2., 0., 0.],
                  [0., 1., -1.]])

    scaler = preprocessing.StandardScaler().fit(X)

    #均值
    scaler_mean = scaler.mean_
    #方差
    scaler_var = scaler.scale_

    # 转换数据,新数据满足正态分布
    X_new = scaler.transform(X)


    print(scaler_mean)
    print(scaler_var)
    print(X_new.mean(axis=0))
    print(X_new.std(axis=0))

结果

[ 1.          0.          0.33333333]
[ 0.81649658  0.81649658  1.24721913]

[ 0.  0.  0.]
[ 1.  1.  1.]

特征缩放至特定范围

另外一个可选的缩放操作是将特征缩放至给定的最小、最大值范围,经常是[0,1]。 或者也可以将每个特征的最大绝对值转换至单位大小。这两类操作可以分别通过使用:class:MinMaxScaler或者:class:MaxAbsScaler实现。

实战:

# 缩放到[0,1]
def MinMaxData():
    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)

    print(X_train_minmax)


# MaxAbsScaler 工作原理非常相似,但是它只通过除以每个特征的最大值将训练数据特征缩放至 [-1, 1]
def MaxAbsData():
    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)
    print(X_train_maxabs)

    X_test = np.array([[-3., -1., 4.], [2., 0., 1.]])
    X_test_maxabs = max_abs_scaler.fit_transform(X_test)
    print(X_test_maxabs)

结果:

[[ 0.5 0. 1. ] [ 1. 0.5 0.33333333] [ 0. 1. 0. ]]

[[ 0.5 -1. 1. ] [ 1. 0. 0. ] [ 0. 1. -0.5]]

[[-1. -1. 1. ] [ 0.66666667 0. 0.25 ]]

规范化

规范化是使单个样本具有单位范数的缩放操作。 这个在你使用二次型,比如点积或者其他核去定量计算任意样本对之间的相似性时是非常有用的。

方法 normalize 为在数组类型的数据集提供了规范化的快速实现,可以选择l1l2 范数:

# L2正则化是指权值向量w中各个元素除以它们的平方和然后再求平方根
def Normalize():
    X = [[1., -1., 2.],
         [2., 0., 0.],
         [0., 1., -1.]]
    X_normalized = preprocessing.normalize(X, norm='l2')
    print(X_normalized)

    # 赋予normalizer规范化操作,默认l2
    normalizer = preprocessing.Normalizer()
    print(normalizer)
    print(normalizer.transform(X))

结果:

[[ 0.40824829 -0.40824829 0.81649658] [ 1. 0. 0. ] [ 0. 0.70710678 -0.70710678]]

Normalizer(copy=True, norm='l2')

[[ 0.40824829 -0.40824829 0.81649658] [ 1. 0. 0. ] [ 0. 0.70710678 -0.70710678]]

特征二值化

特征二值化是将数值型特征变成布尔型特征。

实战:

#二值化
def DataBinarizer():
    X = [[1., -1., 2.],
         [2., 0., 0.],
         [0., 1., -1.]]
    binarizer = preprocessing.Binarizer()
    # 改变二值器阈值
    # binarizer = preprocessing.Binarizer(threshold=1.1)

    X_bin = binarizer.transform(X)
    print(X_bin)

结果:

 [[ 1. 0. 1.] [ 1. 0. 0.] [ 0. 1. 0.]]

缺失值处理

因为各种各样的原因,真实世界中的许多数据集都包含缺失数据,这类数据经常被编码成空格、NaNs,或者是其他的占位符。但是这样的数据集并不能很好的用于学习算法,因为大多的学习算法都默认假设数组中的元素都是数值。 使用不完整的数据集的一个基本策略就是舍弃掉整行或整列包含缺失值的数据。但是这样就付出了舍弃可能有价值数据(即使是不完整的 )的代价。 处理缺失数值的一个更好的策略就是从已有的数据推断出缺失的数值。

sk-learn中:class:Imputer类提供了缺失数值处理的基本策略,比如使用缺失数值所在行或列的均值、中位数、众数来替代缺失值。

实战:

#简单示例:缺失值被编码为np.nan, 使用包含缺失值的列的均值来替换缺失值。
def MissData():
    from sklearn.preprocessing import Imputer
    imp = Imputer(missing_values='NaN', strategy='mean', axis=0)
    x = imp.fit_transform([[1, 2], [np.nan, 3], [7, 6]])
    print(x)


结果
[[ 1. 2.] [ 4. 3.] [ 7. 6.]]

多项式特征生成

很多情况下,考虑输入数据中的非线性特征来增加模型的复杂性是非常有效的。一个简单常用的方法就是使用多项式特征,它能捕捉到特征中高阶和相互作用的项。

sk-learn包中:class:PolynomialFeatures类中可以实现该功能:

# 多项式特征生成,特征向量X从:math:(X_1, X_2) 被转换成:math:(1, X_1, X_2, X_1^2, X_1X_2, X_2^2)
def PolyGen():
    from sklearn.preprocessing import PolynomialFeatures
    X = np.arange(6).reshape(3, 2)
    print(X)
    poly = PolynomialFeatures(2)
    Y = poly.fit_transform(X)
    print(Y)

# 特征向量X从:math:(X_1, X_2, X_3) 被转换成:math:(1, X_1, X_2, X_3, X_1X_2, X_1X_3, X_2X_3, X_1X_2X_3)
    X1 = np.arange(9).reshape(3, 3)
    print(X1)
    poly = PolynomialFeatures(degree=3, interaction_only=True)
    Y1 = poly.fit_transform(X1)
    print(Y1)

结果:

[[0 1] [2 3] [4 5]]

[[ 1. 0. 1. 0. 0. 1.] [ 1. 2. 3. 4. 6. 9.] [ 1. 4. 5. 16. 20. 25.]]

[[0 1 2] [3 4 5] [6 7 8]]

[[ 1. 0. 1. 2. 0. 0. 2. 0.] [ 1. 3. 4. 5. 12. 15. 20. 60.] [ 1. 6. 7. 8. 42. 48. 56. 336.]]

参考:http://scikit-learn.org/stable/modules/preprocessing.html#preprocessing

http://scikit-learn.org/stable/modules/preprocessing.html#preprocessing

欢迎交流指正错误。