1.2 数据预处理技术

在真实世界中,经常需要处理大量的原始数据,这些原始数据是机器学习算法无法理解的。为了让机器学习算法理解原始数据,需要对数据进行预处理。

1.2.1 准备工作

来看看Python是如何对数据进行预处理的。首先,用你最喜欢的文本编辑器打开一个扩展名为.py的文件,例如preprocessor.py。然后在文件里加入下面两行代码:

        import numpy as np
        from sklearn import preprocessing

我们只是加入了两个必要的程序包。接下来创建一些样本数据。向文件中添加下面这行代码:

        data=np.array([[3,   -1.5,     2,   -5.4], [0,     4,     -0.3,   2.1], [1,     3.3,
        -1.9, -4.3]])

现在就可以对数据进行预处理了。

1.2.2 详细步骤

数据可以通过许多技术进行预处理,接下来将介绍一些最常用的预处理技术。

1.均值移除(Mean removal)

通常我们会把每个特征的平均值移除,以保证特征均值为0(即标准化处理)。这样做可以消除特征彼此间的偏差(bias)。将下面几行代码加入之前打开的Python文件中:

        data_standardized=preprocessing.scale(data)
        print "\nMean=", data_standardized.mean(axis=0)
        print "Std deviation=", data_standardized.std(axis=0)

现在来运行代码。打开命令行工具,然后输入以下命令:

        $ python preprocessor.py

命令行工具中将显示以下结果:

        Mean=[   5.55111512e-17   -1.11022302e-16   -7.40148683e-17   -7.40148683e-17]
        Std deviation=[ 1.   1.   1.   1.]

你会发现特征均值几乎是0,而且标准差为1。

2.范围缩放(Scaling)

数据点中每个特征的数值范围可能变化很大,因此,有时将特征的数值范围缩放到合理的大小是非常重要的。在Python文件中加入下面几行代码,然后运行程序:

        data_scaler=preprocessing.MinMaxScaler(feature_range=(0, 1))
        data_scaled=data_scaler.fit_transform(data)
        print "\nMin max scaled data=", data_scaled

范围缩放之后,所有数据点的特征数值都位于指定的数值范围内。输出结果如下所示:

        Min max scaled data:
        [[ 1.               0.               1.               0.          ]
          [ 0.               1.               0.41025641     1.          ]
          [ 0.33333333     0.87272727     0.               0.14666667]]

3.归一化(Normalization)

数据归一化用于需要对特征向量的值进行调整时,以保证每个特征向量的值都缩放到相同的数值范围。机器学习中最常用的归一化形式就是将特征向量调整为L1范数,使特征向量的数值之和为1。增加下面两行代码到前面的Python文件中:

        data_normalized=preprocessing.normalize(data, norm='l1')
        print "\nL1 normalized data=", data_normalized

执行Python文件,就可以看到下面的结果:

        L1     normalized     data:
        [[     0.25210084     -0.12605042     0.16806723     -0.45378151]
          [     0.                0.625          -0.046875         0.328125   ]
          [     0.0952381        0.31428571    -0.18095238     -0.40952381]]

这个方法经常用于确保数据点没有因为特征的基本性质而产生较大差异,即确保数据处于同一数量级,提高不同特征数据的可比性。

4.二值化(Binarization)

二值化用于将数值特征向量转换为布尔类型向量。增加下面两行代码到前面的Python文件中:

        data_binarized=preprocessing.Binarizer(threshold=1.4).transform(data)
        print "\nBinarized data=", data_binarized

再次执行Python文件,就可以看到下面的结果:

        Binarized data:
        [[     1.     0.     1.     0.]
          [     0.     1.     0.     1.]
          [     0.     1.     0.     0.]]

如果事先已经对数据有了一定的了解,就会发现使用这个技术的好处了。

5.独热编码

通常,需要处理的数值都是稀疏地、散乱地分布在空间中,然而,我们并不需要存储这些大数值,这时就需要使用独热编码(One-Hot Encoding)。可以把独热编码看作是一种收紧(tighten)特征向量的工具。它把特征向量的每个特征与特征的非重复总数相对应,通过one-of-k的形式对每个值进行编码。特征向量的每个特征值都按照这种方式编码,这样可以更加有效地表示空间。例如,我们需要处理4维向量空间,当给一个特性向量的第n个特征进行编码时,编码器会遍历每个特征向量的第n个特征,然后进行非重复计数。如果非重复计数的值是K,那么就把这个特征转换为只有一个值是1其他值都是0的K维向量。增加下面几行代码到前面的Python文件中:

        encoder=preprocessing.OneHotEncoder()
        encoder.fit([[0, 2, 1, 12], [1, 3, 5, 3], [2, 3, 2, 12], [1, 2, 4, 3]])
        encoded_vector=encoder.transform([[2, 3, 5, 3]]).toarray()
        print "\nEncoded vector=", encoded_vector

结果如下所示:

        Encoded vector:
        [[ 0.   0.   1.   0.   1.   0.   0.   0.   1.   1.   0.]]

在上面的示例中,观察一下每个特征向量的第三个特征,分别是1、5、2、4这4个不重复的值,也就是说独热编码向量的长度是4。如果你需要对5进行编码,那么向量就是[0, 1, 0, 0]。向量中只有一个值是1。第二个元素是1,对应的值是5。