概念

消除数据特征之间的量纲影响,可以将所有的特征都统一到一个大致相同的数值区间内,使得不同指标之间具有可比性。例如,分析一个人的身高和年龄对健康的影响,通常身高用 cm 作为单位,而年龄用岁作为单位,那么身高特征会大致在 160180 cm 的数值范围内,年龄特征会在 1100 岁的范围内,分析的结果显然会倾向于数值差别比较大的身高特征。想要得到更为准确的结果,就需要对数据进行特征归一化(Normalization)处理,使各指标处于同一数值量级,以便进行分析。特征归一化有时被称为特征缩放或特征规范化。

【量纲(dimension)】:物理量固有的、可度量的物理属性。例如,人的身高、体重和年龄等。

【问答 QA】:

  • 问:为什么对拥有不同数值量级特征的数据集进行分析,其结果会倾向于数值差别较大的特征?
  • 答:具体内容可以参考这篇博文 K-近邻算法 问题 QA 中的“为什么要做数据归一化”。

通常对于需要计算数据集特征距离的模型,我们都需要提前对数据集做特征归一化,尤其是数值型的数据。

常用方法

  • 线性函数归一化(Min-Max Scaling):又称为 min-max 缩放,是对原始数据进行线性变换,将结果映射到 [0, 1] 范围内,实现对原始数据的等比缩放。
    $$
    x_{norm} = \frac{x - x_{min}}{x_{max} - x_{min}}
    $$
  • 零均值归一化(Z-Score Normalization):又称为标准化或方差缩放,将原始数据映射到均值为 0、标准差为 1 的分布上。
    $$
    z = \frac{x-\mu}{\sigma}
    $$

【代码实现】:

1
2
3
4
5
6
7
8
9
10
11
12
import numpy as np


def min_max_scaling(dataset):
dataset_min, dataset_max = np.min(dataset2, axis=0), np.max(dataset2, axis=0)
dataset_range = dataset_max - dataset_min
return (dataset - dataset_min) / dataset_range

def standard_scaling(dataset):
dataset_mean = np.mean(dataset, axis=0)
dataset_var = np.sum((dataset2 - np.mean(dataset2, axis=0))**2 / len(dataset), axis=0)**0.5
return (dataset - dataset_mean) / dataset_var

以上两种方法,在 scikit-learn 的 preprocessing 包中都有实现,分别为 MinMaxScaler(feature_range=(0, 1)) 和 StandardScaler()。

1
2
3
4
5
6
7
8
9
10
11
12
import numpy as np
from sklearn.preprocessing import MinMaxScaler
from sklearn.preprocessing import StandardScaler


dataset = np.array([
[2, 1], [3, 2], [1, 4], [5, 3], [3, 5]
])
min_max_scaler = MinMaxScaler(feature_range=(0, 1))
min_max_scaler.fit_transform(dataset)
standard_scaler = StandardScaler()
standard_scaler.fit_transform(dataset)

那些关于输入是平滑函数的模型, 如线性回归、逻辑回归或任何涉及矩阵的东西, 都受输入的数值范围影响。另一方面, 基于树的模型不太在意这个。如果你的模型对输入特征的数值范围敏感, 则特征缩放可能会有所帮助。

min-max 缩放和标准化都是从原始特征值中减去一个数量。对于 min-max 缩放,移动量是当前特征的所有值中最小的;对于标准化,移动量是当前特征的平均值。如果移动量不是零,则这两种转换可以将稀疏特征的向量转换为一个稠密的向量,这反而会给分类器带来巨大的计算负担,所以需谨慎对稀疏特征执行 min-max 缩放和标准化操作。

此外,对数值型特征做归一化可以加快梯度下降算法找到最优解。

【应用】:通过梯度下降法求解的模型通常是需要归一化的,包括线性回归、逻辑回归、支持向量机、神经网络等模型。

参考