|
|
# 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]`的区间内。
|
|
|
|