一文弄懂特征缩放(归一化/正则化)

引言

特征缩放是机器学习预处理数据中最重要的步骤之一,它有时能决定学习模型的好坏。

特征缩放的作用如下:

  1. 加快梯度下降
  2. 提升模型精度(消除不同量纲)
  3. 防止梯度爆炸(消除过大值的影响)

为什么要特征缩放

在机器学习算法处理数据时通常是忽略数据的单位信息的,或者说不知道这些数据代表什么。比如50kg和50公里代表着两个不同的度量,人类是很容易区分它们的。但是对于机器来说,这两个数据是一样的。

import pandas as pd
import numpy as np
data = np.array([[1,172,30000],[2,160,60000],[3,175,50000],[4,180,5000]])

df = pd.DataFrame(data,columns=['staff','height','salary'])
df

在这里插入图片描述

我们来看下上面的表格,上面是员工身高与薪水的表格。我们人类看到数字172(cm)知道就是身高,看到5000知道肯定是薪水。但是机器就不知道。

假设用神经网络来学习这份数据,那么就会导致取值范围更大的薪水会主导模型的训练,也就是模型会偏向于薪水,但通常我们不希望我们的算法一开始就偏向于某个特征。

假设我们尝试计算两个员工的欧氏距离,在特征缩放之前的结果是:

员工1和员工2的距离: ( 172 160 ) 2 + ( 30000 60000 ) 2 = 30000.002 \sqrt{(172-160)^2 + (30000 - 60000)^2} = 30000.002
员工2和员工3的距离: ( 160 175 ) 2 + ( 60000 50000 ) 2 = 10000.011 \sqrt{(160-175)^2 + (60000 - 50000)^2} = 10000.011

从上面的结果可以看到它们的距离基本上就是薪水的差值。

而在经过最大最小值归一化后(下文会讲到)的结果是:
员工1和员工2的距离: ( 0 0.6 ) 2 + ( 0.45 1 ) 2 = 0.814 \sqrt{(0-0.6)^2 + (0.45 - 1)^2} = 0.814
员工2和员工3的距离: ( 160 175 ) 2 + ( 60000 50000 ) 2 = 0.773 \sqrt{(160-175)^2 + (60000 - 50000)^2} = 0.773

显然经过特征缩放后的结果更具有可比性。

这个问题不仅会出现在神经网络里面,还会出现在任何基于距离计算的算法中。特征缩放就可以解决这个问题。

特征缩放有哪些方法

有很多种特征缩放的方法,我们一一来分析。

均值归一化(Mean Normalization)

将数值范围缩放到 [ 1 , 1 ] [-1,1] 区间里,数据的均值变为 0 0

x = x m e a n ( x ) m a x ( x ) m i n ( x ) x^\prime = \frac{x - mean(x)}{max(x) - min(x)}

以上面的例子说明,假设我们要均值归一化员工1的薪水。那么 m e a n ( x ) = 36250 , m a x ( x ) = 60000 , m i n ( x ) = 5000 mean(x) = 36250,max(x) = 60000,min(x) = 5000

x = 30000 36250 60000 5000 = 0.1136 x^\prime = \frac{30000 - 36250}{60000 - 5000} = -0.1136

下面是对薪水和身高进行均值归一化的结果:

data_mean = data[:,1:]
data_mean = (data_mean - data_mean.mean(axis=0)) / (data_mean.max(axis=0) - data_mean.min(axis=0))

pd.DataFrame(np.c_[np.arange(1,5),data_mean],columns=['staff','height','salary'])

在这里插入图片描述

最大最小值归一化(Min-Max Normalization)

最大最小值归一化简称为归一化,将数值范围缩放到 [ 0 , 1 ] [0,1] 区间里

x = x m i n ( x ) m a x ( x ) m i n ( x ) x^\prime = \frac{x - min(x)}{max(x) - min(x)}

以上面的例子说明,假设我们要最大最小值归一化员工1的薪水。那么 m e a n ( x ) = 36250 , m a x ( x ) = 60000 , m i n ( x ) = 5000 mean(x) = 36250,max(x) = 60000,min(x) = 5000

x = 30000 5000 60000 5000 = 0.455 x^\prime = \frac{30000 - 5000}{60000 - 5000} = 0.455

下面是对薪水和身高进行均最大最小值归一化的结果:

data_min_max = data[:,1:]
data_min_max = (data_min_max - data_min_max.min(axis=0)) / (data_min_max.max(axis=0) - data_min_max.min(axis=0))

pd.DataFrame(np.c_[np.arange(1,5),data_min_max],columns=['staff','height','salary'])

在这里插入图片描述

标准化/z值归一化(Standardization/Z-Score Normalization)

标准化又叫z值归一化,将数值缩放到0附近,且数据的分布变为均值为0,标准差为1的标准正态分布。

x = x m e a n ( x ) σ ( x ) x^\prime = \frac{x - mean(x)}{\sigma(x)}

σ ( x ) \sigma(x) x x 的标准差,计算公式为:
σ ( x ) = 1 N i = 1 N ( x i m e a n ( x ) ) 2 \sigma(x) = \sqrt{\frac{1}{N} \sum_{i=1}^N (x_i - mean(x))^2}

以上面的例子说明,假设我们要标准化员工1的薪水。那么 m e a n ( x ) = 36250 , σ ( x ) = 21028 mean(x) = 36250,\sigma(x)=21028

x = 30000 36250 21028 = 0.2972 x^\prime = \frac{30000 - 36250}{21028} = -0.2972

下面是对薪水和身高进行标准化的结果:

data_std = data[:,1:]
data_std = (data_std - data_std.mean(axis=0)) / (data_std.std(axis=0))

pd.DataFrame(np.c_[np.arange(1,5),data_std],columns=['staff','height','salary'])

在这里插入图片描述

常见问题&注意事项

哪些算法需要特征缩放

特征缩放对基于距离的算法特别重要。因此像KNN、线性回归、逻辑回归、SVM等都需要特征缩放。
不基于距离的算法像朴素贝叶斯以及基于树结构的算法(决策树、随机森林)等不需要特征缩放。

另外,0/1取值的特征不需要归一化。

归一化还是标准化

  • 如果你知道数据分布不是正态分布,那么使用归一化。像用在KNN和NN这种不假设数据分布的算法就很合适。 最大最小值归一化容易受异常值影响,常用于归一化图像的灰度值。
  • 当数据是正态分布时进行标准化是很有帮助的,不像归一化,标准化的数据没有限定范围,对异常值不敏感。
  • 然后,具体的选择还是依赖于你的数据或算法,通常最好归一化和标准化都尝试一下,看哪种方法好。

注意事项

需要先把数据拆分成训练集与验证集,在训练集上计算出需要的数值(如均值和标准值),对训练集数据做标准化/归一化处理(不要在整个数据集上做标准化/归一化处理,因为这样会将验证集的信息带入到训练集中,这是一个非常容易犯的错误),然后再用之前计算出的数据(如均值和标准值)对验证集数据做相同的标准化/归一化处理。

参考

  1. https://www.cnblogs.com/HuZihu/p/9761161.html
  2. https://www.analyticsvidhya.com/blog/2020/04/feature-scaling-machine-learning-normalization-standardization
  3. https://machinelearningknowledge.ai/feature-scaling-machine-learning/

猜你喜欢

转载自blog.csdn.net/yjw123456/article/details/106252908