every blog every motto: You can do more than you think.
0. 前言
标准化和归一化辨析
1. 正文
1.1 概念辨析
-
数据组织形式
数据组织形式如下,一行 代表一条样本,一列代表一个特征,归一化、标准化都是对特征进行的,即列方向上。
编号 身高/cm 体重/kg 脚尺码/ 0 175 66 43 1 182 75 45 2 160 58 38 -
归一化
含义:将特征的值缩放到0到1之间,公式如下,
X n = X − X m i n X m a x − X m i n X_n = {X-X_{min}\over X_{max}-X_{min}} Xn=Xmax−XminX−Xmin
-
标准化
含义:将特征的值缩放成均值为1,方差为1,公式如下,
z = x − μ σ z = {x -\mu \over \sigma} z=σx−μ
-
1.2 好处
1.2.1 提升模型精度
在机器学习算法的目标函数(例如SVM的RBF内核或线性模型的l1和l2正则化),许多学习算法中目标函数的基础都是假设所有的特征都是零均值并且具有同一阶数上的方差。如果某个特征的方差比其他特征大几个数量级,那么它就会在学习算法中占据主导位置,导致学习器并不能像我们说期望的那样,从其他特征中学习。
如前所示,身高的数值更大,相较于脚尺码起的作用更大,所以通过标准化、归一化进一步缩小不同特征差异过大的问题
1.2.2 提升收敛速度
变换前:
变换后:
如上图所示,归一化以后,收敛速度更快。
1.3 标准化、归一化对比
归一化应用场景有限,原因如下:
-
标准化更好保持不同特征间距。如有特征数值为 [2,3,1000]
归一化后,将值缩放到0-1之间,代入公式后为:[0, 0.001, 1],虽然我们将值缩放到了0-1之间,但是前两个特征间的距离会变得非常近,不容易区分。
标准化后,将值缩放为均值为0,方差为1,变换后为:[-0.708,-0.706,1.414],**标准化就不存在不容易区分的问题。**我们用代码实现:
a = [2, 3, 1000] mean = np.mean(a) # 母体标准差,默认参数dof=0 std = np.std(a) res = (a - mean) / std print('变换前,均值:', mean) print('变换前,标准差:', std) print('---------------------') mean2 = np.sum(res) var = np.var(res) print('变换后的值:', res) print('变换后,均值:', mean2) print('变换后,方差:', var)
- 标准化更符合统计学假设
对于数值特征来说,最初的数据很大可能服从正态分布(中心极限定理)。标准化基于这个隐含的假设。只不过将正态分布调整为均值为0,方差为1的标准正态分布。
说明:
- 我们日常中数据,大部分符合正态分布
- 标准化不会改变分布!,如,原来是是卡方分布,不会因为标准化而变成正态分布,更不会变成标准正态分布。只是,经过标准化以后,我们的数据的均值改为0,方差改为1而已。
具体实例如下:
解释: 如下图所示,我们初始数据设定为均匀分布,归一化后,我们的值被缩放到0-1之间。
均值和方差发生改变,数据分布没有发生改变。
import numpy as np
import matplotlib.pyplot as plt
from matplotlib import pyplot
import os
import PySide2
dirname = os.path.dirname(PySide2.__file__)
plugin_path = os.path.join(dirname, 'plugins', 'platforms')
os.environ['QT_QPA_PLATFORM_PLUGIN_PATH'] = plugin_path
# 均匀分布
x = np.random.uniform(5, 500, 1000)
mean = np.mean(x)
# 母体标准差,默认参数dof=0
std = np.std(x)
standardization = (x - mean) / std
print('原始数据,均值:', mean, '标准差:', std)
print('---------------------')
mean2 = np.sum(standardization)
var = np.var(standardization)
# 归一化
norm = (x - np.min(x)) / (np.max(x) - np.min(x))
print('归一化,均值:', np.mean(norm), '方差:', np.std(norm))
print('---------------------')
print('标准化,均值:', mean2, '方差:', var)
# 画图
pyplot.rcParams['font.sans-serif'] = ['SimHei']
pyplot.rcParams['axes.unicode_minus'] = False
plt.figure(figsize=(10, 5))
plt.subplot()
plt.subplot(131)
plt.title('源数据')
plt.hist(x)
plt.subplot(132)
plt.title('归一化')
plt.hist(norm)
plt.subplot(133)
plt.title('标准化')
plt.hist(standardization)
plt.show()
正态分布测试
# 正态分布
x = np.random.normal(15, 10, size=100000)
1.4 关于分布
从上面的实验我们发现,标准化(归一化)以后数据的分布并没有改变。
1. 什么是分布?
分布是某一种类别出现的频率。
2. 理解
我们的标准化只是将出现的类别的范围进行变换,但是频率没有变。
即,我们标准化以后,从概率论的角度来说,我们不会从卡方分布变到正态分布,所以分布没有改变。
但是,一般情况下,我们假设我们的数据为正态分布,标准化以后,变为正态分布(改变了
μ
,
、
σ
\mu,、\sigma
μ,、σ),如果从这个层面说,标准化使分布改变了。
1.4 小结
- 归一化将值缩放到0-1之间
- 标准化改变数据的均值和方差为0和1
- 归一化、标准化都不改变数据的分布
- 如果数据中,最大值和最小值差距较大,使用归一化会导致较小的值被缩放到很小,较小值之间不容易区分,同时,对结果的起作用较小。
参考文献
[1] https://blog.csdn.net/weixin_36604953/article/details/102652160
[2] https://blog.csdn.net/zwqjoy/article/details/81182102
[3] https://www.jianshu.com/p/1e63cd2afedc
[4] https://www.jianshu.com/p/4c3081d40ca6
[5] https://blog.csdn.net/weixin_39190382/article/details/106383101?ops_request_misc=%257B%2522request%255Fid%2522%253A%2522163011539916780261943133%2522%252C%2522scm%2522%253A%252220140713.130102334.pc%255Fblog.%2522%257D&request_id=163011539916780261943133&biz_id=0&utm_medium=distribute.pc_search_result.none-task-blog-2blogfirst_rank_v2~rank_v29-1-106383101.pc_v2_rank_blog_default&utm_term=%E5%BD%92%E4%B8%80%E5%8C%96&spm=1018.2226.3001.4450
[6] https://blog.csdn.net/zbq_tt5/article/details/100054087
[7] https://blog.csdn.net/geek64581/article/details/106606250
[8] https://blog.csdn.net/camillect/article/details/89791734
[9] https://open.163.com/newview/movie/free?pid=M82IC6GQU&mid=M83JBLPM4
[10] https://baijiahao.baidu.com/s?id=1665261046335447411&wfr=spider&for=pc
[11] https://www.zhihu.com/question/20467170