在之前的BLOG中,我们介绍了支持向量机SVM。在许多运用到SVM的实际问题中,我们往往需要另一个高效的工具来加快运行效率,而这个工具就是我们今天要讲的核函数。

高斯核函数

在之前的BLOG里,我们一起学习了SVM-支持向量机,但是在复杂的非线性拟合的时候,使用多项式去拟合往往效率十分低下,所以现在,就让我们一同学习"kernels(核函数)",来达到简化计算过程的目的。这一部分就让我们来看看核函数是什么以及如何使用核函数。

现在让我们来看一个例子。假如我们有一个训练集,像下图这个样子,然后按照之前的做法,我们就会希望通过多项式特征变量来拟合一个非线性的判别边界来区别正负样本:

KN1.png

这种方法的另一种写法是我们可以把那些带x的多项式转化为f,比如在这里,我们设几个新的符号 f1 f2 f3等等来表示一系列我将要计算的新的特征变量,那么我们继续设 f1=x1,f2=x2,f3=x1x2,f4=x1^2,f5=x2^2…,那么我们的式子就变成了θ0 + θ1×f1 + θ2×f2 + θ3×f3 + ……

在这里,我们可以看到,我们可以通过加入一些关于x的高阶项来作为特征变量来替代 f 以得到我们的假设函数。但其实我们不一定要选择高阶项,可以选择别的特征变量。那好好的我们为什么要改变我们之前已经掌握的高阶项作为特征向量呢?因为以后在我们处理计算机视觉的时候,那是的输入就会是一个有很多像素的图像,如果我们用高阶项作为特征变量,那运算量将是非常大的。因此我们需要找到一个更好的选择来构造特征变量以用来嵌入到假设函数中。

那我们可以怎么构造呢?现在我们一起来学习一个可以构造 新特征f1 f2 f3的方法。让我们来通过例子说明,在这个例子中我们只定义两个特征变量 x1 和 x2 。然后我们手动选取一些点,这里为了方便展示就选取三个点,l(1),l(2)和l(3):

KN2.png

记住这三个点一般被称为标记,所以他们分别就是标记1,标记2和标记3。接下来我要做的是这样定义新的特征变量,给出一个样本 x:

KN1.5.png

将第一个特征变量 f1 定义为一种相似度的度,即度量样本 x 与 第一个标记 l(1) 的相似度。接着我们可以用下面这个公式来度量 x 和 l(1) 的相似度:

KN2.5.png

其中 ||w|| 表示的是向量 w 的长度。而所以 x 对于 l(2) 和 l(3) 的相似度也是类似的:

KN3.png

用数学术语来说,这个相似度函数是核函数,而我们现在所学习的核函数,更准确地说其实是是高斯核函数。之后我们会见到别的核函数,但是现在我们先学会使用这个高斯核函数——这个相似度函数。

现在让我们来看看高斯核函数的含义是什么,为什么这些相似度函数可以作为特征值。先来看看我们的第一个标记l(1),让我们来看看这个函数计算的是什么。假设x与l(1)非常接近,那么这个相似度的幂次的分子就会接近于0,那么整个相似度f1 ≈ e^0 = 1;而相反地如果x离l(1)越远,那么f1就等于对一个非常大的数字的平方除以2σ的相反数再取exp,即f1 ≈ e^-∞ = 0。所以我们可以清楚的看到这些特征变量 f 的作用其实就是度量 x 到标记 l 的相似度,并且如果 x 离 l 非常相近,那么特征变量 f 就接近于1,反之如果 x 离标记 l 非常远,那么 f 会约等于0:

KN4.png

之前我所画的那几个标记点 l(1) l(2) l(3) 每一个标记点都会定义一个新的特征变量 f1 f2 f3 。也就是说给出一个训练样本 x ,我们就能基于我们之前给的三个标记点计算三个新的特征变量 f1 f2和 f3 :

KN1.5.png

可能仅仅通过数学的方式来说明你还觉得有些抽象。没事现在我们来看看这个相似度函数的一些图像来更好地理解这些函数是什么样的。

比如假设我们有两个特征值 x1 和 x2,假设我们的第一个标记点是 l(1) 其位于(3,5) ,接着假设σ的平方等于 1。此时如果我们画出图,就会像下面这样:

KN5.png

右边的上面那幅图的曲面的高度就是 f1 的值,水平的坐标代表的就是 x1 和 x2 的值。下面的这个图表达的内容其实是一样的,但它是一个等高线图,x1为水平轴 x2 为竖直轴,即是上面那幅图的3D曲面的等值线图。我们可以发现,当 x 等于(3,5)的时候,这个时候 f1 就等于1,而当 x 往旁边移动离这个点越远时,f1 的值就会越接近 0。这就是特征变量f1计算的内容,也就是X与第一个标记点的远近程度。这个值在0到1之间,具体取决于 x 距离标记点l(1)到底有多近。

