SVM是一个二元分类算法,线性分类和非线性分类都支持。经过演进,现在也可以支持多元分类,以及回归问题。而感知机在思想上可以看做SVM的前辈。
感知机模型就是尝试找到一个超平面,能够把所有二元类分开。如果找不到这么一条直线,就说明类别线性不可分,也就意味着感知机模型不适合你的数据分类。使用感知机的前提就是数据线性可分。而其他模型在面对线性不可分的情况下,比如支持向量机可以通过核技巧来让数据在高维可分,神经网络可以通过激活函数和增加隐藏层来让数据可分。
对于这个分离的超平面,定义为,而将x代入后大于0定义为类别1,小于0定义为-1。如果这两类数据线性可分,这样的超平面一般都不是唯一的,也就是说感知机模型可以有多个解。
则感知机模型可以定义为:,
于是对于误分类的样本,满足 。
该样本点到超平面的距离为:
感知机的损失函数优化,思想是让所有误分类的点(M)到超平面的距离和最小,于是有损失函数:
这里可以不考虑,为什么呢?因为如果当分子的ω扩大N倍,分母的L2范数也会扩大N倍,分子和分母有固定的倍数关系。可以通过固定分子或者分母为1,然后求 分子 或者 分母的倒数的最小化 作为损失函数。这里把分母固定为1,即得到简化的损失函数:
(如果把分母固定为1,则就引入了SVM的损失函数)
对于这个损失函数可以用梯度下降法或者拟牛顿法来解决,常用的是梯度下降法。
回到感知机,感知机采用随机梯度下降,也就是每次只需要使用一个误分类的点来更新梯度。
损失函数:
对ω求偏导:
则ω的梯度下降公式应该为:
,其中α为步长,y(i)的输出样本为1或者-1,x(i)为(n + 1) x 1维向量。
而我们采用随机梯度下降,所以每次仅仅采用一个误分类样本来计算梯度,假设采用第i个样本来更新梯度,则
对偶形式可以对执行速度进行优化。
之前的算法形式为。对于从来没有误分类过的样本,被选择参与ω迭代的次数为0,对于被多次误分类而更新的样本j,参与ω迭代的次数设为mj。如果令ω初始值为0向量,则表达式可以写为:
在判断是否误分类时,原始是 变为 。注意到现在是和。这个内积结果在下面的迭代次数中可以重用。如果事先用矩阵算出所有样本间的内积,那在算法运行时仅仅一次的矩阵内积计算比多次的循环计算更省时。而判断误分类就是感知机里计算量最大的地方,对偶形式就比原始形式更加优越。
感知机是深度学习网络,神经网络等的基础,SVM也参考借鉴了一部分思想。
感知机的解不唯一,与ω的初值和α的初值有关,这个初值的设置会影响最终的结果。
同时使用对偶形式也比原始形式计算效率更高。
支持向量机(Support Vector Machine),如果不考虑集成学习的算法,不考虑特定训练数据集,在分类算法中的表现SVM排第一是没有什么异议的。
之前在感知机的回顾中提到,超平面固定的时候,表示点x到超平面的相对距离。通过观察与y是否同号,判断分类是否正确。
定义函数间隔γ',之前在感知机也提到过:
对于训练集m个样本,对应m个函数间隔的最小值,就是整个训练集的函数间隔(判断性能用最小的那个来确定)。
函数间隔越大,对分类的结果越确信,我们希望函数间隔越大越好。那成比例增加ω和b就可以了?但是与是一回事。
所以函数间隔并不能正常反应点到超平面的距离。为同一度量,得到几何间隔γ,定义为
感知机里用的就是几何间隔。定义训练集到超平面的最小几何间隔为m个几何间隔的最小值。
支持向量机的核心思想是,只关心离超平面近的那些点是否分类正确,因为离超平面很远的那些点已经被分类正确了,如果让比较近的点尽可能远离超平面,那么分类效果会好一些。
而感知机的思想为让所有误分类的点(M)到超平面的距离和最小。思想的差距决定了支持向量机的分类效果是比感知机更优的。
可以证明,符合支持向量机要求的超平面只有一个,具有唯一性,而符合感知机条件的超平面可能有多个。
和支持向量机的超平面保持一定的函数距离的两个超平面对应的向量(距离超平面最近的且满足一定条件的几个训练样本点,也就是在这两个超平面上的样本点),定义为支持向量。
(这里的函数距离为1,支持向量到超平面的几何距离为,两个支持向量的距离为)
在知道支持向量后,支持向量机要所有的分类点都在各自类别的支持向量两边。
我们希望找到最大的函数间隔:
实际上函数间隔在此处并不影响最优化问题的解。因为为了最大化上面式子,若将ω等比例增大,函数间隔也会等比例增大,最后也会除以对应的比例。所以此处可以将函数间隔设为1。
可以看到,支持向量机是在固定分子的形式下,优化分母,同时加上支持向量的限制;而感知机是固定分母优化分子(在回顾感知机有提到)。
由于最大化 等同于 最小化,这样又将损失函数转化为一个二次规划问题:
接着刚才的地方,根据凸优化理论,可以通过广义拉格朗日函数将优化目标转化为优化函数
优化目标变为:
这个优化函数满足KKT条件,其对应的拉格朗日对偶问题为(满足KKT条件后对偶问题的最优值和原始问题相同):
将ω代入消去ω:
现在,下面其实是一个二次规划问题:
去掉负号,等价为:
根据SMO算法,得到上式极小化时对应的α向量,。(N和下面的m都指的是样本数量)。
如何得到支持向量:
根据KKT的对偶互补条件,若αi>0,则说明存在点在支持向量上。
若αi=0,则有(因为这里原始问题的不等式约束是大于等于,要转化为标准形式的小于等于),即样本已经在支持向量上,或者已经被正确分类。
在求解时,我们只采用αi>0的对应的样本作为支持向量。所以最后实际求得的ω只与支持向量有关。
求b:
对于任意支持向量,都有,理论上有多少支持向量就对应多少个,这些b都可以作为最终结果,但是一种更稳健的方法是求出这些b的平均值作为最后的结果(软间隔后的SVM)。对于严格线性可分的SVM,b的值都是有唯一解的,也就是这里求出的所有b都是一样的。
这样最终的分类超平面为。
最终的分类决策函数为。
对于非线性可分的数据,线性可分SVM的学习方法无法使用。有时出现异常点也会导致数据集不能线性可分,这就需要使用软间隔最大化的思想。
刚刚提到了异常点,类似例子如下:
这种异常点导致无法按照刚才的线性可分SVM来分类。
最上面那个蓝色的异常点会严重影响我们线性可分SVM模型的泛化性能,本来按照中间那条红线就可以进行分类,但最上面的蓝色点改变了我们的支持向量。
软间隔是相对于硬间隔说的,而硬间隔就是上面提到的线性分类SVM,“硬”,丝毫没有余地,毫不留情,能分就分。
硬间隔最大化的条件:
而软间隔其实是对每个样本都引入一个松弛变量,于是软间隔的条件变为:
可以看到,对样本到超平面的函数距离要求变低了。
C>0,可以理解为惩罚参数(正则化参数),C越大误分类的惩罚越大,C越小,对误分类的惩罚越小。在实际应用中需要进行调参。
另一种推导:
引入Hinge loss。
我们仅考虑错分的代价:
比如对于类1的数据,我们希望
对于类-1的数据,希望
总之希望。如果实际上为负,或者虽然为正但是小于1,综合起来就是
,就带来了的损失。
在线性可分的情况下,会有许多ω使得L = 0,为了选择一个合理的ω,也需要加入正则化。
于是有了约束:
也就是
于是通过拉格朗日函数就可以转化为下面的形式:
其中拉格朗日系数,均大于等于0。
现在要优化的目标函数为(为什么变成这样):
同时有KKT:
利用上面的式子消除ω和b:
第一个公式到第二个公式套用了。最后得到的式子和硬间隔的一模一样。但是不同的是约束条件。
约束条件可以进行整合,将去掉,同时将极大问题转化为极小问题:
这就得到了原始问题的对偶问题的最终形式,由于满足KKT条件,可以通过解对偶问题进而得到原始问题的解。
KKT条件:
与硬间隔相比,仅仅是多了这个条件。通过SMO算法仍然可以算出极小化对应的α,然后再通过算出。
算支持向量时,由于加入了松弛变量,KKT对偶互补条件变为。
对于αi=0(i = 1,2,...m,m为样本个数),那么由对偶互补条件,可知。且由得知为C。又有对偶互补条件,可知此时为0。于是,样本在间隔边界上或者已经被正确分类。
对于0<αi
对于αi=C,由得到等于0。则由说明可能为0,也可能不为0。所以需要分开考虑。
当,样本位于超平面与类别的间隔边界之间,如图中的样本2和4;当,样本在超平面上,无法正确分类;当,则样本在超平面另一侧,也就是说这个点不能被正常分类,如图中的样本1和3。这四个样本都是支持向量。
通过找到所有的S个支持向量对应的样本,使用函数间隔将对应的算出,最后计算出所有的并算出平均值即为最终的。
以上均为线性可分的情况,对于非线性可分的数据,我们需要引入核函数。
比如对于一个多项式回归:
若,将其映射到高维,则变为
,就又重新回到了线性回归。对于每个样本特征
将其映射为了。
核技巧应用到支持向量机,其基本想法就是通过一个非线性变换将输入空间对应于一个特征空间,使得在输入空间中的超曲面模型对应于特征空间H的超平面模型(支持向量机)。这样就使分类问题的学习任务通过在特征空间中求解线性支持向量机就可以完成。
回顾线性可分SVM的优化目标函数:
特征以内积的形式出现,定义一个从低维到高维的映射,将其替换为。
面对本身比较低的维度,映射后可能得到还能比较接受的维度,而面对本身比较高的维度,映射后得到的高维维度是爆炸性增长的,计算量太大,可能根本无法计算。
而核函数能够避免在高维空间中的直接计算,它在低维上进行计算,而将实质上的分类效果(利用内积)表现在高维,真正解决SVM线性不可分的问题。
核技巧在学习和预测中只定义核函数,而不显式地定义映射函数φ。通常直接计算比较容易,而通过和的内积计算并不容易。所以就像刚刚所说的“能够避免在高维空间中的直接计算”。
通常所说的核函数是正定核函数:里面任何点的集合形成的Gram矩阵是半正定的。也就是是半正定的。
当引入了核函数后,我们的优化目标函数变为了:
实际上就是我们之前的线性支持向量机里用的,所以其实线性支持向量机也可看做非线性支持向量机的一种特殊情况。
线性不可分SVM常用的核函数之一。
,γ、r、d都需要自己进行调参。
在SVM中也称为径向基核函数(Radial Basis Function, RBF)。非线性分类SVM中最主流的核函数。libsvm默认核函数。
γ大于0,需要自己调参。
也是线性不可分SVM的常用核函数。
γ、r都需要自己进行调参。
1、如果特征维数很高,往往线性可分,可以采用线性核
2、如果样本数量多,使用高斯核计算量会大于线性核,通过手动添加一些特征使得线性可分,然后可以使用线性核
3、在选择核函数时,如果线性拟合不好,一般推荐使用默认的高斯核'rbf'。这时我们主要需要对惩罚系数C和核函数参数γγ进行艰苦的调参,通过多轮的交叉验证选择合适的惩罚系数C和核函数参数γγ。
分类的算法库包括SVC,NuSVC和LinearSVC 3个类。另一类是回归算法库,包括SVR,NuSVR和LinearSVR。相关类都在sklearn.svm模块中。
对于SVC和NuSVC,它们差不多,只是对于损失的度量不同,而LinearSVC是线性分类,仅仅支持线性核函数,不能用于线性可分数据。对于回归,也是类似的情况。
在使用这些类的时候,如果有先验知道数据是线性可以拟合的,那么使用LinearSVC或者LinearSVR,不需要慢慢去调参,速度也快。如果对数据分布没有什么经验,一般使用SVC或者SVR,就需要选择核函数以及对核函数调参了。
如果对训练集的错误率或者支持向量的百分比有要求的时候,可以选择NuSVC和NuSVR,它们有一个参数来控制。
主要超参数为为惩罚系数C和RBF核函数的系数γ。
当C较大时,损失函数越大,这意味着不愿放弃比较远的离群点,这样会有更多的支持向量,也就是说支持向量和超平面的模型也会变得越复杂,也容易过拟合。反之,当C较小时,意味不想理哪些离群点,会选择较少的样本来做支持向量,最终的支持向量和超平面的模型也会简单。在sklearn中该值默认为1。
另一个超参数是RBF核函数的参数γ,。γ定义了单个样本对整个分类超平面的影响,当γ比较小时,单个样本对整个超平面的影响比较小,不容易被选择为支持向量,反之,当γ比较大时,单个样本对整个分类超平面的影响比较大,更容易被选择为支持向量。sklearn中默认值为,N为特征维度。
如果把惩罚系数C和RBF核函数的系数γ一起看,当C比较大, γ比较大时,我们会有更多的支持向量,我们的模型会比较复杂,容易过拟合一些。如果C比较小 ,γ比较小时,模型会变得简单,支持向量的个数会少。
在sklearn中,主要使用网格搜索,即GridSearchCV,比cross_val_score更加方便。
使用网格搜索时注意的参数:
estimator:即模型,此处是带高斯核的SVC或SVR。
param_grid:如果用SVC分类的话,param_grid可以定义为{"C":[0.1, 1, 10], "gamma": [0.1, 0.2, 0.3]},这样会有9种超参数组合来进行网格搜索。
cv:S折交叉验证的折数。
至此,SVM可以不用再对线性还是非线性进行区分。
输入m个样本(x1, y1),(x2, y2),(x3, y3)...(xm, ym).x为n维特征向量。y为二元输出,值为1或-1.
算法如下:
(1)选择适当核函数合一惩罚系数C,构造约束优化问题
(2)用SMO算法求出上式最小时对应的α向量,α*。
(4)找出所有支持向量,即满足对应的样本,通过,计算出每个支持向量对应的,计算出。所有的平均值即为最终的。
算法复杂度
SVM的算法复杂度体现在两个方面,一个是训练阶段,一个是预测阶段。在训练阶段,为了解决二次规划问题,常使用内点法,但这会导致需要存储一个nxn的矩阵(n为数据样本数,存储alpha),为了解决这个问题,使用了SMO算法。
若使用线性核函数,我们可以看到计算ω的时间复杂度为O(nd),n为数据样本数,d为特征维度。而在预测阶段,时间复杂度和支持向量的数量成正比。
而使用非线性核函数,由于核函数本身的计算量增大,例如使用RBF核函数,这时计算时间复杂度为O(n^2d)。而在预测阶段时间复杂度依然和支持向量数量成正比。
优点
缺点