一.SMO算法的原理

SMO算法和以往的一些SVM改进算法一样,是把整个二次规划问题分解为很多较易处理的小问题,所不同的是,只有SMO算法把问题分解到可能达到的最小规模:每次优化只处理两个样本的优化问题,并且用解析的方法进行处理。我们将会看到,这种与众不同的方法带来了一系列不可比拟的优势。

对SVM来说,一次至少要同时对两个样本进行优化(就是优化它们对应的Lagrange乘子),这是因为等式约束的存在使得我们不可能单独优化一个变量。

所谓“最小优化”的最大好处就是使得我们可以用解析的方法求解每一个最小规模的优化问题,从而完全避免了迭代算法。

当然,这样一次“最小优化”不可能保证其结果就是所优化的Lagrange乘子的最终结果,但会使目标函数向极小值迈进一步。我们再对其它Lagrange乘子做最小优化,直到所有乘子都符合KKT条件时,目标函数达到最小,算法结束。

这样,SMO算法要解决两个问题:一是怎样解决两个变量的优化问题,二是怎样决定先对哪些Lagrange乘子进行优化。

二.两个Lagrange乘子的优化问题(子程序takeStep)

我们在这里不妨设正在优化的两个Lagrange乘子对应的样本正是第一个和第二个,对两个Lagrange乘子α1和α2,在不改变其他乘子的情况下,它们的约束条件应表达为正方形内的一条线段。如图所示:

在这条线段上求一个函数的极值,相当于一个一维的极值问题。我们可以把α1用α2表示,对α2求无条件极值,如果目标函数是严格上凹的,最小值就一定在这一极值点(极值点在区间内)或在区间端点(极值点在区间外)。α2确定后,α1也就确定下来了。因此我们先找到α2优化区间的上下限制,再在这个区间中对α2求最小值。

由图1我们容易得到α2的上下限应为:

L=max(0,α2-α1),H=min(C,C+α2 –α1) , 若y1与y2异号;

L=max(0,α21-C), H=min(C, α21) ,若y1与y2同号;

令s=y1y2标志这两个样本是否同类,则有

L=max(0, α2+sα1- 1/2 (s+1)C), H=min(C, α2 +sα1 –1/2 (s-1)C)

而α1和α2在本次优化中所服从的等式约束为:

α1+sα201+sα02=d

下面我们推导求最小值点α2的公式:由于只有α1,α2两个变量需要考虑,目标函数可以写成

Wolfe(α12)=1/2 K11α21+1/2 K22α22+ sK12α1α2 + y1α1v1 +y2α2v2 -α1 -α2+常数

其中Kij=K(xi,xj) , vi=y3α03Ki3+…+ylα0lKil = ui+b0- y1α01K1i – y2α01K2i

上标为0的量表示是本次优化之前Lagrange乘子的原值。

将α2用α1表示并代入目标函数:

Wolfe(α2)=1/2 K11(d-sα2)2+1/2 K22α22+sK12(d-sα2) α2

+y1(d-sα2)v1 – d+sα2+y2α2v2-α2+常数

对α2求导:

dWolfe(α2)/dα2

=-sK11(d-sα2)+K22α2-K12α2+sK12(d-sα2)-y2v2+s+y2v2-1 =0

如果Wolfe函数总是严格上凹的,即二阶导数K11+K22-2K12>0, 那么驻点必为极小值点,无条件的极值点就为

α2=[s(K11-K12)d+y2(v1-v2)+1-s] / (K11+K22-2K12)

将d,v与α0,u之间关系代入,就得到用上一步的α02,u1,u2表示的α2的无条件最优点:

α2=[α02(K11+K22-2K12) +y2(u1-u2+y2-y1)] / (K11+K22-2K12)

令η=K11+K22-2K12为目标函数的二阶导数,Ei=ui-yi为第i个训练样本的“误差”,这个式子又可以写为

α2=α02+y2(E1-E2)/η

除非核函数K不满足Mercer条件(也就是说不能作为核函数),η不会出现负值。但η=0是可以出现的情况。这时我们计算目标函数在线段两个端点上的取值,并将Lagrange乘子修正到目标函数较小的端点上:

f1=y1(E1+b)-α1K(x1,x1)­-sα2K(x1,x1)

f2=y2(E2+b)-sα1K(x1,x2)­-α2K(x2,x2)

L11+s(α2-L)

H11+s(α2-H)

WolfeL=L1f1+Lf2+1/2 L21K(x1,x1)+1/2 L2K(x2,x2)+sLL1K(x1,x2)

WolfeH=H1f1+Hf2+1/2 H21K(x1,x1)+1/2 H2K(x2,x2)+sHH1K(x1,x2)