接下俩我们来看看改变 σ^2 的值能产生多大影响。 σ^2 是高斯核函数的参数,当我们改变它的值的时,就会得到略微不同的结果。假设我们让 σ^2 = 0.5 ,我们就会发现核函数看起来还是相似的,只是这个突起的宽度变窄了,等值线图也收缩了一些。与此相反地如果我们增大了 σ^2 的值,比如假设 σ^2 = 3,我们就会发现此时特征变量的值减小的速度会变得比较慢:

KN6.png

在讲完了特征变量的具体含义之后,我们来看看我们通过这个高斯核函数能得到什么样的预测函数。给定一个训练样本x 我们要计算出三个特征变量 f1 f2 f3 ,如果θ0 + θ1*f1 + θ2*f2 + θ3*f3 ≥ 0,我们预测函数的预测值就会等于1:

KN10.png

对于这个特定的例子而言,假设我们已经找到了一个学习算法并且已经得到了这些参数 θ 的值,比如 θ0 = -0.5 θ1 = 1,θ2 = 1,θ3 = 0。

下面我们来看看对于下图这样的一个训练样本,我们的预测函数会给出怎样的预测结果:

KN7.png

此时因为我们的训练样本 x 接近于 l(1),所以 f1 就接近于 1,又因为训练样本 x 离l(2) l(3) 都很远,所以 f2 就接近于 0 ,f3 也接近于 0。代入这些数据后,我们的 θ0 + θ1*f1 + θ2*f2 + θ3*f3 ≈ 0.5 ≥ 0。因此这个点我们预测出的 y 值是 1。

现在我们选择另一个不同的点:

KN8.png

如果我们进行和之前相同的计算,我们就会发现f1 f2 f3都接近于0,因此我们得到此时θ0 + θ1*f1 + θ2*f2 + θ3*f3 ≈ -0.5 < 0。因此这个点我们预测的 y 值是0。

所以实际上,我们最后得到的结果是下面这条分界线:

KN9.png

如果我们看看这个边界线,就会发现对于接近l(1)和l(2)的点,我们的预测值是1;而对于远离 l(1)和l(2)的点,我们最后预测的结果是等于 0 的。因此这就是一个我们如何通过标记点以及核函数来训练出非常复杂的非线性判别边界的例子。

以上就是核函数这部分的概念以及我们如何在支持向量机中使用它们。我但是还有一些问题我们并没有做出回答,其中一个是我们如何得到这些标记点,或者说我们怎么来选择这些标记点;另一个是我们实现核函数还有什么要注意的细节吗?在下一部分中,我们会一同解决这些问题,然后把所有东西都整合到一起来看看支持向量机如何通过核函数的定义有效地学习复杂非线性函数。

核函数的实现细节

在上一部分中,我们谈到过选择标记点,例如 l(1) l(2) l(3),这些标记点的选择使我们能够定义相似度函数,也就是我们的核函数。但是我们从哪里得到这些标记点?换句话说我们该如何选择l(1) l(2) l(3)呢?要知道在一些复杂的学习问题中也许我们需要更多的标记点而不是我们手选的这三个。因此在实际应用时怎么选取标记点是机器学习中必须解决的问题。

我们先来看一个例子,下面是我们的数据集,有一些正样本和一些负样本,我们很自然的一个想法就是直接将训练样本作为标记点:

KN11.png

如果我们有一个训练样本x(1),那么我们将把第一个标记点放在跟我的第一个训练样本点完全重合的地方;如果我们有另一个训练样本x(2),那么我们将把第二个标记点选在与第二个样本点重合的位置上……以此类推。利用这个方法,我们最终能得到 m 个标记点 l(1) l(2) …… l(m),即每一个标记点的位置都与每一个样本点的位置精确对应。接着我们就可以运用之前讲到的高斯核函数,利用x(i)与l(j)之间的相似度来计算出 fi(j)进而判断出 x(i) 这个训练样本的分类。

接下来,类似于我们之前的过程,我们可以对以上过程进行向量化。我将这 m 个特征合并为一个特征向量,于是相比之前用x(i)来描述一个样本,我们用为 n 维或者 n+1 维空间的向量样本向量 x 来描述该样本,这取决于我们是否假如恒为 1 的x0(1)。接着我们可以用我们的样本向量 x 得到特征向量 f 来描述我们的特征向量。同样地特征向量 f 是合并 f(i) 将所有这些项合并为一个向量所得到的向量。接着我们假设运用梯度下降或者其他算法求解到了θ,那对于新来的样本 x,对于它对应的特征向量 f,只要 θ^T * f ≥ 0时,我们就预测 y = 1,反之预测 y = 0。以上就是当已知参数θ时,我们怎么做出预测的过程。

