最近学习了一些机器学习方面的知识,想写一些相关的东西,首先想到的就是先把支持向量机(Support Vector Machine)写下来,倒不是它有多重要,当然确实也挺重要,最重要的原因是我认为它所代表的思想以及一些处理技巧非常的巧妙。所以第一篇相关的文章我想来尽量的写下来它的原理,另外再花一篇文章的篇幅来记录一下在scikit-learn这个机器学习的常用Python库中,SVM的主要使用方法。对于支持向量机网上有非常多的资源,有的文章介绍的非常详细,所以我这篇文章不准备深入到推导中,我觉得这也没必要,所以我主要的目标就是介绍SVM的思想,但是能力有限,如有错漏还请指正。
线性分类器
SVM的起源可以说还是线性分类器,也就是说对于样本集
D={(x1,y1),(x2,y2),…,(xm,ym)},yi∈{−1,+1}
我们怎样用一个超平面
wTx+b=0 将这两部分属于不同label(也就是y值是+1还是-1)的点区分开(假设是线性可分的)?
不用SVM的话我们可以使用Logistic回归(有的也叫对数几率回归),线性回归同样也是找到这样一个超平面,然后,对于超平面上的点来说
wTx+b=0 是满足的,但是对于真正的样例点,
wTx+b可以任意大,但是我们需要的是判断一个点是否为+1还是-1。此时我们用Sigmoid函数
y=11+e−z,下面为函数图象
![支持向量机(SVM)原理与实践(一) 支持向量机(SVM)原理与实践(一)](/default/index/img?u=aHR0cHM6Ly9waWFuc2hlbi5jb20vaW1hZ2VzLzQ4OC82NzA1MGY5MDFjOWQ5NmFhYmZjZjk3MThmZjVhZjQ2OC5wbmc=)
将
z=wTx+b映射到
[0,1]区间内,然后就可以规定比如
y<0.5 输出类为-1,相反为+1。具体的求解过程这里就不再叙述了,思想就是利用极大似然法写出
L(w)函数,这是一个关于w(
注意这里的w是向量,对于向量以及矩阵的求导和标量是不一样的,在碰到的时候可以去查相关公式)的高阶可导连续凸函数,然后利用凸优化的方法,比如梯度下降以及拟牛顿法求出最优的
w∗。
那么作为SVM,他的目标也是求出一个线性分类器,也就是一个超平面,那它和上面的Logistic回归有什么区别么?我认为主要是求解思路不一样,Logistic我们看到了,是利用最优化极大似然函数,求出w,它利用了所有的样本点(也是极大似然法的思想所在,就是让已发生的事情的概率极大化),而SVM我们将要看到,它的出发点是找出一个“间隔“最大的超平面,它实际上只利用了少数几个点,也就是所谓的”支持向量“,这也是支持向量机这个名称的来源,上面有些名词后面会解释,并且这只是最基本的支持向量机,在后面随着功能的不断改进,它的能力会越来越强大。
SVM推导
在这一小节我试着推导一下SVM。不过在那之前先引入几个概念,
函数间隔:对于给定的训练数据集T和超平面(w,b),定义超平面关于某个样本点的函数间隔为
γi^=yi(w⋅xi+b)
对于整个数据集的函数间隔为所有样本点中函数间隔的最小值
γ^=mini=1,⋯,Nγ^i
可以看出函数间隔只是可以用来预测分类的正确性,如果分类正确的话,即
yi为+1的话
w⋅xi+b也为正,
yi为-1的话,
w⋅xi+b也为负的,所以只要分类错误函数间隔
γi^就为负。并且这里要提一件比较关键的事,我刚开始在学习的时候没搞懂,就是超平面时用方程
wx+b=0来描述的,所以若是w和b同时乘以一个数,超平面方程是不会变的(方程右边为0),超平面也不会变。所以对于一个确定的超平面,
函数间隔的数值是没有意义的,有意义的只是它的符号,这也就引出了几何间隔。
几何间隔:一方面如果高中的解析几何还没忘的话,我们记得一个点到平面的距离公式
l=|w⋅x+b|∥w∥
,其实这就是我们所要的几何间隔,但是绝对值不太方便,
|w⋅x+b|在分类正确的情况下就等于
yi(w⋅xi+b)也就是几何间隔。那么我们就得到了几何间隔的公式,以及它和函数间隔的关系
γi=yi(w⋅xi+b)∥w∥=γ^i∥w∥
γ=γ^∥w∥(γ为最小几何间隔)
从另一个角度来说,我们利用w的范数
∥w∥对函数间隔进行规范化,消除w和b变化会对函数间隔带来的影响。
![支持向量机(SVM)原理与实践(一) 支持向量机(SVM)原理与实践(一)](/default/index/img?u=aHR0cHM6Ly9waWFuc2hlbi5jb20vaW1hZ2VzLzI1NC81MWIyNTdlNGI5MTJlMTdkMzY5OTRjZDM3Y2IxYzhiNi5wbmc=)
那么我们的问题就转化为了一个求出最大几何间隔的超平面的最优化问题。根据上面我们对几何间隔的描述,我们就是要求一个所有样本点到超平面的距离最大化的超平面。
maxw,bγ
s.t.yi(w⋅xi+b)∥w∥≥γ
将函数间隔改换成几何间隔
maxw,bγ^∥w∥
s.t.yi(w⋅xi+b)≥γ^
前面已经说过了函数间隔的绝对数值是没有什么意义的,所以这里我们不妨令
γ^为1,然后由于最大化
1∥w∥和最小化
12∥w∥2是等价的,那么我们就能够的到最后也是最常见的最优化形式:
maxw,b12∥w∥2
s.t.yi(w⋅xi+b)−1≥0,i=1,2,⋯,N
以上是我从李航的《统计学习方法》中看到的,也是我看到的最合理地推导方式,有的地方的推导总有些不太对的地方
![支持向量机(SVM)原理与实践(一) 支持向量机(SVM)原理与实践(一)](/default/index/img?u=aHR0cHM6Ly9waWFuc2hlbi5jb20vaW1hZ2VzLzU4LzgyNjNlNGM2MjM2NmE3MzIwMzFiMDk1MDY3M2QzODVhLnBuZw==)
这里先不考虑求解方法,我们来看上面的图,中间的黑色即为超平面,观看右边的部分,虚线的两条刚好经过几个样本点,而两条虚线之间没有样本点,这两个虚线之间的距离就是
间隔(margin),而最大化间隔就是支持向量机的主要目的。其实就是对于超平面,我们沿着超平面的法线方向“前后”移动,直到碰到一个样本点,这个可以“挪动”的空间就是
间隔。而这些限制了超平面“挪动”的样本点就是“支持向量”。
另外支持向量也是使约束条件等号成立的点即
yi(w⋅xi+b)−1=0
对于
yi=±1两类样本点,支持向量分别在
w⋅x+b=±1两个超平面,对于这两个超平面,即下面两个
X+以及
X−两个平面,其上面的点到中间的超平面的距离带入上面的点到直线的公式
yi(w⋅xi+b)∥w∥,即可得到这两个平面到中间超平面的距离分别为
1∥w∥,最后我们就可以得到
间隔也就是这两个两边的超平面之间的距离为
2∥w∥,然后就很容易的就能够转化为上面的最后的最优化问题。
综上我们就从最大化间隔的目的推出了最终的最优化问题。下面我们稍微讲一下这个最优化问题的解法。
SVM解法简述
SVM解法使用的时拉格朗日乘子法,然后将原始问题转化为对偶问题,这个对偶问题以后会讲到。之所以转化为对偶形式,一是因为可以减少参数,是问题更容易求解,第二个原因也非常重要,就是可以引入核函数,核函数的引入可以更好地解决非线性分类的问题。不过,我在学习的时候发现我基本忘记了拉格朗日乘子法,所以我下面稍微介绍一下
* 拉格朗日乘子法
1
对于等式约束比较好理解,等式约束的基本形式是:
minx∈Rnf(x)
s.t.hi(x)=0i=1,2,⋯,n
以前学习的时候就直接引入了拉格朗日函数,
L(x,a)=f(x)+∑i=1naihi(x)
之后联立
∇xL(x,a)=0和
∇aL(x,a)=0可以求出最优值,但是为什么是这样呢?下面这张图来自*
![支持向量机(SVM)原理与实践(一) 支持向量机(SVM)原理与实践(一)](/default/index/img?u=aHR0cHM6Ly9waWFuc2hlbi5jb20vaW1hZ2VzLzI5MC9mMWQ2MTEwZDZmZDJjZDdhMmI2YjlhM2JmOTEyMmNiMi5wbmc=)
椭圆的虚线代表
f(x)的值的等高线,红线代表等式约束,等高线的箭头代表值增加的方向,所以在图中
d1>d2>d3,同时也可以看出只有相切的地方的x所对应的
f值最大,假设这一点为
x∗,那么一定有
∇f(x∗)=λ∇g(x∗),因为在这一点二者的切线方向相同。这也是
∇xL(x,a)能够得到的结果。
2
对于含有不等式约束的情况,要麻烦一点,此时的主要形式为
minx∈Rnf(x)
s.t.ci(x)≤0,i=1,2,⋯,k
hj(x)=0,j=1,2,⋯,l
此时再引入一种拉格朗日函数
L(x,a,b)=f(x)+∑i=1kaici(x)+∑j=1lbjhj(x)
其中一个很重要的一点是
ai≥0,此时令
θP(x)=maxa,b;ai≥0[f(x)+∑i=1kaici(x)+∑j=1lbjhj(x)]
之后由于
hj(x)=0和
aici(x)≤0可得
θP(x)=f(x)因此原问题可化为求
θP(x)的最小值的问题亦即极小极大问题
minxθP(x)=minxmaxa,b;ai≥0L(x,a,b)
该问题的对偶问题为极大极小问题
maxa,b;ai≥0θD(a,b)=maxa,b;ai≥0minxL(x,a,b)
实际上原始问题和对偶问题的最优值不一定一样,但是在满足一定条件下是可以想等的,也就是KKT条件:
∇L(x,a,b)=0
aici(x)=0
ai≥0
其中第一个求梯度代表对所有参量求导,包括a,b。具体的KKT条件是怎么来的就不证明了
求解SVM
上面推导的最终的SVM优化问题是不等式约束的所以引入拉格朗日函数
L(w,b,α)=12∥w∥2+∑i=1mαi(1−yi(wTxi+b))
其中很重要的是
ai≥0,原始问题的对偶问题就是
maxαminw,bL(w,b,α)
先求
minw,bL(w,b,α),也就是求
L对
w和
b的偏导数,并令其为0,可得
w=∑i=1mαiyixi
0=∑i=1mαiyi
这里需要提醒的一句话是对矩阵和向量的求导最好直接参考The Matrix Cookbook直接查公式就好了,这里对向量范数的平方求向量本身的导数刚好就是向量本身
之后把上面推导出的
w代入原问题,就可以得到原问题的对偶问题
minα−∑i=1mαi+12∑i=1m∑j=1mαiαjyiyjxTixj
s.t.∑i=1mαiyi=0
αi≥0,1,2,⋯,m
这是一个关于
α的最优化问题,求出
α之后,可以根据上面的
w的表达式求出
w,然后可以根据一个或所有的支持向量求出b,因为支持向量满足
yi(wTxi+b)=1。
对于求
α的方法,这是一个二次规划问题,问题规模正比于样本数,所以人们开发出了SMO算法,具体算法不再详述,主要是每次固定两个
α:
αi和
αj,然后仅仅优化这两个个参数。
软间隔支持向量机
实际之中很少有完全可以线性可分的数据样本,经常会出现你中有我,我中有你的情况
![支持向量机(SVM)原理与实践(一) 支持向量机(SVM)原理与实践(一)](/default/index/img?u=aHR0cHM6Ly9waWFuc2hlbi5jb20vaW1hZ2VzLzg4NS9kNTY2ZjExYTExY2YyOWQ5MDAxODE5Mzk1NjNlYTFiNS5wbmc=)
这是我们要根据情况对支持向量机作出调整。
前面我们说过函数间隔的数值是没有意义的,但是支持向量不同,因为他们在wx+b=±1这两个超平面上,也就是说 对于原来比较强的约束条件yi(wxi+b)≥1,支持向量代表的yi(wxi+b)=1是下限,但现在有些样本要突破下限,因为两种样本混在一起,无论如何也分不开,那么为了满足条件,我们人为地调低下线,亦即引进一个松弛变量ξi≥0,之后的约束条件变为yi(wxi+b)≥1−ξi,但是下限不能无限低,需要在目标函数中引入惩罚项C∑Ni=1ξi,这样,新的支持向量机(原始问题)为:
minw,b,ξ12∥w∥2+C∑i=1Nξi
s.t.yi(wxi+b)≥1−ξi,i=1,2,⋯,N
ξi≥0,i=1,2,⋯,N
目标函数的意义为我们想办法尽可能使间隔最大(和原来的一样),同时使误分类点数最小(误分类点数越少惩罚项越小)。最后
可以证明w的解是唯一的,但是b的解不唯一,b的解存在于一个区间
对于这个我们依然采用拉格朗日参数法来求解,原始优化问题的拉格朗日函数为:
L(w,b,ξ,a,b)=12∥w∥2+C∑i=1Nξi−∑i=1Nai(yi(w⋅xi+b)−1+ξi)−∑i=1Nbiξi
其中要注意的依然是
ai≥0,bi≥0,对偶函数是拉格朗日函数的极大极小问题,即分别对
w,b,ξ求偏导并令其为0,求出的式子再代入原问题,最后可以推导出对偶问题为:
mina12∑i=1N∑j=1Naiajyiyj(xixj)−∑i=1Nai
s.t.∑i=1Naiyi=0
0≤ai≤C,i=1,2,⋯,N
可以看出软间隔支持向量机与上面的硬间隔的支持向量机基本类似,具体的符号上有所不同,唯一的区别就是对参数
ai的约束不同,软间隔的有上限上线就是C,从这里就看出,如果C趋于无穷大的时候,软间隔SVM就变成了硬间隔的,从目标函数也可以看出,C无穷大的时候对误分类样本点的惩罚是无穷大的,也就是SVM趋向于将所有点都分对,这点在scikitlearn中也有所体现。得到对偶问题之后的求解就不再赘述了,和硬间隔的SVM一样。
从另一个角度看SVM
有些时候我们可以将目标函数写成更一般的形式:
minw∑L(yi,f(xi;w))+λΩ(w)
其中第一项称为
经验风险,第二项称为
结构风险,其中
L(yi,f(xi;w))表示对每一个样本点,预测与实际的误差,一般我们想的就是最小化这个误差就行了,比如最小二乘法,我们采用的模型
f是线性模型,误差函数
L是平方误差,但是为了防止过拟合,我们引入结构误差项
Ω(w),该项一方面表述了我们希望获得怎样性质的模型,另一方面有助于削减假设空间,从而降低过拟合风险。上式称为
正则化问题,
Ω(w)也被称为正则化项,一般用的正则化项就是
Lp范数,其中
L2范数倾向于w的分量尽量均衡,
L0,L1范数倾向于w的分量尽量稀疏。这其实就是上面所说的希望获得的模型的性质。从贝叶斯估计的角度正则化项可以认为是为模型提供了先验概率。
以这个角度看待SVM首先对于经验风险,我们用的是合页(hinge)函数:
ℓhinge(z)=max(0,1−z)
在SVM中z就是函数间隔
yi(w⋅xi+b),然后正则化项使用的是w的2范数
L2
此时的目标函数为
minw,b∑ℓhinge(yi(w⋅xi+b))+12∥w∥22
非线性SVM
有了线性的SVM无论是软间隔还是硬间隔,对于解决线性可分问题都是非常有效的,但是有些问题就是线性不可分的,或者即使使用软间隔的SVM效果也很不好,这个时候,我们如果把数据映射到更高的维度(也叫特征空间)就有可能可以分开。看起来不好理解,我们看一张图:
![支持向量机(SVM)原理与实践(一) 支持向量机(SVM)原理与实践(一)](/default/index/img?u=aHR0cHM6Ly9waWFuc2hlbi5jb20vaW1hZ2VzLzM4LzllZGNkYjMwZWVjZDhkMGU1Y2M3Mjc0NTcyOGM5MGVlLnBuZw==)
左边的红蓝两类样本被圆分隔开,这个面用线性SVM无论如何都是得不到的,我们将每一维度映射为他们的平方φ(x)=x2,然后再右边的空间中就可以用线性SVM解决。这也称作核技巧。
应用了核技巧之后SVM的对偶问题就化为了如下形式:
mina12∑i=1N∑j=1Naiajyiyj(φ(xi)⋅φ(xj))−∑i=1Nai
其中
φ(xi)⋅φ(xj)代表在特征空间中的内积,但是这个很难计算,因为特征空间的维数经常很高甚至是无穷维的,所以我们设想有没有那么一种函数,
让两个向量在原空间进行运算之后得到的结果和在特征空间中的内积相同?令人兴奋的是这种函数是存在的!!这也可以说是令SVM强大的工具,也就是核函数,核函数的作用就是:
κ(xi,xj)=<φ(xi),φ(xj)>=φ(xi)φ(xj)
有了核函数之后SVM的目标函数就可以改写成如下的形式:
mina12∑i=1N∑j=1Naiajyiyjκ(xi,xj)−∑i=1Nai
常用的核函数为
名称 |
表达式 |
参数 |
线性核 |
κ(xi,xj)=xi⋅xj
|
多项式核 |
κ(xi,xj)=(xi⋅xj)d
|
d≥1为多项式的次数(degree)
|
高斯核 |
κ(xi,xj)=exp(−∥xi−xi∥22σ2)
|
σ>0为多项式的带宽(width)
|
以上几个为常用的核函数。我们再回头看一下核函数,以高斯核为例,我们计算核函数是很简单的,但是此时特征空间的维度是多少?答案是无穷维!因为高斯函数按照泰勒展开可以得到无穷多项,并且我们不需要知道这个到特征空间的映射的具体形式,可以说是很强大了。实际中很多时候使用高斯核就可以得到很好的结果,但是具体情况仍应该具体分析,选择合适的核函数。
综上,为支持向量机的主要内容,在下一篇博客中我将主要介绍在scikit-learn中SVM的主要用法。
主要参考
[1]周志华,《机器学习》
[2]李航,《统计学习方法》
[3]袁博,《数据挖掘:理论与算法》课程
(不少图片是从袁博老师的ppt里面截的)