数据预处理的标准化和归一化
对数据预处理的必要性:
举个例子,假如现在要评价一个学生在学校的综合表现,有以下三个指标:思想道德,学业成绩,科研竞赛,权重是0.2,0.5,0.3,但是三个指标给出来的数据是90分,3.7(绩点),400分。现在如果不对数据进行任何处理直接利用权重乘以数值的方式来的出综合结果的话,当科研竞赛增加100分时对最终结果的影响很大,而绩点即便拼了老命增加0.5也不及增加100分的结果高,这样是不是很不合理,所以对数据先进行处理是很必要的。(例子只是呈现了一个小方面,还有其他很多必要处理的情况)
标准化后的数据是没有单位的数值,消除了量纲(单位)和不同属性数值差距大的影响,让不同属性的数据能够在同一数量级上进行比较和计算,让分析结果更加合理,数据运算不至于扭曲。以下是两种常见的数据处理方法:
1. Min-max normalization
x
i
′
=
(
x
i
−
x
m
i
n
)
/
(
x
m
a
x
−
x
m
i
n
)
x_i'=(x_i-x_{min})/(x_{max}-x_{min})
xi′=(xi−xmin)/(xmax−xmin)
-
它还被叫做:离差标准化,0-1标准化,线性函数归一化。能将数据的范围限制在0~1之间,是消除量纲和数据变异大小影响的最简单方法。
-
适用:一般适用于通过梯度下降法求解的模型(KNN,SVM,K-means,线性回归等)。
-
优点:在机器学习中,能够提升模型的收敛速度和精度,防止模型梯度爆炸。
-
缺点:当数据中有异常值时,影响较大。比如一组数据:0,1,2,3,4,200,归一化后数值基本趋近于0 ,很难比较差异(如下图)。
- zero-mean normalization**
x i ′ = ( x i − x 平均 ) / s 标准差 x_i'=(x_i-x_{平均})/s_{标准差} xi′=(xi−x平均)/s标准差
- 该方法也叫标准差标准化,正规化方法。处理后变量的数值有的小于0,表示低于平均水平,有的大于0,表示高于平均水平,变量的平均值为0,标准差为1。
- 适用:近似正态(高斯)分布的原始数据,最大值和最小值未知的情况,超出取值范围的离群数据的情况,在分类、聚类算法中,需要使用距离来度量相似性,或是使用PCA(主成分分析法)进行降维的情况。
- 优点:简单,容易计算,不受数据量级的影响,结果适合用于比较。
- 缺点:处理后的数据不再是原来的分布状态,失去了原先的意义,只能用于数据间的比较。
说明:如果原始数据不是正态分布的,得到的结果就不会是正态分布(本质上是对数据进行线性变换),这样也不便对结果进行分析,因此对不是正态分布的原始数据该方法的效果不佳。这里有一个中心极限定理可以了解一下:在自然界与生产中,一些现象受到许多相互独立的随机因素的影响,如果每个因素所产生的影响都很微小时,总的影响可以看作是服从正态分布的。
补充
1.上面两种方法都是对数据进行线性变换,还有很多非线性变换的处理方法,如:log函数转换,atan函数转换,小数定标标准化等。
2.两种方法的python代码:
# Min-max normalization:直接写出公式
import numpy as np
# 初始化数据(随便写了一个数组)
data = np.array([arange(1,4),arange(17,20),arange(56,59)])
# 记录数组的行数和列数
data_rows = data.shape[0]
data_cols = data.shape[1]
# 创建新数组
new_data = np.zeros(shape = (data_rows,data_cols))
for i in range(0,data_rows,1):
for j in range(0,data_cols,1):
data_col_min = min(data[:,j])
data_col_max = max(data[:,j])
new_data[i][j] = (data[i][j]-data_col_min)/(data_col_max - data_col_min)
print(new_data)
z-score可以直接调用sklearn中的模块函数(代码出处:http://t.csdn.cn/4NUes):
from sklearn import preprocessing
import pandas
data={'price':[492,286,487,519,541,429]} # 用字典来存放数据
price_frame=pandas.DataFrame(data) # 把字典类型转化为dataframe对象
normalizer=preprocessing.scale(price_frame)
# 沿着某个轴标准化数据集,以均值为中心,以分量为单位方差
price_frame_normalized=pandas.DataFrame(normalizer,columns=['price'])
# 将标准化的数据转换为dataframe对象,将列名改为price
print(price_frame_normalized)