那怎样得到参数θ呢?当我们在使用 SVM 学习算法时,具体来说就是要求解下面这个式子的最小化问题:

KN12.png

我们需要求出能使这个式子取最小值的参数 θ,我们可以看到可以有两个地方做出替换,首先在这里,我们有 n = m个特征,所以我们可以把所有的 n 都替换为 m 。接着对于正则化处理,我们仍然不对 θ0 做正则化处理,并且在支持向量机的具体实现的过程中,这最后一项正则化的式子与这里写的有细微差别。具体来说,最后的那一项可以被重写为θ^T * θ:

KN13.png

这是理所当然的,但是更进一步,这是理所当然的,但是更进一步,θ^T * M * θ来进行替换,而这其实是另一种略有区别的距离度量方法,我们用一种略有变化的度量来取代,而不直接用 θ 的模的平方进行最小化。这种变化所加入的矩阵 M 具体来说和核函数相关:

KN14.png

这个数学细节使得支持向量机能够更有效率的运行,这么做可以适应超大的训练集。例如当我们的训练集有10000个样本时,根据我们之前定义标记点的方法,我们最终有10000个标记点,θ也随之是10000维的向量,或许这时这么做还可行。但是当 m 变得非常非常大时,那么求解这么多参数的成本就会非常高,这些数学细节在软件包的数值优化下可以在更少的迭代下得到我们代价函数的最低点。

顺便说一下,你可能会想为什么我们不将核函数这个想法应用到其他算法比如逻辑回归上?事实证明如果愿意的话,确实可以将核函数这个想法用于定义特征向量,将标记点之类的技术用于逻辑回归算法,但是用于支持向量机的计算技巧不能较好的推广到其他算法诸如逻辑回归上,所以将核函数用于逻辑回归时会变得非常的慢。相比之下这些计算技巧比如具体化技术对这些细节的修改以及支持向量软件的实现细节使得支持向量机可以和核函数相得益彰,而逻辑回归和核函数则运行得十分缓慢。更何况它们还不能使用那些高级优化技巧,因为这些技巧是人们专门为使用核函数的支持向量机开发的。

而且我们并不需要知道怎么去写一个软件来最小化代价函数,因为我们能找到很好的成熟软件来做这些,就像我一直不建议自己写矩阵求逆函数或者平方根函数的道理一样,我也不建议亲自写最小化代价函数的代码,而应该使用人们开发的成熟的软件包,这些软件包已经包含了那些数值优化技巧,可以让你的训练时间大幅缩短。

另外一个值得说明的问题是在我们使用支持向量机时怎么选择支持向量机中的参数?在使用支持向量机时的偏差-方差折时,其中一个要选择的事情是目标函数中的参数 C。回忆一下 C 的作用与 1/λ 相似,λ 是逻辑回归算法中的正则化参数,所以大的 C 对应着我们以前在逻辑回归问题中的小的 λ,这意味着几乎不使用正则化,所以如果我们这么做就有可能得到一个低偏差但高方差的模型;反之如果我们使用了较小的 C,这对应着在逻辑回归问题中使用较大的 λ,对应着一个高偏差但是低方差的模型。所以使用较大 C 值的模型为高方差,更倾向于过拟合;而使用较小C值的模型为高偏差更倾向于欠拟合。

C只是我们要选择的其中一个参数,另外一个要选择的参数是高斯核函数中的 σ^2,当高斯核函数中的 σ^2 偏大时 那么对应的相似度函数exp(-||x-l(i)||^2/(2*σ^2))就会倾向于变得相对平滑:

KN15.png

这条曲线就是我的特征 fi,而由于函数平滑且变化的比较平缓,这会给你的模型带来较高的偏差和较低的方差。且由于高斯核函数变得平缓,就更倾向于得到一个随着输入 x 变化得缓慢的模型。

反之如果σ^2很小,那么高斯核函数即相似度函数会变化的很剧烈:

KN16.png

在这种情况下最终得到的模型会是低偏差和高方差。这就是利用核函数的支持向量机算法,希望这些关于偏差和方差的讨论能给你一些对于算法结果预期的直观印象。

结语

通过这篇BLOG,相信你已经对核函数有了一定的了解。在接下来的BLOG中,我们将会具体学习如何使用支持向量机来进行机器学习。最后希望你喜欢这篇BLOG!

Last modification:March 4th, 2021 at 03:48 am
If you think my article is useful to you, please feel free to appreciate