支持向量机: Kernel
by pluskid, on 2010-09-11, in
Machine Learning
68 comments
本文是“支持向量机系列”的第三篇,參见本系列的其它文章。
前面我们介绍了线性情况下的支持向量机,它通过寻找一个线性的超平面来达到对数据进行分类的目的。只是,由于是线性方法,所以对非线性的数据就没有办法处理了。
比如图中的两类数据,分别分布为两个圆圈的形状,不论是不论什么高级的分类器。仅仅要它是线性的,就没法处理。SVM 也不行。
由于这种数据本身就是线性不可分的。
对于这个数据集。我能够悄悄透露一下:我生成它的时候就是用两个半径不同的圆圈加上了少量的噪音得到的。所以,一个理想的分界应该是一个“圆圈”而不是一条线(超平面)。假设用
和
来表示这个二维平面的两个坐标的话。我们知道一条二次曲线(圆圈是二次曲线的一种特殊情况)的方程能够写作这种形式:
注意上面的形式,假设我们构造另外一个五维的空间,当中五个坐标的值分别为 ,
,
,
,
,那么显然,上面的方程在新的坐标系下能够写作:
关于新的坐标
。这正是一个 hyper plane 的方程!也就是说。假设我们做一个映射
,将
依照上面的规则映射为
,那么在新的空间中原来的数据将变成线性可分的。从而使用之前我们推导的线性分类算法就能够进行处理了。
这正是 Kernel 方法处理非线性问题的基本思想。
再进一步描写叙述 Kernel 的细节之前,最好还是再来看看这个样例映射过后的直观样例。当然。我没有办法把 5 维空间画出来,只是因为我这里生成数据的时候就是用了特殊的情形,详细来说,我这里的超平面实际的方程是这个样子(圆心在
轴上的一个正圆):
因此我仅仅须要把它映射到 ,
,
这样一个三维空间中就可以,下图(这是一个 gif 动画)即是映射之后的结果。将坐标轴经过适当的旋转,就能够非常明显地看出,数据是能够通过一个平面来分开的:
如今让我们再回到 SVM 的情形,如果原始的数据时非线性的,我们通过一个映射
将其映射到一个高维空间中,数据变得线性可分了,这个时候,我们就能够使用原来的推导来进行计算。仅仅是全部的推导如今是在新的空间,而不是原始空间中进行。当然,推导过程也并非能够简单地直接类比的,比如,原本我们要求超平面的法向量
,可是假设映射之后得到的新空间的维度是无穷维的(确实会出现这种情况。比方后面会提到的 Gaussian Kernel )。要表示一个无穷维的向量描写叙述起来就比較麻烦。于是我们最好还是先忽略过这些细节,直接从终于的结论来分析,回顾一下,我们上一次得到的终于的分类函数是这种:
如今则是在映射过后的空间,即:
而当中的
也是通过求解例如以下 dual 问题而得到的:
这样一来问题就攻克了吗?似乎是的:拿到非线性数据,就找一个映射
,然后一股脑把原来的数据映射到新空间中,再做线性 SVM 就可以。只是若真是这么简单,我这篇文章的标题也就白写了——说了这么多,事实上还没到正题呐!事实上刚才的方法稍想一下就会发现有问题:在最初的样例里。我们对一个二维空间做映射。选择的新空间是原始空间的全部一阶和二阶的组合。得到了五个维度。假设原始空间是三维,那么我们会得到 19 维的新空间(验算一下?)。这个数目是呈爆炸性增长的,这给
的计算带来了很大的困难。并且假设遇到无穷维的情况,就根本无从计算了。
所以就须要 Kernel 出马了。
最好还是还是从最開始的简单样例出发。设两个向量
和
,而
即是到前面说的五维空间的映射,因此映射过后的内积为:
另外,我们又注意到:
二者有非常多相似的地方,实际上。我们仅仅要把某几个维度线性缩放一下。然后再加上一个常数维度。详细来说。上面这个式子的计算结果实际上和映射
之后的内积
的结果是相等的(自己验算一下)。
差别在于什么地方呢?一个是映射到高维空间中,然后再依据内积的公式进行计算;而还有一个则直接在原来的低维空间中进行计算。而不须要显式地写出映射后的结果。回顾刚才提到的映射的维度爆炸,在前一种方法已经无法计算的情况下,后一种方法却依然能从容处理。甚至是无穷维度的情况也没有问题。
我们把这里的计算两个向量在映射过后的空间中的内积的函数叫做核函数 (Kernel Function) ,比如。在刚才的样例中。我们的核函数为:
核函数能简化映射空间中的内积运算——刚好“碰巧”的是。在我们的 SVM 里须要计算的地方数据向量总是以内积的形式出现的。对照刚才我们写出来的式子,如今我们的分类函数为:
当中
由例如以下 dual 问题计算而得:
这样一来计算的问题就算攻克了,避开了直接在高维空间中进行计算,而结果却是等价的。实在是一件很美妙的事情。当然。由于我们这里的样例很easy,所以我能够手工构造出相应于
的核函数出来,假设对于随意一个映射,想要构造出相应的核函数就非常困难了。
最理想的情况下。我们希望知道数据的详细形状和分布,从而得到一个刚好能够将数据映射成线性可分的
,然后通过这个
得出相应的
进行内积计算。
然而,第二步一般是很困难甚至全然没法做的。
只是,因为第一步也是差点儿无法做到,因为对于随意的数据分析其形状找到合适的映射本身就不是什么easy的事情,所以。人们通常都是“胡乱”选择映射的,所以。根本没有必要精确地找出相应于映射的那个核函数,而仅仅须要“胡乱”选择一个核函数就可以——我们知道它相应了某个映射,尽管我们不知道这个映射详细是什么。因为我们的计算仅仅须要核函数就可以,所以我们也并不关心也没有必要求出所相应的映射的详细形式。
当然。说是“胡乱”选择,事实上是夸张的说法,由于并非随意的二元函数都能够作为核函数,所以除非某些特殊的应用中可能会构造一些特殊的核(比如用于文本分析的文本核,注意事实上使用了 Kernel 进行计算之后,事实上全然能够去掉原始空间是一个向量空间的如果了,仅仅要核函数支持,原始数据能够是随意的“对象”——比方文本字符串),通常人们会从一些经常使用的核函数中选择(依据问题和数据的不同,选择不同的參数,实际上就是得到了不同的核函数),比如:
- 多项式核
,显然刚才我们举的样例是这里多项式核的一个特例()。尽管比較麻烦,并且没有必要,只是这个核所相应的映射实际上是能够写出来的。该空间的维度是
。当中
是原始空间的维度。 - 高斯核
,这个核就是最開始提到过的会将原始空间映射为无穷维空间的那个家伙。只是,假设
选得非常大的话,高次特征上的权重实际上衰减得非常快。所以实际上(数值上近似一下)相当于一个低维的子空间;反过来。假设
选得非常小,则能够将随意的数据映射为线性可分——当然,这并不一定是好事,由于随之而来的可能是非常严重的过拟合问题。只是,总的来说,通过调控參数
,高斯核实际上具有相当高的灵活性。也是使用最广泛的核函数之中的一个。 - 线性核
,这实际上就是原始空间中的内积。这个核存在的主要目的是使得“映射后空间中的问题”和“映射前空间中的问题”两者在形式上统一起来了。
最后,总结一下:对于非线性的情况。SVM 的处理方法是选择一个核函数
。通过将数据映射到高维空间。来解决在原始空间中线性不可分的问题。因为核函数的优良品质,这种非线性扩展在计算量上并没有比原来复杂多少,这一点是很难得的。当然,这要归功于核方法——除了 SVM 之外,不论什么将计算表示为数据点的内积的方法。都能够使用核方法进行非线性扩展。
此外。稍微提一下。也有不少工作试图自己主动构造专门针对特定数据的分布结构的核函数,感兴趣的同学能够參考。比方 NIPS 2003 的 Cluster Kernels for Semi-Supervised Learning 和 ICML 2005 的 Beyond the point cloud: from transductive to semi-supervised learning 等。