菜鸟笔记
提升您的技术认知

Sklearn之数据预处理——StandardScaler

为什么要进行归一化?

机器学习模型被互联网行业广泛应用,一般做机器学习应用的时候大部分时间是花费在特征处理上,其中很关键的一步就是对特征数据进行归一化,为什么要归一化呢?维基百科给出的解释:

  • 归一化后加快了梯度下降求最优解的速度;

如果机器学习模型使用梯度下降法求最优解时,归一化往往非常有必要,否则很难收敛甚至不能收敛。

  • 归一化有可能提高精度;

一些分类器需要计算样本之间的距离(如欧氏距离),例如KNN。如果一个特征值域范围非常大,那么距离计算就主要取决于这个特征,从而与实际情况相悖(比如这时实际情况是值域范围小的特征更重要)。

哪些机器学习算法不需要(需要)做归一化?

 概率模型(树形模型)不需要归一化,因为它们不关心变量的值,而是关心变量的分布和变量之间的条件概率,如决策树、RF。而像Adaboost、SVM、LR、Knn、KMeans之类的最优化问题就需要归一化。

StandardScaler原理

作用:去均值和方差归一化。且是针对每一个特征维度来做的,而不是针对样本。 

标准差标准化(standardScale)使得经过处理的数据符合标准正态分布,即均值为0,标准差为1,其转化函数为:

             

其中μ为所有样本数据的均值,σ为所有样本数据的标准差。

  • 下面使用numpy来实现一个矩阵的标准差标准化
import numpy as np

x_np = np.array([[1.5, -1., 2.],
                [2., 0., 0.]])
mean = np.mean(x_np, axis=0)
std = np.std(x_np, axis=0)
print('矩阵初值为:{}'.format(x_np))
print('该矩阵的均值为:{}\n 该矩阵的标准差为:{}'.format(mean,std))
another_trans_data = x_np - mean
another_trans_data = another_trans_data / std
print('标准差标准化的矩阵为:{}'.format(another_trans_data))
矩阵初值为:[[ 1.5 -1.   2. ]
            [ 2.   0.   0. ]]
该矩阵的均值为:  [ 1.75 -0.5   1.  ]
该矩阵的标准差为:[0.25 0.5  1.  ]
标准差标准化的矩阵为:[[-1. -1.  1.]
                     [ 1.  1. -1.]]

经结果验证,新值符合 --->(旧值-均值)/ 标准差 .

  • 下面使用sklearn提供的StandardScaler方法
from sklearn.preprocessing import StandardScaler  # 标准化工具
import numpy as np

x_np = np.array([[1.5, -1., 2.],
                [2., 0., 0.]])
scaler = StandardScaler()
x_train = scaler.fit_transform(x_np)
print('矩阵初值为:{}'.format(x_np))
print('该矩阵的均值为:{}\n 该矩阵的标准差为:{}'.format(scaler.mean_,np.sqrt(scaler.var_)))
print('标准差标准化的矩阵为:{}'.format(x_train))
矩阵初值为:[[ 1.5 -1.   2. ]
            [ 2.   0.   0. ]]
该矩阵的均值为:   [ 1.75 -0.5   1.  ]
 该矩阵的标准差为:[0.25 0.5  1.  ]
标准差标准化的矩阵为:[[-1. -1.  1.]
                     [ 1.  1. -1.]]

可以发现,sklearn的标准化工具实例化后会有两个属性,一个是mean_(均值),一个var_(方差)。最后的结果和使用numpy是一样的。

其他的归一化类型

  • 线性归一化

这种归一化方法比较适用在数值比较集中的情况。这种方法有个缺陷,如果max和min不稳定,很容易使得归一化结果不稳定,使得后续使用效果也不稳定。实际使用中可以用经验常量值来替代max和min。

  • 非线性归一化 

经常用在数据分化比较大的场景,有些数值很大,有些很小。通过一些数学函数,将原始值进行映射。该方法包括 log、指数,正切等。需要根据数据分布的情况,决定非线性函数的曲线,比如log(V, 2)还是log(V, 10)等。