【机器学习08】数据归一化 Fearture Scaling

数据归一化 Fearture Scaling。

摘要:介绍最大最小值归一化和均值方差归一化。

上一篇文章末我们说到了影响 kNN 模型的一个至关重要的因素,即距离(数据)的归一化问题。可拆解成 距离归一化两点。kNN 模型就是依靠样本点之间的距离来分类的,所以距离对 kNN 模型的分类效果很重要。至于归一化,来看两幅图就知道了。

从下面的图中可以直观看到,黄色点离绿色点更近。

接着,把纵坐标轴的单位年放大成天后得到下图。虽然点坐标和上图一样,但是 y 轴刻度是 x 轴的 50 倍,所以 y 轴主导了两点之间的距离。尽管黄色点和红色点的 x 轴距离比绿色点远,但是 y 轴距离要比绿色点近很多,这样一来,黄色点变得离红色点更近了。

假设这个黄色点表示一个患肿瘤的病人,现在要用 kNN 模型判断该该病人患的是良性肿瘤还是恶性肿瘤,准确分类就变得非常重要。

所以对 kNN 模型来说数值的单位对模型影响很大。

为了消去距离的影响,可以消除数值的量纲,最好的方法就是做归一化处理,将所有数据映射到同一尺度。归一化方法有很多种,常用的是最大最小值归一化和均值方差归一化。

最大最小值归一化 Normalization

$$
x_{\text { scale }}=\frac{x-x_{\text { min }}}{x_{\text { max }}-x_{\text { min }}}
$$

最值归一化很简单,就是将所有数据映射到 0-1 之间

它有两个特点。一个是适用于数据分布有明显边界的情况,比如学生考试成绩,分数是有边界的,通常在 0 到 100 分范围内。另外一个特点是容易极端值影响,比如一个公司员工和老板的收入,员工平均收入是两万元,而老板收入一百万元,对这样的数据归一化后,老板的值是 1,而员工数值基本是 0,数据呈现严重的有偏分布,对后续建模不利。

mark

根据上面的最大最小值公式对刚才的肿瘤数据归一化,绘制归一化后的分布图:

mark

mark

坐标轴的刻度都是 0.2,黄色点离绿色点更近。

那么,对没有明显边界的分布数据,或者有极端值的数据可以使用用:均值方差归一化。

均值方差归一化 standardization

这种方法是把所有数据映射到 均值为 0 方差为 1 的分布中。即使有极端值存在,也不会出现严重的数据有偏分布,便于后续建模。
$$
x_{\text { scale }}=\frac{x-x_{\text { mean }}}{s}
$$
根据这个公式编码绘制出归一化后的图:

mark

相比最值归一化,坐标轴起始点不是 0 -1,但数据基本沿两轴中心对称分布。

所以,通常情况下建议使用用均值方差归一化。当然,还有别的归一化方式,以后再讲。


下面,我们在 Sklearn 中使用归一化方法。

Sklearn 最值归一化

先来看一下最值归一化,仍然使用葡萄酒数据集。该数据集有十三个特征,特征的样本分布范围差别很大,有的达到上百倍只差。比如 Alcohol(酒精度) 和 Proline(脯氨酸) 两个特征样本。

mark

现在,将全部特征映射到 0-1 的范围后建模,预测模型得分效果如何,分三个步骤。

第一步,将数据归一化。加载和划分数据集已经练习过很多遍了不用多说。Sklearn 中的最值归一化方法是 MinMaxScaler 类,fit 拟合之后调用 fit_transform 方法归一化训练集。

mark

解释一下 fit 、 fit_transform 和 transform 的作用和关系。

在执行归一化操作时,一定要先 fit 然后才能调用 fit_transform。因为 fit 的作用是计算出训练集的基本参数,比如最大最小值等。只有当最大最小值有确定的数值时,才能通过 fit_tranform 方法的断言,进而才能运行并进行归一化操作。否则不先运行 fit 那么最大最小值的值是空值,就通不过 fit_transform 的断言,接着程序就会报错。虽然计算最大最小值和归一化这两个步骤不相关,但 Sklearn 的接口就是这样设计的。

所以,要先 fit 然后 fit_transform。至于 transform,它的作用和 fit_transform 差不多,只是在不同的方法中应用。比如 MinMaxScaler 中是 fit_transform,等下要讲的均值方差归一化 StandardScaler 中则是 transform。

第二步,建立 kNN 模型。这一步也做过很多遍了。

mark

第三步,测试集归一化并预测模型。

这里一定要注意测试集归一化的方法:是在训练集的最大最小值基础归一化,而非测试集的最大最小值。

为什么是在训练集上呢?其实很好理解,虽然我们划分出的测试集能很容易求出最大最小值,但是别忘了我们划分测试集的目的:来模拟实际中的情况。而在实际中,通常很难获得数据的最大最小值,因为我们得不到全部的测试集。比如早先说的案例:酒吧猜新倒的一杯红酒属于哪一类。凭这一杯葡萄酒它是没有最大最小值的,你可能说加多样本,多几杯红酒不就行了?但这也只是有限的样本,有限样本中求出的最大最小值是不准确的,因为如果再多加几杯酒,那参数很可能又变了。

所以,测试集的归一化要利用训练集得到的参数,包括下面要说的均值方差归一化。

mark

这样求出模型得到了 0.907 的高分。而我们之前用未归一化的数据建立的模型仅得到 0.76 分。即使后来通过网格搜索调参的方式,得到的模型得分也远没有这个分数高。

可见,建模前的数据归一化有多重要。

说完均值归一化,下面再来介绍 Sklearn 中的均值方差归一化。

Sklearn 均值方差归一化

建模的步骤和上面一样,也是三步走。只是第二步使用的是 StandardScaler 类,使用该类会自动把训练集转变为均值为 0 方差 1 的数据分布。

最后查看模型得分,达到 0.96,比刚才的得分还要高。将得分换算成测试集红酒的分类准确率的话,就是 54 个测试样本中,正确分类了其中的 52 个,仅错了 2个,而未归一化的 0.76 分,错了 13 个之多。

mark

最后小结一下,拿到一份数据集后,做基本的数据探索,查看特征数据分布是否差别很大,很大的话需要进行归一化,建议采用均值方差归一化。尤其是对 kNN 这种算法来说,模型好坏跟距离是直接相关的,对于后续会介绍的一些跟距离不相关的模型,比如决策树等,归一化就没有太大必要。

本文的 jupyter notebook 代码,可以在公众号:「高级农民工」后台回复「kNN8」得到,加油!

你一打赏,我就写得更来劲了
0%