0%

机器学习之数据预处理:Feature Scaling 特征缩放

数据预处理作为机器学习中的关键一环,这里介绍其中的Feature Scaling 特征缩放

abstract.png

楔子

不同特征数据之间由于量纲、尺度的不同,彼此差异非常大往往无法直接进行比较。而对特征进行缩放,则可实现不同特征之间具有一致的尺度、标准。其价值在于:

  • 一致的数据尺度可以加速模型的收敛。典型地:使用梯度下降优化算法的模型
  • 部分模型对特征的尺度敏感,使得某些特征因其数值较大而在模型中占据主导地位,从而严重影响模型的准确性。典型地:K-Means、SVM、KNN等基于距离的模型
  • 过大、过小的数据在计算过程中可能会发生精度、溢出等问题

Standardization 标准化

机器学习领域下,一般指的是Z-score标准化。其通过对特征进行线性变换(平移和缩放),将特征转换成均值为0、标准差为1的分布。具体地,先计算原始数据的均值、标准差;然后,对每个原始数据减去该均值、再除以该标准差

这里强调下:

  • 标准化不改变数据原始分布的相对位置关系、形状、形态特征,因为其只是一个线性变换
  • 均值为0、标准差为1 是标准正态分布的必要条件,而不是充分条件。例如:对于这样一个数据集: -1、-1、-1、1、1、1。其显然不是标准正态分布,而是一个双峰分布。但其均值却为0、标准差却为1

特点:

  • 转换后,数据的数值范围是不固定的
  • 相对于归一化而言,其对异常值的敏感度相对较低
  • 消除了各数据之间的尺度差异,使得基于距离的模型表现更加良好
  • 针对线性回归等模型,系数的绝对值大小可以直接反映、解释特征的重要性。因为所有特征都在一致的尺度上

可以通过Sklearn中的StandardScaler来实现数据的标准化。典型的方法有:

  • fit(X):从指定数据集中计算均值、标准差等参数
  • transform(X):使用已经学习到的参数(均值、标准差)对指定数据集进行标准化转换
  • fit_transform(X):顾名思义,其结合了fit()、transform()的功能。先对指定数据集进行fit操作来计算均值、标准差等参数,然后使用这些参数对该数据集进行transform操作
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
from sklearn.model_selection import train_test_split
from sklearn.preprocessing import StandardScaler
from sklearn import datasets


# 加载数据集
dataset = datasets.fetch_california_housing()
X = dataset.data
y = dataset.target

# 切分训练集和测试集
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.3, random_state=69)

# 创建 StandardScaler 实例
scaler = StandardScaler()

# 从训练集中学习均值、标准差,并对训练集进行标准化
X_train = scaler.fit_transform(X_train)

# 使用 从训练集中计算的均值、标准差 对测试集进行标准化
X_test = scaler.transform(X_test)

Normalization 归一化

机器学习领域下,一般指的是Min-Max Scaling 最小-最大缩放。其将数据的数值缩放到固定的范围内。常见的范围有:[0,1]、[−1,1]。该方法同样可以消除数据间的量纲,但更多的是应用场景还是为了满足某些算法(梯度下降优化算法、神经网络等)对输入数据范围非常敏感的要求

将数据缩放到 [0,1] 范围下:

将数据缩放到 [-1,1] 范围下:

特点:

  • 其与标准化显著的区别是,其会数据的数值转换到一个固定的区间范围下
  • 归一化是线性压缩,故其会改变数据的原始分布形状
  • 由于该缩放技术依赖最小值、最大值,故对异常值非常敏感。会将大部分正常的数据被压缩到一个非常小的范围内,失去了区分度
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
from sklearn.model_selection import train_test_split
from sklearn.preprocessing import MinMaxScaler
from sklearn import datasets


# 加载数据集
dataset = datasets.fetch_california_housing()
X = dataset.data
y = dataset.target

# 切分训练集和测试集
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.3, random_state=69)

# 创建 MinMaxScaler 实例,默认缩放到[0,1]范围
scaler = MinMaxScaler()

# 从训练集中学习最值,并对训练集进行归一化
X_train = scaler.fit_transform(X_train)

# 使用 从训练集中学习的最值 对测试集进行归一化
X_test = scaler.transform(X_test)

Note

需要注意的是,在进行数据预处理时,任何关于数据集的均值、标准差、最值、极值等参数只能通过训练集来进行计算、学习,绝对不可以使用整个样本集(训练集+测试集)来计算。即:必须使用在训练集上学习到的均值、标准差、最值、极值等参数来对训练集、测试集进行处理

原因很简单,如果在学习的过程中时使用了测试集中的数据,相当于模型在训练阶段偷看了它本不应该知道的测试集信息(例如,分布特征、统计信息等),发生了数据泄露。这样模型训练完成后,再用该测试集来评估模型的性能是不真实的、虚高的。因为它在考试时作弊了

参考文献

  • 机器学习 周志华著
  • 机器学习公式详解 谢文睿、秦州著
  • 图解机器学习和深度学习入门 山口达辉、松田洋之著
请我喝杯咖啡捏~

欢迎关注我的微信公众号:青灯抽丝