(一) 特征缩放定义特征缩放是用来统一资料中的自变项或特征范围的方法,在资料处理中,通常会被使用在资料前处理这个步骤。因为在原始的资料中,各变数的范围大不相同。
(二) 特征缩放的目的对于大多数的机器学习算法和优化算法来说,将特征值缩放到相同区间可以使得获取性能更好的模型。
例如:
(a)有两个不同的特征,第一个特征的取值范围为1~10,第二个特征的取值范围为1~10000。在梯度下降算法中,代价函数为最小平方误差函数,所以在使用梯度下降算法的时候,算法会明显的偏向于第二个特征,因为它的取值范围更大。
(b)k近邻算法,它使用的是欧式距离,也会导致其偏向于第二个特征。对于决策树和随机森林以及XGboost算法而言,特征缩放对于它们没有什么影响。
(三) 常用特征缩放方法常用的特征缩放算法有两种,归一化(normalization)和标准化(standardization)
1. 归一化(a)归一化是利用特征的最大值,最小值,将特征的值缩放到[0,1]区间,对于每一列的特征使用min - max函数进行缩放。
(b) 归一化可以消除纲量,加快收敛。不同特征往往具有不同的量纲单位,这样的情况会影响到数据分析的结果,为了消除指标之间的量纲影响,需要进行数据归一化处理,以解决数据指标之间的可比性。原始数据经过数据归一化处理后,各指标处于[0,1]之间的小数,适合进行综合对比评价。
(c) 归一化可能模型提高精度。
(1)min-max标准化(Min-max normalization)
1)说明标准化为[0,1]
(x’ = frac{(x - X_{min})}{(X_{max} - X_{min})})
标准化为[min,max]
(x’ = frac{x’}{(X_{max} - X_{min})} + X_{min})
其中(X_{max})为样本数据的最大值,(X_{min})为样本数据的最小值
2)缺点这种方法有一个缺陷就是当有新数据加入时,可能导致max和min的变化,需要重新定义。
3)python实现1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16from sklearn import preprocessing
import numpy as np
#创建一组特征数据,每一行标识一个样本,每一列标识一个特征
X_train = np.array([[ 1., -1., 2.],
[ 2., 0., 0.],
[ 0., 1., -1.]])
min_max_scaler = preprocessing.MinMaxScaler()
X_train_minmax = min_max_scaler.fit_transform(X_train)
print(X_train_minmax)
#将相同的缩放应用到测试集数据中
X_test = np.array([[ -3., -1., 4.]])
X_test_minmax = min_max_scaler.transform(X_test)
print(X_test_minmax)
#打印缩放因子等属性
print(min_max_scaler.scale_)
print(min_max_scaler.min_)
(2)log函数转换
1)说明(x’ = frac{log_{10}left ( x right )}{log_{10}left ( max right )})
max为样本数据最大值,并且所有的数据都要大于等于1
(3)atan函数转换
1)说明(x’ = frac{atanleft ( x right )*2}{pi })
使用这个方法需要注意的是如果想映射的区间为[0,1],则数据都应该大于等于0,小于0的数据将被映射到[-1,0]区间上,而并非所有数据标准化的结果都映射到[0,1]区间上。
(4)l2-norm归一化
1)说明(x’ = frac{x}{sqrt{sum_{i=1}^{n}x_{i}^{2}} })
正则化是将样本在向量空间模型上的一个转换,经常被使用在分类与聚类中。
2)特性(a) normalize和Normalizer都既可以用在密集数组也可以用在稀疏矩阵(scipy.sparse)中
(b) 对于稀疏的输入数据,它会被转变成维亚索的稀疏行表征(具体请见scipy.sparse.csr_matrix)
3)python实现1
2
3
4
5
6
7
8
9from sklearn import preprocessing
import numpy as np
#创建一组特征数据,每一行标识一个样本,每一列标识一个特征
X_train = np.array([[ 1., -1., 2.],
[ 2., 0., 0.],
[ 0., 1., -1.]])
x_normalized = preprocessing.normalize(x, norm='l2')
print(x)
print(x_normalized)preprocessing这个模块还提供了一个实用类Normalizer,实用transform方法同样也可以对新的数据进行同样的转换1
2
3
4
5
6
7normalizer= preprocessing.Normalizer().fit(x)
print(normalizer)
#对训练数据进行正则
normalizer.transform(x)
#对新的测试数据进行正则
normalizer.transform([[-1.,1., 0.]])
2. 标准化(a)标准化是通过特征的平均值和标准差,将特征缩放成一个标准的正态分布,缩放后均值为0,方差为1。但即使数据不服从正态分布,也可以用此法。特别适用于数据的最大值和最小值未知,或存在孤立点。
(b)标准化是为了方便数据的下一步处理,而进行的数据缩放等变换,不同于归一化,并不是为了方便与其他数据一同处理或比较。
(1) z-score
1)公式(x’ = frac{(x - μ)}{σ})
其中μ为特征的期望(平均值),σ为标准差
2)优缺点(a)Z-Score最大的优点就是简单,容易计算,Z-Score能够应用于数值型的数据,并且不受数据量级的影响,因为它本身的作用就是消除量级给分析带来的不便。
(b)但是Z-Score应用也有风险。首先,估算Z-Score需要总体的平均值与方差,但是这一值在真实的分析与挖掘中很难得到,大多数情况下是用样本的均值与标准差替代。其次,Z-Score对于数据的分布有一定的要求,正态分布是最有利于Z-Score计算的。最后,Z-Score消除了数据具有的实际意义,A的Z-Score与B的Z-Score与他们各自的分数不再有关系,因此Z-Score的结果只能用于比较数据间的结果,数据的真实意义还需要还原原值。
3)python实现1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19from sklearn import preprocessing
import numpy as np
x = np.array([[1., -1., 2.],
[2., 0., 0.],
[0., 1., -1.]
])
#将每一列特征标准化为标准正态分布,注意,标准化是针对每一列而言的
x_scale = preprocessing.scale(x)
print(x_scale)
# 可以查看标准化后的数据的均值与方差,已经变成0,1了
print(x_scale.mean(axis=0))
# axis=1表示对每一行去做这个操作,axis=0表示对每一列做相同的这个操作
print(x_scale.mean(axis=1))
# 同理,看一下标准差
print(x_scale.std(axis=0))(a) preprocessing这个模块还提供了一个实用类StandarScaler,使用sklearn.preprocessing.StandardScaler类,使用该类的好处在于可以保存训练集中的参数(均值、方差)直接使用其对象转换测试集数据集。
(b) 这是相当好的一个功能。可以对训练数据,测试数据应用相同的转换,以后有新的数据进来也可以直接调用,不用再重新把数据放在一起再计算一次了。1
2
3
4
5
6
7
8# 调用fit方法,根据已有的训练数据创建一个标准化的转换器
scaler = preprocessing.StandardScaler().fit(X)
print(scaler)
print(scaler.mean_)
# 使用上面这个转换器去转换训练数据x,调用transform方法
print(scaler.transform(X))
#可以直接使用训练集对测试集数据进行转换
print(scaler.transform([[-1., 1., 0.]]))
3. 归一化与标准化区别(a) 目的不同,归一化是为了消除纲量压缩到[0,1]区间;标准化只是调整特征整体的分布。
(b) 归一化与最大,最小值有关;标准化与均值,标准差有关。
(c) 归一化输出在[0,1]之间;标准化无限制。
4. 归一化与标准化应用场景(a) 在分类、聚类算法中,需要使用距离来度量相似性的时候(如SVM、KNN)、或者使用PCA技术进行降维的时候,标准化(Z-score standardization)表现更好。
(b) 在不涉及距离度量、协方差计算、数据不符合正太分布的时候,可以使用第一种方法或其他归一化方法。比如图像处理中,将RGB图像转换为灰度图像后将其值限定在[0 255]的范围。
(c) 基于树的方法不需要进行特征的归一化。例如随机森林,bagging与boosting等方法。如果是基于参数的模型或者基于距离的模型,因为需要对参数或者距离进行计算,都需要进行归一化。
参考博客