# 3.2 数据预处理常用技巧---标准化 ## 为什么要进行标准化 对于大多数数据挖掘算法来说,数据集的标准化是基本要求。这是因为有些数据挖掘算法中需要计算距离或梯度等信息,而这些信息需要数据中的特征处于同一量纲内才会有比较好的效果。 比如现在问你个问题,是 1000 克的棉花重,还是 1 公斤的铁重?你肯定能不假思索的回答:一样重!但是,有些数据挖掘算法会觉得 1000 克的棉花重,因为它并不会看 1000 后面的单位是克还是公斤。所以如果想要使用这类算法来进行数据挖掘,那么首先要做的事情就是对数据进行标准化,因为标准化能够解决特征量纲不一致的问题。 ## Z-score标准化 这种方法基于原始数据的均值和标准差进行数据的标准化。对特征`A`的原始值`x`使用`z-score`标准化,将其值标准化为到`x’`。`z-score`标准化方法适用于特征`A`的最大值和最小值未知的情况,或有超出取值范围的离群数据的情况。将数据按其特征(按列进行)减去其均值,然后除以其方差。最后得到的结果是,对每个特征/每列来说所有数据都聚集在`0`附近,方差值为`1`。数学公式如下: $$ x^,=\frac{x-x_{mean}}{x_{std}} $$ `sklearn`的`preprocessing`模块中的函数`scale`实现了`Z-score`标准化的功能。实例代码如下: ```python # 导入preprocessing模块 from sklearn import preprocessing # 导入numpy库 import numpy as np # 定义数据,该数据中有3条记录,每条记录有3个特征 X_train = np.array([[ 1., -1., 2.], [ 2., 0., 0.], [ 0., 1., -1.]]) # 对数据进行z-score标准化,并将结果保存至X_scaled X_scaled = preprocessing.scale(X_train) # z-score标准化的结果 >>>X_scaled array([[ 0. ..., -1.22..., 1.33...], [ 1.22..., 0. ..., -0.26...], [-1.22..., 1.22..., -1.06...]]) ``` 从结果上看,可以看出`scale`函数好像起了作用,为了验证标准化是否正确,我们可以检查一下`X_scaled`的均值和方差。代码如下: ```python # 计算X_scaled中每个特征的均值,发现全是0 >>> X_scaled.mean(axis=0) array([ 0., 0., 0.]) # 计算X_scaled中每个特征的方差,发现全是1 >>> X_scaled.std(axis=0) array([ 1., 1., 1.]) ``` 嗯,不错,`scale`成功地对数据进行了标准化。 ## Min-max标准化 `Min-max`标准化方法是对原始数据进行线性变换。设`minA`和`maxA`分别为特征`A`的最小值和最大值,将`A`的一个原始值`x`通过`min-max`标准化映射成在区间`[0,1]`中的值`x'`,其公式为: $$ x^, = \frac{x-x_{min}}{x_{max}-x_{min}} $$ `sklearn`的`preprocessing`模块中的`MinMaxScaler`类的`fit_transform`函数实现了`Min-max`标准化的功能。实例代码如下: ```python # 导入preprocessing模块 from sklearn import preprocessing # 导入numpy库 import numpy as np # 定义数据,该数据中有3条记录,每条记录有3个特征 X_train = np.array([[ 1., -1., 2.], [ 2., 0., 0.], [ 0., 1., -1.]]) # 实例化MinMaxScaler对象 min_max_scaler = preprocessing.MinMaxScaler() # 对数据进行Min-max标准化,并将结果保存至X_train_minmax X_train_minmax = min_max_scaler.fit_transform(X_train) # Min-max标准化的结果 >>> X_train_minmax array([[ 0.5 , 0. , 1. ], [ 1. , 0.5 , 0.33333333], [ 0. , 1. , 0. ]]) ``` 可以看出,经过`Min-max`标准化后,数据中的所有特征值都缩放到了`[0, 1]`的区间内。 ## MaxAbs标准化 `MaxAbs`的工作原理与`Min-max`非常相似,但是它只通过除以每个特征的最大值将训练数据特征缩放至 `[-1, 1]` 范围内,这就意味着,训练数据应该是已经零中心化或者是稀疏数据。公式如下: $$ x^, = \frac{x}{x_{max}} $$ `sklearn`的`preprocessing`模块中的`MaxAbsScaler`类的`fit_transform`函数实现了`MaxAbs`标准化的功能。实例代码如下: ```python # 导入preprocessing模块 from sklearn import preprocessing # 导入numpy库 import numpy as np # 定义数据,该数据中有3条记录,每条记录有3个特征 X_train = np.array([[ 1., -1., 2.], [ 2., 0., 0.], [ 0., 1., -1.]]) # 实例化MaxAbsScaler对象 max_abs_scaler = preprocessing.MaxAbsScaler() # 对数据进行MaxAbs标准化,并将结果保存至X_train_maxabs X_train_maxabs = max_abs_scaler.fit_transform(X_train) # MaxAbs标准化的结果 >>> X_train_maxabs array([[ 0.5, -1. , 1. ], [ 1. , 0. , 0. ], [ 0. , 1. , -0.5]]) ``` 可以看出,经过`MaxAbs`标准化后,数据中的所有特征值都缩放到了`[-1, 1]`的区间内。