当两个端点上取得相同的目标函数值时,目标函数在整条线段上的取值都会是一样的(因为它是上凹的),这时不必对α1,α2作出修正。

α2的无条件极值确定后,再考虑上下限的限制,最终的α2

最后,由等式约束确定α1

α1*1+s(α2-α2*)

三.选择待优化Lagrange乘子的试探找点法

事实上即使我们不采用任何找点法,只是按顺序抽取αi,αj的所有组合进行优化,目标函数也会不断下降,直到任一对αi,αj都不能继续优化,目标函数就会收敛到极小值。我们采取某种找点方法只是为了使算法收敛得更快。

这种试探法先选择最有可能需要优化的α2,再针对这样的α2选择最有可能取得较大修正步长的α1。这样,我们在程序中使用两个层次的循环:

内层循环(子程序examineExample)针对违反KKT条件的样本选择另一个样本与它配对优化(指优化它们的Lagrange乘子),选择的依据是尽量使这样一对样本能取得最大优化步长。对其中一个Lagrange乘子α2来说优化步长为|(E1-E2)/η|,但由于核函数估算耗时较大,我们只用|E1-E2|来大致估计有可能取得的步长大小。也就是说,选出使得|E1-E2|最大的样本作为第二个样本。需要注意的是,这样的步长估计是比较粗略的,选择出来的一对样本有时非但不能“一劳永逸”地“一步到位”,反而不能作出进一步调整,(例如η=0的情况,最小优化问题的二次型只是半正定的)。这时我们遍历所有非边界样本(非边界样本就是Lagrange乘子不在边界0或C上的样本),继续寻找能与α2配对优化的α1,如果这样的样本在非边界样本中找不到,再遍历所有样本。这两次遍历都是从随机位置开始的,以免算法总是在一开始遍历就向固定的方向偏差。在极端退化的情形,找不到与α2配对能作出进一步调整的α1,这时我们放弃第一个样本。

外层循环(主程序smo)遍历非边界样本或所有样本:优先选择遍历非边界样本,因为非边界样本更有可能需要调整,而边界样本常常不能得到进一步调整而留在边界上(可以想象大部分样本都很明显不可能是支持向量,它们的Lagrange乘子一旦取得零值就无需再调整)。循环遍历非边界样本并选出它们当中违反KKT条件的样本进行调整,直到非边界样本全部满足KKT条件为止。当某一次遍历发现没有非边界样本得到调整时,就遍历所有样本,以检验是否整个集合也都满足KKT条件。如果在整个集合的检验中又有样本被进一步优化,就有必要再遍历非边界样本。这样,外层循环不停地在“遍历所有样本”和“遍历非边界样本”之间切换,直到整个训练集都满足KKT条件为止。

以上用KKT条件对样本所作检验都是达到一定精度就可以了,例如正侧的非边界样本的输出ui可以在1的一定公差范围之内,通常这一公差(tolerance)取0.001,如果要求十分精确的输出算法就不能很快收敛。

四.每次最小优化后的重置工作

每做完一次最小优化,必须更新每个样本的误差(Error Cache),以便用修正过的分类面对其它样本再做KKT检验,以及选择第二个配对优化样本时估计步长之用。

更新Error Cache首先要重置阈值b 。我们可直接利用刚刚被优化的两个样本的信息在原阈值b0基础上作简单修正,而不需要调用所有支持向量重新计算b 。最小优化后的α1*如果不在边界上,b的计算公式为:

b1=E1+y11*-α10)K(x1,x1)+y22*-α20)K(x1,x2)+b0

最小优化后的α2*如果不在边界上,b的计算公式为:

b2=E2+y11*-α10)K(x1,x2)+y22*-α20)K(x2,x2)+b0

α1*,α2*都不在边界上时,b1和b2是相等的。两个Lagrange乘子都在边界上时,b1和b2以及它们之间的数都可作为符合KKT条件的阈值。这时SMO算法选择最安全的b1 ,b2之中点作为阈值。

非线性的情况,误差的计算要用到所有已找到的支持向量及它们的Lagrange乘子:

线性的情况则是先重置分类超平面的法向量w,再根据uj=w’xj-b计算输出uj和误差Ej=uj-yj 。同阈值的重置一样,法向量的重置也不需要调用所有的支持向量,只需在原来的法向量基础上作改动:

w*=w+y11*-α1)x1+y22*-α2)x2

大部分重置工作都是以简单的非循环计算来完成的,这使得需要做很多次最小优化的SMO算法不必在每次优化后的重置中花费太多时间。但是我们也看到,非线性的情况误差的重置必须与所有支持向量逐个计算核函数,而且核函数的计算本身就比点积复杂,于是非线性的情况误差的重置将成为算法速度的瓶颈。

四、算法的流程图

五、Platt大神的逻辑代码

六、源代码的实现

