4.7 数据归一化

数据归一化 Feature Scaling

首先我们开看一下为什么要进行数据归一化。
我们使用前边说道的肿瘤的例子:

-- 肿瘤大小( 厘米) 发现时间(天)
样本1 1 200
样本2 5 100

那么这两个样本的距离是多少呢?如果使用欧拉距离的话,就是

在这种情况下,我们发现显然样本间的距离被发现时间所主导,因为时间间隔比较大,导致最终距离衡量的是时间。如果我们发现时间调整成以年为单位,此时肿瘤的距离有一下子又取决于肿瘤大小这个特征。很显然,如果不进行数据的基本处理,直接计算样本间的距离是有很大偏差的,不能反映每个样本特征的重要程度,所以要进行数据归一化处理。

-- 肿瘤大小( 厘米) 发现时间(天)
样本1 1 200=0.55年
样本2 5 100=0.27年

数据归一化,所谓的数据归一化处理就是将所有的数据映射到同一尺度。通常最简单的方式叫作最值归一化(normalization): 把所有的数据映射到0-1之间。适用于有明确的边界,如学生的成绩。

最值归一化适用于分布有明显边界的情况;缺点:受outliner影响较大,例如每个人的收入,没有明显的边界,假如大部分人的收入是1万,有一个人收入是100万,那么大部分人的映射在0-0.01左右,而收入高的人映射值接近1,因为这样偏差比较大,改进的方法是均值方差归一化(standardization)
均值方差归一化:把所有数据归一到均值为0方差为1的分布中。适用于数据分布没有明显的边界;有可能存在极端数据值的情况。计算方法:

x:特征值
表示特征值均值
S:表示方差
下面我们来实现这两种归一化过程

import numpy as np
import matplotlib.pyplot as plt
# 最值归一化 Normalization
# 处理向量
x = np.random.randint(0, 100, size=100)
(x - np.min(x)) / (np.max(x)-np.min(x))
array([0.12121212, 0.24242424, 0.43434343, 0.49494949, 0.91919192,
       0.54545455, 0.16161616, 0.53535354, 0.8989899 , 0.11111111,
       0.49494949, 0.33333333, 0.72727273, 0.85858586, 0.27272727,
       0.4040404 , 0.53535354, 0.56565657, 0.63636364, 0.58585859,
       0.74747475, 0.8989899 , 0.54545455, 0.85858586, 0.25252525,
       0.55555556, 0.77777778, 0.39393939, 0.43434343, 0.37373737,
       0.4040404 , 0.15151515, 0.29292929, 0.31313131, 0.6969697 ,
       0.93939394, 0.61616162, 0.78787879, 0.3030303 , 0.26262626,
       0.17171717, 0.05050505, 0.56565657, 0.52525253, 0.13131313,
       0.63636364, 0.7979798 , 0.4040404 , 0.49494949, 1.        ,
       0.52525253, 0.51515152, 0.85858586, 0.49494949, 0.25252525,
       0.36363636, 0.        , 0.51515152, 0.87878788, 0.42424242,
       0.5959596 , 0.44444444, 0.1010101 , 0.03030303, 0.33333333,
       0.07070707, 0.7979798 , 0.35353535, 0.34343434, 0.11111111,
       0.45454545, 0.95959596, 0.83838384, 0.4040404 , 0.45454545,
       0.45454545, 0.31313131, 0.39393939, 0.58585859, 0.02020202,
       0.19191919, 0.60606061, 0.05050505, 0.25252525, 0.61616162,
       0.73737374, 0.52525253, 0.6969697 , 0.35353535, 0.95959596,
       0.98989899, 0.3030303 , 0.47474747, 0.85858586, 0.        ,
       0.12121212, 0.74747475, 0.18181818, 0.92929293, 0.3030303 ])
# 处理矩阵
X = np.random.randint(0, 100, (50, 2))
# 由于最值归一化得到的是浮点数,所以进行一下类型转换
X = np.array(X, dtype=float)
# 查看是否吧变成浮点数
X[:10]
array([[85., 65.],
       [17., 55.],
       [16., 67.],
       [45., 77.],
       [90., 71.],
       [31., 89.],
       [42., 92.],
       [53., 56.],
       [80., 25.],
       [75., 45.]])
# 对第0列数据,就是这谢数据的第一个特征值,进行最值归一化
X[:, 0] = (X[:,0] - np.min(X[:,0])) / (np.max(X[:,0]) - np.min(X[:,0]))
# 对第1列数据,就是这谢数据的第二个特征值,进行最值归一化
X[:, 1] = (X[:,1] - np.min(X[:,1])) / (np.max(X[:,1]) - np.min(X[:,1]))
# 我们取出前十行看一下对应的数据结果
X[:10,:]
array([[0.89361702, 0.64948454],
       [0.17021277, 0.54639175],
       [0.15957447, 0.67010309],
       [0.46808511, 0.77319588],
       [0.94680851, 0.71134021],
       [0.31914894, 0.89690722],
       [0.43617021, 0.92783505],
       [0.55319149, 0.55670103],
       [0.84042553, 0.2371134 ],
       [0.78723404, 0.44329897]])
# 简单的绘制我们的样本
plt.scatter(X[:,0],X[:,1])
plt.show()
image
# 查看X中第0列对应的均值
np.mean(X[:,0])
0.5546808510638298
# 查看X中第0列对应的方差
np.std(X[:,0])
0.28191296667346266
# 查看X中第1列对应的均值
np.mean(X[:,1])
0.49711340206185567
# 查看X中第1列对应的方差
np.std(X[:,1])
0.2898010576098996

下面我们来看均值方差归一化

X2 = np.random.randint(0, 100, (50, 2))
X2 = np.array(X, dtype=float)
X2[:,0] = (X2[:,0] - np.mean(X2[:,0])) / np.std(X2[:,0])
X2[:,1] = (X2[:,1] - np.mean(X2[:,1])) / np.std(X2[:,1])
# 简单的绘制我们的样本
plt.scatter(X2[:,0],X2[:,1])
plt.show()
image

对于这组数据,我们不能确定得到的结果是在0-1之间的,下面我们来看一下均值和方差

np.mean(X2[:,0])
-2.2204460492503132e-17
np.std(X2[:,0])
1.0
np.mean(X2[:,1])
4.440892098500626e-18
np.std(X2[:,1])
0.9999999999999999
由此可见,我们可以看出均值接近于0,方差接近1

你可能感兴趣的:(4.7 数据归一化)