前言
一、什么是SVM?
SVM(Support Vector Machine)即支持向量机,主要是用于分类任务(或者说二分类任务)中使用。对于分类任务,最基本的思路就是:基于训练集,在样本空间中,找到一个划分超平面(Hyper Plane),将不同类别的样本划分开来。但是,可以将训练样本分开的超平面可能有很多,我们是根据什么来选择到底哪一个是所需要的呢?1.1 线性分类
1.1.1 分类取值1或-1的标准:逻辑回归
扫描二维码关注公众号,回复: 69494 查看本文章
1.1.3 线性分类的简单例子
下面举个简单的例子(硬间隔),一个二维平面(一个超平面,在二维空间中的例子就是一条直线),如下图所示,平面上有两种不同的点,分别用两种不同的颜色表示,一种为红颜色的点,另一种则为蓝颜色的点,红颜色的线表示一个可行的超平面。
从上图中我们可以看出,这条红颜色的线把红颜色的点和蓝颜色的点分开来了。而这条红颜色的线就是我们上面所说的超平面,也就是说,这个所谓的超平面的的确确便把这两种不同颜色的数据点分隔开来,在超平面一边的数据点所对应的 全是 -1 ,而在另一边全是 1 。
接着,我们可以令分类函数(提醒:下文很大篇幅都在讨论着这个分类函数,或者说模型):
显然,如果f(x) = 0 ,那么x 是位于超平面上的点。
如图所示,距离超平面最近的几个训练样本点使得为1,这些样本点称为支持向量(Support Vector),两个异类向量到超平面的距离之和为:。找到有最大间隔的划分超平面,也就是使最大化,要求满足条件(s.t.的意思是:subject to)这也就是使得最小化。这就是支持向量机的基本型。
当然,有些时候,或者说大部分时候数据并不是线性可分的,这个时候满足这样条件的超平面就根本不存在(不过关于如何处理这样的问题我们后面会讲),这里先从最简单的情形开始推导,就假设数据都是线性可分的,亦即这样的超平面是存在的。
请注意,下面的篇幅将按下述3点走:
- 咱们就要确定上述分类函数f(x) = w.x + b(w.x表示w与x的内积)中的两个参数w和b,通俗理解的话w是法向量,b是截距;
- 那如何确定w和b呢?答案是寻找两条边界端或极端划分直线中间的最大间隔(之所以要寻最大间隔是为了能更好的划分不同类的点,下文你将看到:为寻最大间隔,导出,继而引入拉格朗日函数和对偶变量,化为对单一因数对偶变量的求解,当然,这是后话),从而确定最终的最大间隔分类超平面hyper plane和分类函数;
- 进而把寻求分类函数f(x) = w.x + b的问题转化为对w,b的最优化问题,最终化为对偶因子的求解。
二、深入了解SVM
2.1 线性可分到线性不可分
2.1.1 从原始问题到对偶问题的求解
虽然上文1.3节给出了目标函数,却没有讲怎么来求解。现在就让我们来处理这个问题。回忆一下之前得到的目标函数(subject to导出的则是约束条件):
- 转化到这个形式后,我们的问题成为了一个凸优化问题,或者更具体的说,因为现在的目标函数是二次的,约束条件是线性的,所以它是一个凸二次规划问题。这个问题可以用任何现成的 QP (Quadratic Programming) 的优化包进行求解,归结为一句话即是:在一定的约束条件下,目标最优,损失最小;
- 但虽然这个问题确实是一个标准的 QP 问题,但是它也有它的特殊结构,通过 Lagrange Duality 变换到对偶变量 (dual variable) 的优化问题之后,可以找到一种更加有效的方法来进行求解,而且通常情况下这种方法比直接使用通用的 QP 优化包进行优化要高效得多。
也就说,除了用解决QP问题的常规方法之外,还可以通过求解对偶问题得到最优解,这就是线性可分条件下支持向量机的对偶算法,这样做的优点在于:一者对偶问题往往更容易求解;二者可以自然的引入核函数,进而推广到非线性分类问题。
至于上述提到,关于什么是Lagrange duality?简单地来说,通过给每一个约束条件加上一个 Lagrange multiplier(拉格朗日乘子),即引入拉格朗日乘子,如此我们便可以通过拉格朗日函数将约束条件融和到目标函数里去(也就是说把条件融合到一个函数里头,现在只用一个函数表达式便能清楚的表达出我们的问题,n为样本个数):
然后我们令
容易验证,当某个约束条件不满足时,例如,那么我们显然有(只要令即可)。而当所有约束条件都满足时,则有,亦即我们最初要最小化的量。因此,在要求约束条件得到满足的情况下最小化,实际上等价于直接最小化。(当然,这里也有约束条件,就是)
因为如果约束条件没有得到满足,会等于无穷大,自然不会是我们所要求的最小值。具体写出来,我们现在的目标函数变成了:
这里用表示这个问题的最优值,这个问题和我们最初的问题是等价的。不过,现在我们来把最小和最大的位置交换一下(稍后,你将看到,当下面式子满足了一定的条件之后,这个式子d 便是上式P 的对偶形式表示):
当然,交换以后的问题不再等价于原问题,这个新问题的最优值用来表示。并且,我们有≤ ,这在直观上也不难理解,最大值中最小的一个总也比最小值中最大的一个要大吧! 总之,第二个问题的最优值在这里提供了一个第一个问题的最优值的一个下界,在满足某些条件的情况下,这两者相等,这个时候我们就可以通过求解第二个问题来间接地求解第一个问题。
也就是说,下面我们将先求L 对w、b的极小,再求L 对的极大。而且,之所以从minmax的原始问题,转化为maxmin的对偶问题,一者因为是的近似解,二者,转化为对偶问题后,更容易求解。
2.1.2 KKT条件
与此同时,上段说“在满足某些条件的情况下”,这所谓的“满足某些条件”就是要满足KKT条件。那KKT条件的表现形式是什么呢?据维基百科:KKT 条件的介绍,一般地,一个最优化数学模型能够表示成下列标准形式:
其中,f(x)是需要最小化的函数,h(x)是等式约束,g(x)是不等式约束,p和q分别为等式约束和不等式约束的数量。同时,我们得明白以下两个定理:
- 凸优化的概念: 为一凸集, 为一凸函数。凸优化就是要找出一点 ,使得每一 满足 。
- KKT条件的意义:它是一个非线性规划(Nonlinear Programming)问题能有最优化解法的必要和充分条件。
那到底什么是所谓Karush-Kuhn-Tucker条件呢?KKT条件就是指上面最优化数学模型的标准形式中的最小点 x* 必须满足下面的条件:
经过论证,我们这里的问题是满足 KKT 条件的(首先已经满足Slater condition,再者f和gi也都是可微的,即L对w和b都可导),因此现在我们便转化为求解第二个问题。也就是说,现在,咱们的原问题通过满足一定的条件,已经转化成了对偶问题。而求解这个对偶学习问题,分为3个步骤,首先要让L(w,b,a) 关于 和 最小化,然后求对α的极大,最后利用SMO算法求解对偶因子。
2.1.3 求解对偶问题的步骤
(1)首先固定,要让 关于 和 最小化,我们分别对w,b求偏导数,即令 和 等于零。
以上结果代回上述的
得到:
提醒:有读者可能会问上述推导过程如何而来?说实话,其具体推导过程是比较复杂的,如下图所示:
最后,得到:
(2)求的极大值,这块交由SMO算法处理,具体可以参考相关论文资料。
不得不提醒下读者:经过上面第一个步骤的求w和b,得到的拉格朗日函数式子已经没有了变量w,b,只有,而反过来,求得的将能导出w,b的解,最终得出分离超平面和分类决策函数。为何呢?因为如果求出了,根据,即可求出w。然后通过,即可求出b 。
如前面所说,这个问题有更加高效的优化算法,即我们常说的SMO(Sequential Minimal Optization)算法。
2.2 核函数(线性不可分)
2.2.1、特征空间的隐式映射:核函数
咱们首先给出核函数的来头:
- 在上文中,我们已经了解到了SVM处理线性可分的情况,而对于非线性的情况,SVM 的处理方法是选择一个核函数 ,通过将数据映射到高维空间,来解决在原始空间中线性不可分的问题。由于核函数的优良品质,这样的非线性扩展在计算量上并没有比原来复杂多少,这一点是非常难得的。当然,这要归功于核方法——除了 SVM 之外,任何将计算表示为数据点的内积的方法,都可以使用核方法进行非线性扩展。
也就是说,Minsky和Papert早就在20世纪60年代就已经明确指出线性学习器计算能力有限。为什么呢?因为总体上来讲,现实世界复杂的应用需要有比线性函数更富有表达能力的假设空间,也就是说,目标概念通常不能由给定属性的简单线性函数组合产生,而是应该一般地寻找待研究数据的更为一般化的抽象特征。
而下文我们将具体介绍的核函数则提供了此种问题的解决途径,从下文你将看到,核函数通过把数据映射到高维空间来增加第一节所述的线性学习器的能力,使得线性学习器对偶空间的表达方式让分类操作更具灵活性和可操作性。因为训练样例一般是不会独立出现的,它们总是以成对样例的内积形式出现,而用对偶形式表示学习器的优势在为在该表示中可调参数的个数不依赖输入属性的个数,通过使用恰当的核函数来替代内积,可以隐式得将非线性的训练数据映射到高维空间,而不增加可调参数的个数(当然,前提是核函数能够计算对应着两个输入特征向量的内积)。
- 首先使用一个非线性映射将数据变换到一个特征空间F,
- 然后在特征空间使用线性学习器分类。
在2.1节中我们介绍了线性情况下的支持向量机,它通过寻找一个线性的超平面来达到对数据进行分类的目的。不过,由于是线性方法,所以对非线性的数据就没有办法处理。举个例子来说,则是如下图所示的两类数据,分别分布为两个圆圈的形状,这样的数据本身就是线性不可分的,此时咱们该如何把这两类数据分开呢(下文将会有一个相应的三维空间图)?
事实上,上图所述的这个数据集,是用两个半径不同的圆圈加上了少量的噪音生成得到的,所以,一个理想的分界应该是一个“圆圈”而不是一条线(超平面)。如果用 和 来表示这个二维平面的两个坐标的话,我们知道一条二次曲线(圆圈是二次曲线的一种特殊情况)的方程可以写作这样的形式:
注意上面的形式,如果我们构造另外一个五维的空间,其中五个坐标的值分别为 , , , , ,那么显然,上面的方程在新的坐标系下可以写作:
关于新的坐标 ,这正是一个 hyper plane 的方程!也就是说,如果我们做一个映射 ,将 按照上面的规则映射为 ,那么在新的空间中原来的数据将变成线性可分的,从而使用之前我们推导的线性分类算法就可以进行处理了。这正是 Kernel 方法处理非线性问题的基本思想。
再进一步描述 Kernel 的细节之前,不妨再来看看这个例子映射过后的直观例子。当然,你我可能无法把 5 维空间画出来,不过由于我这里生成数据的时候就是用了特殊的情形,具体来说,我这里的超平面实际的方程是这个样子(圆心在 轴上的一个正圆):
因此我只需要把它映射到 , , 这样一个三维空间中即可,下图即是映射之后的结果,将坐标轴经过适当的旋转,就可以很明显地看出,数据是可以通过一个平面来分开的(pluskid:下面的gif 动画,先用 Matlab 画出一张张图片,再用 Imagemagick 拼贴成):
现在让我们再回到 SVM 的情形,假设原始的数据时非线性的,我们通过一个映射 将其映射到一个高维空间中,数据变得线性可分了,这个时候,我们就可以使用原来的推导来进行计算,只是所有的推导现在是在新的空间,而不是原始空间中进行。当然,推导过程也并不是可以简单地直接类比的,例如,原本我们要求超平面的法向量 ,但是如果映射之后得到的新空间的维度是无穷维的(确实会出现这样的情况,比如后面会提到的 高斯核Gaussian Kernel ),要表示一个无穷维的向量描述起来就比较麻烦。于是我们不妨先忽略过这些细节,直接从最终的结论来分析,回忆一下,我们上一次2.1节中得到的最终的分类函数是这样的:
现在则是在映射过后的空间,即:
而其中的 也是通过求解如下 dual 问题而得到的:
这样一来问题就解决了吗?似乎是的:拿到非线性数据,就找一个映射 ,然后一股脑把原来的数据映射到新空间中,再做线性 SVM 即可。不过事实上没有这么简单!其实刚才的方法稍想一下就会发现有问题:在最初的例子里,我们对一个二维空间做映射,选择的新空间是原始空间的所有一阶和二阶的组合,得到了五个维度;如果原始空间是三维,那么我们会得到 19 维的新空间,这个数目是呈爆炸性增长的,这给 的计算带来了非常大的困难,而且如果遇到无穷维的情况,就根本无从计算了。所以就需要 Kernel 出马了。
不妨还是从最开始的简单例子出发,设两个向量和,而即是到前面2.2.1节说的五维空间的映射,因此映射过后的内积为:
(公式说明:上面的这两个推导过程中,所说的前面的五维空间的映射,这里说的前面便是文中2.2.1节的所述的映射方式,仔细看下2.2.1节的映射规则,再看那第一个推导,其实就是计算x1,x2各自的内积,然后相乘相加即可,第二个推导则是直接平方,去掉括号,也很容易推出来)
另外,我们又注意到:
二者有很多相似的地方,实际上,我们只要把某几个维度线性缩放一下,然后再加上一个常数维度,具体来说,上面这个式子的计算结果实际上和映射
之后的内积的结果是相等的,那么区别在于什么地方呢?
- 一个是映射到高维空间中,然后再根据内积的公式进行计算;
- 而另一个则直接在原来的低维空间中进行计算,而不需要显式地写出映射后的结果。
(公式说明:上面之中,最后的两个式子,第一个算式,是带内积的完全平方式,可以拆开,然后,通过凑一个得到,第二个算式,也是根据第一个算式凑出来的)
回忆刚才提到的映射的维度爆炸,在前一种方法已经无法计算的情况下,后一种方法却依旧能从容处理,甚至是无穷维度的情况也没有问题。
我们把这里的计算两个向量在隐式映射过后的空间中的内积的函数叫做核函数 (Kernel Function) ,例如,在刚才的例子中,我们的核函数为:
核函数能简化映射空间中的内积运算——刚好“碰巧”的是,在我们的 SVM 里需要计算的地方数据向量总是以内积的形式出现的。对比刚才我们上面写出来的式子,现在我们的分类函数为:
其中 由如下 dual 问题计算而得:
这样一来计算的问题就算解决了,避开了直接在高维空间中进行计算,而结果却是等价的!当然,因为我们这里的例子非常简单,所以我可以手工构造出对应于的核函数出来,如果对于任意一个映射,想要构造出对应的核函数就很困难了。
通常人们会从一些常用的核函数中选择(根据问题和数据的不同,选择不同的参数,实际上就是得到了不同的核函数),例如:
- 多项式核,显然刚才我们举的例子是这里多项式核的一个特例(R = 1,d = 2)。虽然比较麻烦,而且没有必要,不过这个核所对应的映射实际上是可以写出来的,该空间的维度是,其中 是原始空间的维度。
- 高斯核,这个核就是最开始提到过的会将原始空间映射为无穷维空间的那个家伙。不过,如果选得很大的话,高次特征上的权重实际上衰减得非常快,所以实际上(数值上近似一下)相当于一个低维的子空间;反过来,如果选得很小,则可以将任意的数据映射为线性可分——当然,这并不一定是好事,因为随之而来的可能是非常严重的过拟合问题。不过,总的来说,通过调控参数,高斯核实际上具有相当高的灵活性,也是使用最广泛的核函数之一。下图所示的例子便是把低维线性不可分的数据通过高斯核函数映射到了高维空间:
- 线性核,这实际上就是原始空间中的内积。这个核存在的主要目的是使得“映射后空间中的问题”和“映射前空间中的问题”两者在形式上统一起来了(意思是说,咱们有的时候,写代码,或写公式的时候,只要写个模板或通用表达式,然后再代入不同的核,便可以了,于此,便在形式上统一了起来,不用再分别写一个线性的,和一个非线性的)。
2.2.4、核函数的本质
- 实际中,我们会经常遇到线性不可分的样例,此时,我们的常用做法是把样例特征映射到高维空间中去(如上文2.2节最开始的那幅图所示,映射到高维空间后,相关特征便被分开了,也就达到了分类的目的);
- 但进一步,如果凡是遇到线性不可分的样例,一律映射到高维空间,那么这个维度大小是会高到可怕的(如上文中19维乃至无穷维的例子)。那咋办呢?
- 此时,核函数就隆重登场了,核函数的价值在于它虽然也是讲特征进行从低维到高维的转换,但核函数绝就绝在它事先在低维上进行计算,而将实质上的分类效果表现在了高维上,也就如上文所说的避免了直接在高维空间中的复杂计算。
最后引用这里的一个例子举例说明下核函数解决非线性问题的直观效果。
假设现在你是一个农场主,圈养了一批羊群,但为预防狼群袭击羊群,你需要搭建一个篱笆来把羊群围起来。但是篱笆应该建在哪里呢?你很可能需要依据牛群和狼群的位置建立一个“分类器”,比较下图这几种不同的分类器,我们可以看到支持向量机完成了一个很完美的解决方案。
这个例子从侧面简单说明了支持向量机使用非线性分类器的优势,而逻辑模式以及决策树模式都是使用了直线方法。
2.2.5、当满足什么条件的时候,k(.,.)才是核函数呢?
ht关于核函数的选取和为什么他可以在低维计算等效成高维计算,请看这篇文章核函数
2.3、使用松弛变量处理 outliers 方法(软间隔问题)
在本文第一节最开始讨论支持向量机的时候,我们就假定,数据是线性可分的,亦即我们可以找到一个可行的超平面将数据完全分开。后来为了处理非线性数据,在上文2.2节使用 Kernel 方法对原来的线性 SVM 进行了推广,使得非线性的的情况也能处理。虽然通过映射 将原始数据映射到高维空间之后,能够线性分隔的概率大大增加,但是对于某些情况还是很难处理。
例如可能并不是因为数据本身是非线性结构的,而只是因为数据有噪音。对于这种偏离正常位置很远的数据点,我们称之为 outlier ,在我们原来的 SVM 模型里,outlier 的存在有可能造成很大的影响,因为超平面本身就是只有少数几个 support vector 组成的,如果这些 support vector 里又存在 outlier 的话,其影响就很大了。例如下图:
用黑圈圈起来的那个蓝点是一个 outlier ,它偏离了自己原本所应该在的那个半空间,如果直接忽略掉它的话,原来的分隔超平面还是挺好的,但是由于这个 outlier 的出现,导致分隔超平面不得不被挤歪了,变成途中黑色虚线所示(这只是一个示意图,并没有严格计算精确坐标),同时 margin 也相应变小了。当然,更严重的情况是,如果这个 outlier 再往右上移动一些距离的话,我们将无法构造出能将数据分开的超平面来。
为了处理这种情况,SVM 允许数据点在一定程度上偏离一下超平面(为了防止过拟合,SVM允许在一些样本上预测出错,以满足整体的的最大化Margin)。例如上图中,黑色实线所对应的距离,就是该 outlier 偏离的距离,如果把它移动回来,就刚好落在原来的超平面上,而不会使得超平面发生变形了。
插播下一位读者@Copper_PKU的理解:“换言之,在有松弛的情况下outline点也属于支持向量SV,同时,对于不同的支持向量,拉格朗日参数的值也不同,如此篇论文《Large Scale Machine Learning》中的下图所示:
对于远离分类平面的点值为0;对于边缘上的点值在[0, 1/L]之间,其中,L为训练数据集个数,即数据集大小;对于outline数据和内部的数据值为1/L。更多请参看本文文末参考条目第51条。”
我们的优化目标是:
其中:l0/1为损失函数。(下面损失函数的形式用采用hinge损失函数)。
还可以将优化目标写成更一般的形式:
其中,称为结构风险(Structural risk),用于描述模型f的某些性质;第二项称为经验风险(Empirical risk),用于描述模型和训练数据的契合程度;C将二者折中。换一个角度说,可以将上式理解成“正则化问题”,为正则化项,C为正则化常数。(在吴恩达的机器学习课程中,效果等同于,其中为逻辑回归中的正则化参数,或者说是为了防止过拟合的惩罚因子)
OK,继续回到咱们的问题。我们,原来的约束条件为:
现在考虑到outlier问题(即不是所有的样本点都满足这个条件,由噪声数据或者其他情况造就,采用hinge损失形式),约束条件变成了:
其中称为松弛变量 (slack variable),对应数据点允许偏离的 functional margin 的量。当然,如果我们使任意大的话,那任意的超平面都是符合条件的了。所以,我们在原来的目标函数(效果等效为Logistic regression中的Cost Function)后面加上一项,使得这些的总和也要最小:
其中 是一个参数,用于控制目标函数中两项(“寻找 margin 最大的超平面”和“保证数据点偏差量最小”)之间的权重。注意,其中 是需要优化的变量(之一),而 是一个事先确定好的常量。完整地写出来是这个样子:
分析方法和前面一样,转换为另一个问题之后,我们先让针对、和最小化:
将 带回 并化简,得到和原来一样的目标函数:
不过,由于我们得到而又有(作为 Lagrange multiplier 的条件),因此有,所以整个 dual 问题现在写作:
把前后的结果对比一下(错误修正:图中的Dual formulation中的Minimize应为maxmize):
可以看到唯一的区别就是现在 dual variable 多了一个上限 。而 Kernel 化的非线性形式也是一样的,只要把 换成 即可。这样一来,一个完整的,可以处理线性和非线性并能容忍噪音和 outliers 的支持向量机才终于介绍完毕了。
三、小结
不准确的说,SVM它本质上即是一个分类方法,用w^T+b定义分类函数,于是求w、b,为寻最大间隔,目标是求函数1/2||w||^2的最小值,继而引入拉格朗日因子,化为对拉格朗日乘子a的求解(求解过程中会涉及到一系列最优化或凸二次规划等问题)。如此,通过对偶转换,将求w.b与求等价,而的求解可以用一种快速学习算法SMO,至于核函数,是为处理非线性情况,若直接映射到高维计算恐维度爆炸,故在低维计算,等效高维表现。
本文主要参考了July大神的《支持向量机通俗导论(理解SVM的三层境界)》,周志华的《机器学习》还是吴恩达的机器学习课程,并在此基础上加上了一些自己的理解。文中的图主要是从July的文章中拿的,衷心感谢!