未完,待续……

转载于:https://www.cnblogs.com/machinelearner/archive/2013/03/28/2987509.html

手把手教你实现SVM算法(二)相关推荐

  1. 手把手教你给 SSH 启用二次身份验证

    目前来说,二次验证是比较常用的安全手段,通过设置二次验证,就可以有效的避免账户密码的泄露导致的安全问题.因为,每次登陆前都需要获取一次性验证码,如果没有验证码的话就无法成功登陆. 1.安装 PAM 模 ...

  2. 2019-1-30手把手教你怎么用AbaqusGUI二次开发攻略

    2019年1月30日13:05:51 手把手教你怎么用Abaqus进行GUI二次开发攻略 1.前言: 最近研究了下GUI二次开发,做了如下几个插件,学到了一些东西特地就跟大家做个分享,其中插件注册到了 ...

  3. echarts formatter_手把手教你玩转echarts(二)折线图

    茫茫人海中与你相遇 相信未来的你不会很差 作者:婷酱Yaaa 来源:https://juejin.im/post/5f0292d35188252e5a5dbed0 前言 哈喽,everybody,我又 ...

  4. 手把手教你用YOLOv5算法训练数据和检测目标(不会你捶我)

    前言 本人从一个小白,一路走来,已能够熟练使用YOLOv5算法来帮助自己解决一些问题,早就想分析一下自己的学习心得,一直没有时间,最近工作暂时告一段落,今天抽空写点东西,一是为自己积累一些学习笔记,二 ...

  5. 【手把手教你树莓派3 (二)】 启动wifi模块

    概述 树莓派3内置了wifi和蓝牙模块,我们不用像以前的版本那样,再去购买一个外接的模块练到raspberry上. 当我们第一次启动了树莓派的时候,必然使用了网线,但是之后的每一次使用,我们当然更希望 ...

  6. vue手把手教你实现论坛bbs——(二)创建组件

    创建页面基本组件:包括Header.PostList.SideBar.Article和UserInfo组件. 1.以创建Header组件为例子,主要步骤: a.编写组件页面基本内容 在src/comp ...

  7. 手把手教你学Go(二)——Hello world

    环境安装 brew install go 然后查看安装情况 ➜ ~ go env GOARCH="amd64" GOBIN="/Users/xingqi/go/bin&q ...

  8. echarts 折线图 设置y轴最小刻度_手把手教你玩转echarts(二)折线图

    茫茫人海中与你相遇 相信未来的你不会很差 作者:婷酱Yaaa 来源:https://juejin.im/post/5f0292d35188252e5a5dbed0 前言 哈喽,everybody,我又 ...

  9. 手把手教你玩物联网(三)---对接onenet云端

    <手把手教你玩物联网>系列推文将介绍使用RT-Thread----小而美的物联网操作系统,制作一个室内温湿度数据采集,并实现终端采集数据上传物联网云平台onenet,实现云端远程数据监控功 ...

最新文章

  1. Linux下时间戳格式和标准时间格式的转换
  2. 模糊数学笔记:七、模糊综合评判决策
  3. spring 注解说明以及@Resource和@Autowired的区别
  4. 树莓派输出pwm波c语言,树莓派Ubuntu18.04使用pigpio库产生PWM波实现舵机控制
  5. js学习小计1-onbeforeunload
  6. 小程序初始化服务器数据,微信小程序 项目实战(一)生命周期 配置服务器信息 splash启动页...
  7. servlet3.0理解
  8. 千人千面是php算法吗,推荐算法可以做到千人千面,但它的流量利用效率一定是优于人工分发吗?...
  9. 静态成员对比实例成员(static修饰符解析)
  10. 安全牛:安全与业务不存在平衡 证明价值是关键
  11. 长沙小吃比较好吃and著名的地方
  12. windows nginx出现 was not signaled for 5s的看过来
  13. Git常用命令及其作用_艾孜尔江撰
  14. (课堂作业)spring-boot集成shiro的步骤及代码解析
  15. 微信开发(3)微信支付
  16. OpenCV学习(二十) :直方图匹配、对比:calcHist(),minMaxLoc(),compareHist()
  17. 怎么打开苹果Mac电脑科学型计算器
  18. 知识补充----Java
  19. Win7安装完成后对系统的优化设置
  20. vue 菜单路由重复点击报错

热门文章

  1. Android学习笔记之自定义Toast
  2. 有趣的0-1背包问题:分割等和子集
  3. C++中的const
  4. 从小白到社会精英必须经历的三个阶段
  5. MOVW 和 rep
  6. springmvc二十一:自定义类型转换器
  7. spring30: 事务
  8. 操作系统一:内核态的开销
  9. linux:安装mysql
  10. GSON的使用以及GsonFormat工具的安装