前言
本系列是《玩转机器学习教程》一个整理的视频笔记。在上一小节详解介绍了什么是核函数,并且以多项式核函数为例介绍了核函数的实际含义。本小节具体来介绍另外一种比较特殊的核函数:高斯核函数,高斯核函数是在SVM算法中使用最多的一种核函数。
a
什么是高斯核函数?
通常我们会将核函数表示成函数 K(x, y),其中 x, y 为两个样本点的特征向量,核函数表示的就是重新定义后的 x 和 y 的点乘。高斯核函数的定义如下所示:
高斯核函数的表达式虽然看起来很复杂,但是记起来比较简单,e 的幂次方,幂次方的式子为 -γ 乘以 (x - y) 向量模的平方,式子中的 γ 类似多项式核函数表达式中的 d 和 c 一样是一个超参数,所以对于高斯核函数来说只有一个超参数 γ。
为什么会将这样的函数称为高斯核函数呢?高斯核函数和基础概率论中的正太分布非常像。
正太分布其实就是一个高斯函数,对比高斯函数与高斯核函数会发现:
通过对比高斯函数(正太分布函数)和高斯核函数它们之间的关系能够帮助我们更好的记忆高斯核函数的表达式。高斯核函数被称为RBF核(Radial Basis Function Kernel),中文也称为径向基核函数。高斯核函数、RBF核和径向基核函数代表的是同一个函数。为了方便记忆,sklearn 将svm算法中的高斯核函数称为rbf。
前面小节在介绍多项式核函数的时候提到过多项式核函数的本质就是为所有的样本点添加多项式项的特征,然后再将这些多项式项的新的样本特征进行点乘就形成了多项式核函数。类似的,高斯核函数的本质也是将原来样本点先映射成为一种新的特征向量,然后再将这些新的特征向量进行点乘,不过高斯核函数表达出来的这种映射非常复杂。在学习过程中经常会听到:"高斯核函数的本质就是将每一个样本点映射到无穷维的特征空间",这种说法。这种说法听起来比较抽象,虽然高斯核函数将每一个样本点进行变形非常复杂,但是经过这种变形之后再进行点乘得到的结果却非常简单,即下式中的 k(x, y) 函数。
核函数再一次显现出它的威力,核函数可以让我们不需要具体计算出对于每一个样本点 x 和 y 到底变成了一个怎样的新的样本点,而是直接关注映射成新的样本点之后的点乘结果。
为了能够对高斯核函数有一个更加感性的认识,这里使用一个简单的小例子来进行模拟,来看看高斯核函数到底在做什么事情?在这之前首先回忆一下使用多项式特征为什么可以处理非线性数据的问题。多项式特征的基本原理就是升维,也就是将我们原来的样本点按照某种规则扩充样本点的维度。
在多项式特征中,我们要做的事情就是添加多项式的特征,使得原本线性不可分的数据变得线性可分。比如如果原本的样本点只有一个特征 x,那么现在为每一个样本点相对应的添加新的特征 x 的平方,这样就可能使得原本线性不可分的数据集变的线性可分。
下面通过可视化一个简单的小例子来说明添加多项式特征能够将线性不可分的数据变成线性可分,原本的样本点只有一个特征,可以用一个坐标轴将这些样本点表示出来,坐标轴上的不同位置表示样本点的不同特征值,这些样本点分为红色和蓝色两个类别。
显然此时的数据是线性不可分的,也就是说我们没有办法找到一根直线将红色和蓝色两个类别的样本点完全分开。如果我们为数据添加多项式特征的话,做的就是升维的过程,也就是让每一个样本点不仅有横坐标轴一个维度,还有纵坐标轴的第二个维度。每个样本点的:
此时,我们所有数据点一下子变成了下图的样子。
这些样本点在横坐标轴上的位置没有改变,只不过在纵坐标轴上相应的也有了一个取值,这个取值就是对应新添加的样本点特征值 x 的平方。这些样本点原本在一维空间(横坐标轴)中是线性不可分的,可是添加多项式特征之后我们很容易找到一根直线把红色和蓝色两个类别区分开,即线性可分,这就是升维的意义,我们依靠最原始的数据进行升维可以使原本线性不可分的数据线性可分。
高斯核函数本质上也是在做同样的事情。为了方便可视化,首先对高斯核函数进行一个改变,高斯核函数中原本是 x - y 的平方,现在将这个 y 值固定。换句话说,此时的 y 值不再取样本点,而是取固定的点,这里取固定的两个点,分别称为 l1 和 l2。将 y 值固定成 l1 和 l2 两个值之后,依然是一维样本点,依然只有红色和蓝色两个类别以及数据依然是线性不可分的。
一维样本点中找出 l1 和 l2 两个特殊的点,l1 和 l2 通常称为land mark不过现在在这个一维样本空间中拎出两个特殊的点,我们管着两个点称为 L1和 L2,这两个特殊点的英文名通常称为Land Mark,中文翻译成地标。
如果设置两个地标的话,高斯核函数将一维样本点升维到二维样本点,这二维的样本点每一个样本点的坐标取值如下所示。
对于每一个二维样本点:
这样就将原本一维的样本点映射到一个二维空间中。
b
直观理解高斯核函数
下面使用编程的方式模拟一下,更加直观的看看这样一个映射是如何将原来线性不可分的数据变的线性可分。
本小节使用的数据集非常简单,生成-4到5前闭后开步长为1的向量 x,每一个样点都只有一个特征。为了构造一个线性不可分的二分类问题,对于分类标签 y,将特征值>=-2并且<= 2 区间的样本点类别设置为1,将其余范围特征值的样本点类别设置为0。接下来绘制出数据集的分布。
通过绘制结果可以看出,此时的数据集显然是线性不可分的。
接下来可以尝试使用高斯核函数来看看是如何将一维线性不可分的数据映射成一个二维空间线性可分的数据。定义一个名为gaussian的函数,函数中的两个参数分别是 x 样本点和 l 地标。
在高斯核函数的公式中有一个 γ 参数,此时将 γ 值固定为1.0。由于传入的 x 和 l 都是一个数(后面通过 for 循环调用 gaussian 函数),因此不需要考虑计算模式,所以在代码中直接写成 x - l 结果的平方。
接下来就可以实现具体的映射过程,这一小节固定了两个地标l1,l2,让 l1 和 l2 取固定值-1和1。
使用 X_new 存储新的二维样本点,首先使用 np.empty 函数开辟一块空间。使用 for 循环每次取出一维样本点的特征值 data,然后根据 l1 和 l2 两个地标分别计算出 X_new 的第1个特征和第2个特征。此时的 X_new 存放的就是经过高斯核函数计算映射出来的二维样本点。
接下来对 X_new 进行可视化。
使用高斯核函数的思路将原来的一维样本点映射到二维空间的二维样本点,映射后的二维样本点显然是线性可分的,可以很容易的使用一根直线将红色和蓝色类别的样本点区分开。
通过下面的式子将一维样本点映射成了二维样本点。
对比与原本的高斯核函数,此时高斯核函数中原来 y 的位置被固定成了两个地标 l1 和 l2。实际上我们的高斯核函数如下所示。
此时 y 的位置其实是每一个样本点,换句话说,高斯核函数所做的事情和之前是一样的。此时 y 位置的样本点可以看成是地标点,只不过这个时候的地标点取的要比以前固定的两个地标点要多的多,有多少个样本点就有多少个地标点。高斯核函数的本质就是升维,但是它是将一个 (m * n) 的数据集映射成了 (m * m) 的数据集,也就是说数据集中一共有 m 个样本点,并且原本每个样本点只有 n 个特征维度,经过高斯核函数之后,每个样本点被映射成了 m 个特征维度。如果 m 非常大的话,经过高斯核函数会将原始样本点映射到非常高维的空间中。
通过这样一个小例子,可以更加感性的理解为什么很多资料会有"高斯核函数的本质就是将每一个样本点映射到无穷维的特征空间"的说法,由于样本点可以有无穷多个,所以才会有所谓的无穷维的空间。不过通常在实际中的样本个数 m 为有限个,使用高斯核函数都需要计算这 m 个样本点,这个计算开销是非常大的。正因为如此在 SVM 算法中使用这种高斯核函数,训练的时间会比较长,但是尽管如此还是存在一些非常适合使用这种高斯核函数的场景,其中最为典型的是在初始样本点的特征维度非常高,但是样本的数量可能并不多的场景。换句话说,如果数据集的样本数量 m 小于样本的特征维度 n 的时候,使用高斯核函数的 SVM 算法非常划算。样本数量 m 小于样本的特征维度 n 的场景多见于自然语言处理领域,通常我们需要构建一个非常高维度的特征空间,但是很有可能样本数量相对来说并不多。
c
小结
这一小节详细介绍了什么是高斯核函数。下一小节将会具体的使用高斯核函数的 SVM 来看看分类的结果是怎样的,以及得到分类结果的决策边界。此外在下一小节将会介绍高斯核函数中 γ 超参数的具体作用。