前言
本文主要从如下六个方面进行介绍:支持向量机SVM目标的提出,线性可分支持向量机(硬间隔最大化),线性支持向量机(软间隔最大化--松弛因子),非线性支持向量机(核函数),SMO算法,小结。同时有些地方需要解释或者注意一下的地方会额外说明。
本文主要介绍的是理论,并没有涉及到代码,关于代码的具体实现,可以在阅读完本文,掌握了SVM算法的核心内容后去看一下笔者另一篇SVM代码剖析:
https://blog.csdn.net/weixin_42001089/article/details/83420109
1. 支持向量机SVM目标的提出
svm原理并不难理解,其可以归结为一句话,就是最大化离超平面最近点(支持向量)到该平面的距离。
如上图所示有一堆数据点,用X表示(x是n维特征向量(x1,x2,x3...xn),xn表示任意实数的标量),每个点都有对应类别y,假设蓝色点天气好,红色点天气差。
假设数据点是线性可分的(这是SVM的大前提,我不知道我理解是否有偏差),那么一定存在一个超平面能够将红色数据点和蓝色数据点分开,该超平面如上图蓝色线条,此时定义该超平面方程为:
此时回到我们需要实际解决的问题:
我们希望得到一个模型,给定一个x,能够使用该模型预测出该x所对应的类别y。
那么根据该问题,如何建立与上述的超平面方程关联性成为了新的问题。
这里我们先看一个二维特征(x1,x2)的图像,如下图红色直线的直线方程为2x1+5x2-10=0,这条线我们可以看成超平面方程,蓝色点(4,3)和橘色点(0,0)是不同类别的数据点,蓝色点的y值为1,橘色点的y值为-1。将(4,3)和(0,0)带入f(x)=2x1+5x2-10函数中可以发现,f(4,3)=13, f(0,0)=-10。可以看出不同类别的符号不同,一个是正数一个是负数,这是一个很好地性质,也能区分不同的类别。
根据上述引用中的说明,超平面方程与实际的问题通过分类决策函数产生了联系。那么此时,问题转变为如何求超平面函数
(记住这是最终目标,尽管后续一直在转变方式,但是求解的目标一直是该函数)。
2. 线性可分支持向量机(硬间隔最大化)
现在的目的是要求出超平面函数,但是超平面函数可能取很多种,如下图所示,下图表示每一个超平面都能分开数据,那么这么多超平面中如何选出最优的超平面呢?
最朴素的想法就是两边的点距离这个超平面都很远,即使离超平面最近点的距离也是这些候选超平面中最大的。如下图中所示,蓝色线是超平面,绿色线上的点就是我们的支持向量。
关于点到线的距离点到直线距离公式的几种推导 - 知乎,经过拓展,可以得出距离公式为:
,其中||w||表示2范数。L0,L1,L2范数(双竖线,有下标)_mjiansun的博客-CSDN博客_范数下标。
但是
公式中有绝对值,绝对值求解难度较大,需要去掉绝对值。根据“支持向量机SVM目标的提出”中的例子,y的正负号(如果y不是正负的类别,例如天气差天气好,直接将天气差指定为-1,天气好指定为+1即可)与f(x)的正负号一致,那么y*f(x)>=0,等于0仅发生在某一个数据点正好落在超平面上。
那么距离公式转变成:
下面就转化为了最值优化问题:
注意:
(1)这里的就是标签假设这里是二分类问题,其值是1和-1,其保证了不论样本属于哪一类都是
大于0的。这里的xi的下表i表示第几个样本,而不是值特征维度。
为啥取1和-1?
具体阐述如下:1.对于二类问题,因为y只取两个值,这两个是可以任意取的,只要是取两个值就行;2.支持向量机去求解二类问题,目标是求一个特征空间的超平面,而超平面分开的两类对应于超平面的函数值的符号是刚好相反的;3.基于上述两种考虑,为了使问题足够简单,我们取y的值为1和-1;4.在取定分类标签y为-1和1之后,那么,一个平面正确分类样本数据,就相当于用这个平面计算的那个y*f(x)>0; 5、而且这样一来,y*f(x)有明确的几何含义;
总而言之:你要明白,二类问题的标签y是可以取任意两个值的,不管取怎样的值对于相同的样本点,只要分类相同,所有的y的不同取值都是等价的,之所以取某些特殊的值,只是因为这样一来计算会变得方便,理解变得容易。
正如朋友张磊所言,svm中y取1或-1的历史原因是因为感知器最初的定义,实际取值可以任意,总能明确表示输入样本是否被误分,但是用+1、-1可以起码可以是问题描述简单化、式子表示简洁化、几何意义明确化。
举个例子,如你要是取y为1和2,比如原来取-1的现在取1,原来取1的现在取2 , 这样一来,分类正确的判定标准变为(y-1.5)*f(X)>0 , 故取1和-1只是为了计算简单方便,没有实质变化,更非一定必须取一正一负。
(2)称为函数距离,
称为几何距离,这里之所以要使用几何距离是因为,当
成倍增加时,函数距离也会相应的成倍的增加,而几何函数则不会。
几何距离为何不会随着w和b成倍增加,举例如下:
超平面函数:f(x1,x2)=2x1+5x2-10
那么(4,3)点离直线距离1*f(4,3)/sqrt(2^2+5^2) = 13/sqrt(29)
超平面函数的w和b扩大2倍变为:f(x1,x2)=4x1+10x2-20
那么(4,3)点离直线距离1*f(4,3)/sqrt(4^2+10^2) = 13/sqrt(29)
可以发现几何距离始终由于除了w的二范数所以一直没有成倍增加。
但是函数距离f(4,3)有原来的13变成了26.扩大了两倍。
这里涉及到求两个最值问题,比较棘手,正如上面所说,几何距离不受成倍增加的影响,这里不妨就将最近点到超平面的函数距离设为1(1是因为函数距离总能通过增大缩小w和b来实现),自然其他非最近点的函数距离便是大于1,于是以上问题转化为:
这是一个在有不等式约束下,最小值优化的问题,这里可以使用kkt条件。
根绝拉格朗日乘子法,可以将上面的最小化问题转为:
于是问题转化为:
根据对偶转化:
好啦,这里没什么说的就是根据kkt条件求偏导令其为0:
于是就得到:
将上述两公式带入到如下:
于是问题转化为:
所以最后就得出这样的步骤:
1.首先根据上面的最优化问题求出一些列的
2.然后求出w和b
所以超平面函数是:
将新的x带入上面的式子,即可得到预测的y值。
3. 根据如下进行分类:
这里有一个例子SVM支持向量机原算法与对偶算法举例_mjiansun的博客-CSDN博客。
3. 线性支持向量机(软间隔最大化--松弛因子)
如上图所示,上面的那个圆圈点是一个特殊点,从我们的直观角度,虚线的超平面比直线的超平面要好,泛化性更强。
总结来说:有一个点由于采集错误或者其他原因,导致其位置落在了别的离别当中,而svm是找最近的点,所以这时候找出的超平面就会过拟合,解决的办法就是忽略掉这些点(离群点),即假如松弛因子,使几何距离不那么大于1。
数学化后的约束条件即变为:
这里简单来理解一些C的含义:这是一个在使用SVM时需要调的参数,代表离群点到底离群点有多远,而C就是我们对这些点的重视程度,假设现在
是一个定值,那么当C越大,就代表我们越重视这些点,越不想舍弃这些点,即极端的当
时,优化是求min,则无解,即对应的直观理解就是:这时线性不可分,大家都混在一起,这时又不想舍弃任何一个点,自然就不能找到适合的超平面(当然可以使用核函数进行映射分类,后面说明)。
接下来还是使用上面拉格朗日对偶问题进行求解,这里就不详细说明了,直接给出过程:
求导令其为0:
将其带入最终问题可得:
这里得到的和没加松弛变量时是一样的。
对应的kkt条件为:
一、对比最开始的kkt条件模板
这里的(1)(8)(9)是求偏导的结果即一二三公式,(6)(7)是拉格朗日乘子即相当于模板的第五公式,(2)(4)相当于模板第六个公式,(3)(5)是原始约束条件即相当于模板的第七个公式。
二、可以将kkt中部分条件进行总结归纳:(6)(7)(8)三个条件:
所以可以总结为:
可以看到这里和没加松弛变量相比,唯一不同的就是
有了上界C,它代表着我们对那些离群点的重视程度。
三、说一下
取不同值时意义
关于求b还是有一点疑惑,我再理解理解
4. 非线性支持向量机(核函数)
出现的背景:
对于一些线性不可分的情况,比如一些数据混合在一起,我们可以将数据先映射到高纬,然后在使用svm找到当前高纬度的超平面,进而将数据进行有效的分离,一个直观的例子:
比如原来是:
则现在为:
其中就是映射公式,即先映射到高纬再进行内积
但是问题来了,那就是假设原始数据维度就好高,再进一步映射到高纬,那么最后的维度可能就非常之高,再进行内积等这一系列计算要求太高,很难计算。
因此我们可以令
这里的便是核函数,其意义在于我们不用去映射到高纬再内积,而是直接在低纬使用一种核函数计算
,使其结果和映射到高纬再内积效果一样,这就是核函数的威力,大部分是内积,而SVM的奇妙之处就在于所有的运算都可以写成内积的形式,但是这种核函数具体该怎么选取呢?别慌,已经有前辈们帮我们找到了很多核函数,我们直接拿过来用就可以啦。
下面介绍几种常见的吧:更多的大家可以自行查阅
(1)线性核函数 :也是首选的用来测试效果的核函数
其维度与原来相同,主要用于线性可分的情况,其实就是原始导出的结果
(2)多项式核函数
其实现将低维的输入空间映射到高纬的特征空间,但多项式的阶数也不能太高,否则核矩阵的元素值将趋于无穷大或者无穷小,计算复杂度同样会大到无法计算。而且它还有一个缺点就是超参数过多
(3)径向基高斯(RBF)核函数
高斯(RBF)核函数核函数性能较好,适用于各种规模的数据点,而且参数要少,因此大多数情况下优先使用高斯核函数。
(4)sigmoid核函数
不难看出这里有点深度学习当中,一个简单的神经网络层。
总的来说就是,当样本足够多时,维度也足够高即本身维度已经满足线性可分,那么可以考虑使用线性核函数,当样本足够多但是维度不高时,可以考虑认为的增加一定的维度,再使用线性核函数,当样本也不多,维度也不高时,这时候可以考虑使用高斯(RBF)核函数。
5. SMO算法(不太懂我先去看看原博主的代码)
关于SVM ,python中有一个机器学习库sklearn,其中集成了很多机器学习方法,包括SVM,笔者这里也做过一个简单直观的调用,可以参看python_sklearn机器学习算法系列之SVM支持向量机算法_爱吃火锅的博客-CSDN博客
再者就是我们虽然可以直接拿sklearn库下集成好的接口来用,但是其具体实现细节,还是有必要了解一下,换句话说,上面我们最后得到的结果是:
我们求出一些列便可,可是
具体怎么求呢?落实到代码上面应该怎么搞呢?下面就来说说这个事情。
首先要明确我们的目的是求一些列的,其思路也是很简单就是固定一个参数即以此为自变量,然后将其他的变量看成常数,只不过因为这里
约束条件,所以我们一次取出两个
作为自变量进行优化,然后外面就是一个大的循环,不停的取不停的优化,直到达到某个条件(后面介绍)停止优化。
为什么是二元一次方程呢?很简单由原始优化目标可以看出基本单元就
,然后就是组合相加,所以最高次数就是2次,前面还有单次项,后面有常数项,所以最后归结起来就是一个一元二次方程。
现在我们进一步化简一下
我们将本次要优化的参数标为*即规范一下就是:
好啦,最最最最最最重要的一张图来啦,也是我们上面花了这么多力气得出的结果,也是我们最终程序设计的蓝图:
6. 小结
求解过程