特征工程中的归一化问题
特征工程中的「归一化」有什么作用? - 微调的回答 - 知乎 https://www.zhihu.com/question/20455227/answer/370658612
本文主要摘自知乎问题中微调童鞋的答案,侵删。
首先,我们需要明白三个问题:
- 数据缩放的本质是什么
- 不同数据缩放的区别
- 如何选择不同的缩放方法
我们从定义入手:
- 归一化(normalization):
- 标准化(standardization):
其中 和
代表样本的均值和标准差,
为最大值,
为最小值。
1. 归一化和标准化本质上都是一种线性变换
先看归一化,在数据给定的前提下,令常数 ,常数
,那么归一化的新的形式就是
。在这种改写后下,易发现和标准化形式
类似,因为在数据给定后
和
也可看做常数。
因此可以再稍微变形一下: (公式1)
就发现事实上就是对向量 按照比例压缩
再进行平移
。所以归一化和标准化的本质就是一种线性变换。
举个简单的例子:
- 原始数据:
,其中
,
,
- 归一化:代入公式1,将
压缩4倍并平移
,得到
,最终有
- 标准化:与归一化类似,略
2. 线性变化的性质
线性变换有很多良好的性质,这些性质决定了为什么对数据进行改变后竟然不会造成“失效”,反而还能提高数据的表现。拿其中很重要的一个性质为例,线性变化不改变原始数据的数值排序。
下面举个栗子:
from sklearn import preprocessing
from scipy.stats import rankdata
x = [[1], [3], [34], [21], [10], [12]]
std_x = preprocessing.StandardScaler().fit_transform(x) n
orm_x = preprocessing.MinMaxScaler().fit_transform(x)
# print(std_x)
# print(norm_x)
print('原始顺序 :', rankdata(x))
print('标准化顺序:', rankdata(std_x))
print('归一化顺序:', rankdata(norm_x))
发现两种处理方法都不会改变数据的排序。对很多模型来说,这个性质保证了数据依然有意义,顺序性不变,而不会造成了额外的影响。说白了,只是因为线性变换保持线性组合与线性关系式不变,这保证了特定模型不会失效。
3. 归一化和标准化的区别
我们已经说明了它们的本质是缩放和平移,但区别是什么呢?在不涉及线性代数的前提下,我们给出一些直觉的解释:归一化的缩放是“拍扁”统一到区间(仅由极值决定),而标准化的缩放是更加“弹性”和“动态”的,和整体样本的分布有很大的关系。值得注意:
- 归一化:缩放仅仅跟最大、最小值的差别有关。
- 标准化:缩放和每个点都有关系,通过方差(variance)体现出来。与归一化对比,标准化中所有数据点都有贡献(通过均值和标准差造成影响)。
当数据较为集中时, 更小,于是数据在标准化后就会更加分散。如果数据本身分布很广,那么
较大,数据就会被集中到更小的范围内。
从输出范围角度来看, 必须在0-1间。对比来看,显然
,甚至在极端情况下
,所以标准化的输出范围一定比归一化更广。
- 归一化: 输出范围在0-1之间
- 标准化:输出范围是负无穷到正无穷
4. 什么时候用归一化?什么时候用标准化?
我们已经从第三部分得到了一些性质,因此可以得到以下结论:
- 如果对输出结果范围有要求,用归一化
- 如果数据较为稳定,不存在极端的最大最小值,用归一化
- 如果数据存在异常值和较多噪音,用标准化,可以间接通过中心化避免异常值和极端值的影响
5.最后补两张图,直观理解一下: