本文章主要参考《机器学习实战》之前一直使用sklearn库来调用算法,却不知道算法的低层含义是什么,如何构造出来的。让我很是苦恼。于是决定学习这本书来增强自己对算法的理解能力。
本节主要介绍支持词向量机的算法的推导过程,试图用自己理解的话语最简单的解答支持向量机的主要思想,之后会通过python代码加以实现。
优点:泛化错误率低,计算开销小,结果易解释
缺点:对参数调节和核函数的选择敏感,原始分类器不加修改仅适用于处理二分类问题
适用数据类型:数值型,标称型数据
我们知道机器学习中监督学习主要任务就是分类,而分类的目的是学会一个分类函数或分类模型(或者叫做分类器),该模型能把数据库中的数据项映射到给定类别中的某一个,从而可以用于预测未知类别。对于SVM来说,它作为一个而分类的分类模型,也就是给定一个包含正例和反例(正样本点和负样本点)的样本集合,支持向量机的目的是寻找一个超平面来对样本进行分割,把样本中的正例和反例用超平面分开,但是不是简单地分开,其原则是使正例和反例之间的间隔最大。学习的目标是在特征空间中找到一个分类超平面wx+b=0,分类面由法向量w和截距b决定。分类超平面将特征空间划分两部分,一部分是正类,一部分是负类。法向量指向的一侧是正类,另一侧为负类。
如下图两分类的例子所示,我们的分类目标是在Class1与Class2两类样本之间找到一条线,将他们分隔开,如果有新的样本来了,落在线的左边则分到class1类,落到右边则分到class2类。但是又如右图所示,我们可以得出很多条线。那么问题来了,究竟那一条线才能最有效的将两类样本分隔开呢?此外,下图为二维空间,在二维空间中分类就是线,如果是三维那就叫做面了,在高维中也有个NB的名字,叫做超平面。一般将任何维的分类边界都统称为超平面。
对于二维来说人眼可以轻易的找到这条线(超平面)但是但维度大于3的时候,我们则无法将这些样本画出来了。此时我们则需要利用计算机来找到这条线。这时候我们也得开始建模了,但计算机将这个模型解出来的时候,这个解就是我们需要的那条线。这样就能达到分类目的了。
以上的思想就是SVM的基本思想,可以解释为:SVM试图寻找一个超平面来对样本进行分割,把样本中的正例和反例用超平面分开,但是不是很敷衍地简单的分开,而是尽最大的努力使正例和反例之间的间隔margin最大。这样它的分类结果才更加可信,而且对于未知的新样本才有很好的分类预测能力(机器学习美其名曰泛化能力)。
我们先用数学公式来描述下。假设我们有N个训练样本{(x1, y1),(x2, y2), …, (xN, yN)},x是d维向量,而yi∊{+1, -1}是样本的标签,分别代表两个不同的类。这里我们需要用这些样本去训练学习一个线性分类器(超平面):f(x)=sgn(wTx + b),也就是wTx + b大于0的时候,输出+1,小于0的时候,输出-1。sgn()表示取符号。而g(x) =wTx + b=0就是我们要寻找的分类超平面,如上图所示。刚才说我们要怎么做了?我们需要这个超平面最大的分隔这两类。也就是这个分类面到这两个类的最近的那个样本的距离相同,而且最大。为了更好的说明,我们在上图中找到两个和这个超平面平行和距离相等的超平面:H1: y = wTx + b=+1 和 H2: y = wTx + b=-1。
这时候出现了两个需要满足的条件:(1)没有任何样本点分布在两个平面之间(没有数据点在H1与H2之间)。(2)两平面距离最大化。
首先解决条件(2):
若需要两平面距离最大化,那么就会存在一些样本处于这两条线上,这就叫支持向量。而两条线呈平行线,例如ax+by=c1和ax+by=c2,那他们的距离是|c2-c1|/sqrt(x2+y2)(sqrt()表示开根号)。注:x,y都是二维坐标。换成用w来表示:
H1:w1x1+w2x2=+1
H2:w1x1+w2x2=-1
所以:H1与H2的距离为:
|1+1|/ sqrt(w12+w12)=2/||w|| (也就是w的模的倒数的两倍)
margin=2/||w|| (为了最大化这个距离,我们应该最小化||w||)
之后解决条件(1):
对于任何一个正样本yi=+1,它都要处于H1的右边,也就是要保证:y= wTx + b>=+1。对于任何一个负样本yi=-1,它都要处于H2的左边,也就是要保证:y = wTx + b<=-1。这两个约束,其实可以合并成同一个式子:yi (wTxi + b)>=1。
问题则变成凸二次规划问题:
既然为凸二次规划问题则可以采用拉格朗日对偶性解决。通过求解对偶问题得到最优解,这就是线性可分条件下支持向量机的对偶算法,这样做的优点在于:一是对偶问题往往更容易求解;二者可以自然的引入核函数,进而推广到非线性分类问题。
新问题出现:求解对偶问题???
primal problem(原始问题):
引入拉格朗日乘子,我们得到拉格朗日函数:
对L(w, b, α)分别求w和b的极值。也就是L(w, b,α)对w和b的梯度为0:∂L/∂w=0和∂L/∂b=0,还需要满足α>=0。求解这里导数为0的式子可以得到:
代入拉格朗日函数后得出dual problem:
即知道了α就知道w,发过来知道w也能得出α。
此时的问题则转化为对α求极大值(关于对偶变量α的优化问题,没有了变量w,b,只有α)当求解得到最优的α*后,就可以同样代入到上面的公式,导出w*和b*了,最终得出分离超平面和分类决策函数。也就是训练好了SVM。
此时新样本喂进来的分类决策函数就可以进行分类:
以上情况是建立在优雅的线性分割的假设上,但现实中的数据很可能出现离群点(outlier),有可能将超平面挤歪,同时margin变小,甚至无法构造超平面。如下图所示:
此时我们可允许数据点在一定程度上偏离超平面,允许一些点到H1与H2之间。也就是 分类面间隔会小于-1。
此时原来的约束条件改为:
在目标函数中增加一个惩罚项,得到新模型(软间隔)
引入非负参数ξi后(称为松弛变量)就允许某些样本点的函数间隔小于1
放松限制条件后,需要调整目标函数,以对离群点进行处罚。
目标函数后加上的第二项表明离群点越多,目标函数越大,而我们要求目标函数值尽可能小。
C是离群点的权重,C越大表明目标函数影响越大,我们越不希望看到离群点。
此时目标函数已控制离群点数目和程度。
经过同样的推导后,转变为对偶问题得出:
此时,我们发现没有了参数ξi,与之前模型唯一不同在于αi又多了αi<=C的限制条件。同时b的求值公司发生了改变,引入核函数概念。
以上的方法都建立在样本线性可分或者只有少量离群点存在于H1与H2之间的情况,但如果样本的分布本来就是线性不可分的时候,在采用松弛变量ξi构造分类边界的效果会很差,此时采用核函数(kernel trick)。
如果我们把原始样本点变换到一个线性可分的空间,那么SVM又可以继续工作了如下图所示:
但是引发两个问题:
(1)首先使用一个非线性映射Φ(x)将全部原始数据x变换到另一个特征空间,在这个空间中,样本变得线性可分;
(2)然后在特征空间中使用SVM进行学习分类。
需要解决问题(1)则想到cover定理:将复杂的模型分类问题非线性地投到高维空间比投射到低维空间更可能线性可分;但是找到这样的映射函数很难,因此支持向量机采用核函数,不仅能映射到高维空间,又能不增加太多的计算量。
之前的SVM忧患问题:
从中发现对样本x利用,自己算第i和第j两个样本的内积即可,决策函数为:
训练SVM与使用SVM时都是用样本间的内积且只用到内积。
因此我们采用核函数计算两个样本映射到高维空间的内积值即可:
K(xi, xj)=Φ(xi)T Φ(xj)
即两个样本xi和xj对应的高维空间的内积Φ(xi)T Φ(xj)通过一个核函数K(xi, xj)计算得到。
计算K(xi, xj)一般使用径向基RBF函数:
此时,优化的对偶问题则变成:
样本内积使用核函数代替,优化过程与之前无差别但决策函数变为:
也就是新来的样本x和训练样本计算函数即可,但注意大部分样本的拉格朗日因子αi都为0,所以我们只需要计算少量训练样本与新来样本的核函数,然后求和取符号即可完成对新来样本x的分类。
支持向量机(SVM)基本事项可概括为首先通过非线性变换将输入空间变换到一个高维的空间;然后在这个新的空间求最优分类面即最大间隔分类面,而这种非线性变换是通过定义适当的内积核函数来实现的;SVM实际上是根据统计学习理论结构风险最小化原则提出,要求实现两个目的:
(1)两类问题能够分开(经验风险最小);
(2)margin最大化(风险上界最小)即在保证风险最小的子集中选择经验风险最小的函数。