关于归一化,网上的内容大部分都是在重复归一化的好处,但是之前被问到什么模型可以不做归一化?还有归一化具体的代码实现
这边把这部分的内容也都一起总结一下
一、什么时候可以不做归一化?
什么时候可以不做归一化,这个问题其实很难回答,百度和谷歌后,也没得到满意的结果,这边我结合查到的比较靠谱的资料,写一下自己的理解。
1. 数据属于同量纲的时,且分布较均匀。
这是在知乎上看到的一点,但其实这种情况实际中应该非常少见,或者即时出现了,做归一化与不做归一化区别不大,感觉不存在作者所说的损失信息的说法
但是如果作为面试回答问题的一点,还算可以接受吧。因为本来很多面试问题都是没有较好的答案的。
2.概率模型可以不做归一化
这是在百度问答中看到的一点,可以说是比较好的回答,作者提到的决策树是属于此类,这个还是比较好理解的,决策树中,我们一般逐一对每一个维度进行判断,实际上都是同一维度进行比较,不存在量纲不同的问题。但是衍生出来的问题是,哪些属于概率模型呢?
3.模型是否具有伸缩不变性
这点其实也是在知乎上看到的,但实际我们很难直接知道模型是否具有伸缩不变性,通过观察损失函数或者做两次预测,对比归一化和未归一化后的结果是否一致?
二、归一化的作用
这点在网上是被总结得最多的,基本上每篇博客都会提到,而且大家都是一样的,这边为了完整性也写下来吧
1. 加速梯度下降收敛速度
这点主要是来源吴恩达教学视频,简单的讲,就是让整个环更趋向于正圆形而不是椭圆形,梯度下降朝着最低点下降速度更快
2、归一化有可能提高精度
一些分类器需要计算样本之间的距离(如欧氏距离),例如KNN。如果一个特征值域范围非常大,那么距离计算就主要取决于这个特征,从而与实际情况相悖(比如这时实际情况是值域范围小的特征更重要)。
三、归一化的方法:
网上介绍这部分的也有很多,但是基本都没有相应的代码,这边我补充上使用sklearn库的相应方法的使用。
1、线性归一化
使用sklearn的方法:
min_max_scaler = preprocessing.MinMaxScaler()
X_train_minmax = min_max_scaler.fit_transform(X_train)
X_test_minmax = min_max_scaler.transform(X_test)
经过处理的数据符合标准正态分布,即均值为0,标准差为1,其转化函数为:
scaler = preprocessing.StandardScaler().fit(X_train)
scaler.transform(X_test)
3、非线性归一化
经常用在数据分化比较大的场景,有些数值很大,有些很小。通过一些数学函数,将原始值进行映射。该方法包括 log、指数,正切等。需要根据数据分布的情况,决定非线性函数的曲线,比如log(V, 2)还是log(V, 10)等。
sns.distplot(df_train['SalePrice'], fit=norm);
fig = plt.figure()
res = stats.probplot(df_train['SalePrice'], plot=plt)
![](https://www.kaggle.io/svf/1700573/e06479d4d0768891ce97f68d870bf7da/__results___files/__results___59_0.png)
df_train['SalePrice'] = np.log(df_train['SalePrice'])
四、归一化方法的选择:
使用第一种方法(线性变换后),其协方差产生了倍数值的缩放,因此这种方式无法消除量纲对方差、协方差的影响,对PCA分析影响巨大;同时,由于量纲的存在,使用不同的量纲、距离的计算结果会不同。
而在标准差归一化方式中,新的数据由于对方差进行了归一化,这时候每个维度的量纲其实已经等价了,每个维度都服从均值为0、方差1的正态分布,在计算距离的时候,每个维度都是去量纲化的,避免了不同量纲的选取对距离计算产生的巨大影响。
总结来说,在算法、后续计算中涉及距离度量(聚类分析)或者协方差分析(PCA、LDA等)的,同时数据分布可以近似为状态分布,应当使用0均值的归一化方法。其他应用中更具需要选用合适的归一化方法。