一、SMO算法简单推导

前面讲了一大堆都是理论推导,最后得到的公式是:

KKT条件为:

接着我们要将的就是如何求解,编程如何实现,这才是我们学习的真正目的。

在这里我们先不管KKT条件,相关公式推导,我们的目的是求解拉格朗日乘子,求解上面那么方程,我们可以用梯度上升的方法进行求解。然而按照梯度上升的思想,如果我们对α1进行迭代更新的时候,我们需要固定除了α1以外的所有参数,然后对上面的式子进行求解偏导数。如果按照这种思路进行求解,我们发现约束等式变为:

根本无法对α1进行迭代更新,因此我们需要一次性选择两个参数进行更新,也就是我们想要对αi进行更新的时候,还要再选择αj,这样就有

上面的公式三个公式,便是我们得到的结果,接着我们的目的是要消去αi,然后得到只有变量αj方程式。

步骤1:有方程(2)我们可以知道那是一条直线,当yi 与yj 异号的时候,这个直线就相当于αi-αj=ξ,然后根据,这样可以得到如图所示的图解:

也就是说αj除了要在直线上之外,还要满足αj的取值点位于上面的正方形中。据此我们可以得到αj的取值范围:

其中上式中L、H的计算公式为:

这一步我们仅仅根据公式(2)(3)得到更精确的αj取值范围,上面得到的αj依旧可以在直线上移动,只要移动的范围满足公式(4)即可。

步骤2:把约束方程(2)写成:

然后代入方程(1),消去αi,然后根据梯度上升法,求取αj,可得求取公式:

其中:

因此我们最后的αj取值为:

因此如果求得αj,这个时候我们就可以求取αi了。

步骤3:更新αi,最简单的方法是直接把更新得到的αj代入公式(5),就可以了。当然还可以用下面的式子求取:

因为yi值为1或-1,因此最后的求解公式为:

到了这里,我们已经实现的了对αi、αj的优化更新。

步骤4:接着我们需要更新b值,使得其对于数据点i,j都满足kkt条件,我们知道在前面的推导中,我们知道如果更新后的αi满足0<αi<C,这个时候根据KKT条件满足yi*gi(xi)=1,因此我们最后b的更新公式为:

二、SMO算法实现

为了更为简单的学习SMO算法,我先从最简单,简化版的SMO算法,进行讲解,这样从简单到复杂,比较容易掌握。其实SMO算法的过程,只要根据上面的推导过程,代码一步一步的往下写,基本上没什么问题。

简化版SMO算法流程:

输入参数:训练数据点X,软约束参数C、迭代次数n

输出:W,b,拉格朗日乘子

1、初始化参数拉格朗日乘子α,b

2、循环迭代,直到满足最大迭代次数

{

(1)根据公式,计算W

(2)遍历每个数据点xi,根据以下公式,判断其对应的拉格朗日乘子是否可以被优化(不满足以下KKT条件):

如果不满足KKT条件,那么随机选择另外一个数据点j,及其对应的拉格朗日乘子αj,以αi、αj为一对,固定其它的α,对这两个参数进行优化,具体优化步骤如下:

a、计算αj 优化值,根据如下公式:

其中:

根据下面公式,计算αj的取值范围:

最后αj的最后更新值为:

b、根据计算更新的αj计算αi,计算公式如下:

c、更新计算直线的截距 b,计算公式如下:

}

简化版SMO编程实现:

from numpy import *
from matplotlib.pyplot import *
#文件读取函数
def readdata(filename):dataset=[];labelset=[];file=open(filename,'r');for line in file.readlines():linedata=line.strip().split('\t');dataset.append([linedata[0],linedata[1]]);labelset.append([linedata[2]])dataset=mat(dataset,float);labelset=mat(labelset,int);return dataset,labelset
#随机选择函数
def SelectionJ(i,m):j=iwhile j==i:j=int(random.uniform(0,m))return j
#根据约束条件,计算取值范围
def LH(labeli,labelj,alphai,alphaj,C):if labeli*labelj<0:L=max(0,alphaj-alphai);H=min(C,C+alphaj-alphai);else:L=max(0,alphai+alphaj-C)H=min(C,alphaj+alphai)return L,H
def smo(data,label,C,toler,maxiter):#参数初始化m,n=shape(data)b=0;alpha=mat(zeros([m,1]));fx=mat(zeros([m,n]))it=0;while it<maxiter:alphaPairsChanged = 0for j in range(n):fx[:,j]=multiply(multiply(alpha,label),data[:,j]);weight=fx.sum(axis=0);for i in range(m):fxi=weight*data[i,:].T+b#满足KKT条件:#1.label[i]*fxi>1  &&  alpa[i]==0#2.label[i]*fxi==1 &&  0<alpa[i]<C#3.label[i]*fxi<1  &&  alpa[i]=CEI=fxi-label[i];#定义EI,则EI*label[i]=fxi*label[i]-label[i]*label[i]=fxi*label[i]-1#根据定义的EI,可知根据符号 EI*label[i]与零比较,等价于上面的KKT条件#那么不满足KKT条件的为:#1、EI*label[i]>0  &&   alpa[i]>0    需要做优化#2、EI*label[i]==0 &&   这个时候数据点i位于边界上,不做优化处理#3、EI*label[i]<0  &&   alpa[i]<C    需要做优化if (EI*label[i]>toler and alpha[i]>0) or (EI*label[i]<-toler and alpha[i]<C):#alpa[i]不满足KKT,随机选择alpa[j]与alpa[i]进行优化,且i!=jj=SelectionJ(i,m);alphai_old=alpha[i].copy()#因为下面要开始更新参数,所以我们alphaj_old=alpha[j].copy()#深拷贝#计算更新alpha[j]的公式:alpha[j]:=alpha[j]-(EJ-EI)/eta;EJ=weight*data[j,:].T+b-label[j];eta=2*data[j,:]*data[i,:].T-data[i,:]*data[i,:].T-data[j,:]*data[j,:].Tif eta>=0:print 'eta' ;continue#必满足2xy-x^2-y^2>=0  等于零的时候,下面公式的分母为零,因此不能继续计算alpha[j]-=label[j]*(EI-EJ)/eta;#计算alpha[j]的取值范围L,HL,H=LH(label[i],label[j],alphai_old,alphaj_old,C)#根据公式alpha[j]范围,重新求取alpha[j],公式如下:#如果 alpha[j]>H      那么alpha[j]=H#如果 L<=alpha[j]<=H  那么不需要更新#如果 alpha[j]<L      那么alpha[j]=Lif alpha[j]>H:alpha[j]=Helif alpha[j]<L:alpha[j]=L#根据公式,更新alpha[i]alpha[i]+=label[i]*label[j]*(alphaj_old-alpha[j])#更新参数b 分别根据公式 计算b1、b2 并计算b值b1=b-EI-label[i]*(alpha[i]-alphai_old)*data[i,:]*data[i,:].T- \label[j]*(alpha[j]-alphaj_old)*data[i,:]*data[j,:].Tb2=b-EJ-label[j]*(alpha[i]-alphai_old)*data[i,:]*data[j,:].T- \label[j]*(alpha[j]-alphaj_old)*data[j,:]*data[j,:].Tif 0<alpha[i] and alpha[i]<C:b=b1;elif 0<alpha[j] and alpha[j]<C:b=b2else:b=(b1+b2)/2alphaPairsChanged += 1if (alphaPairsChanged == 0): it+= 1else: it= 0return alpha,b,weight
data,label=readdata("testSet.txt");
alpha,b,weight=smo(data,label,0.6,0.01,40)
print weight[0,0]
print weight[0,1]
y1=float((weight[0,0]*2+b)/(-weight[0,1]));
y2=float((weight[0,0]*8+b)/(-weight[0,1]));
plot([2,8],[y1,y2],'-')for i in range(len(label)):if label[i]<0:plot(data[i,0],data[i,1],'.y')elif label[i]>0:plot(data[i,0],data[i,1],'.b')
show()

分类结果

至此可以说算法已经完成了,然而简化版的SMO算法有很多问题,比如速度非常慢,因此接着我们就要讲解进化版的SMO算法。

机器学习(八)支持向量机svm终结篇相关推荐

  1. 机器学习实战 支持向量机SVM 代码解析

    机器学习实战 支持向量机SVM 代码解析 <机器学习实战>用代码实现了算法,理解源代码更有助于我们掌握算法,但是比较适合有一定基础的小伙伴.svm这章代码看起来风轻云淡,实则对于新手来说有 ...

  2. 机器学习之支持向量机SVM之python实现ROC曲线绘制(二分类和多分类)

    目录 一.ROC曲线 二.TP.FP.TN.FN 三. python绘制ROC曲线(二分类) 1.思路 2.关键代码 3.完整代码 四. python绘制ROC曲线(多分类) 五.参考文献 一.ROC ...

  3. 优达学城机器学习之--支持向量机(SVM)

    前言 SVM是支持向量机的简称(Support Vector Machine) 文章目录如下: 简述 选择分隔线 核函数(kernel)及其参数c, gamma 过拟合 over-fitting SV ...

  4. OpenCV之ml 模块. 机器学习:支持向量机(SVM)介绍 支持向量机对线性不可分数据的处理

    支持向量机(SVM)介绍 目标 本文档尝试解答如下问题: 如何使用OpenCV函数 CvSVM::train 训练一个SVM分类器, 以及用 CvSVM::predict 测试训练结果. 什么是支持向 ...

  5. 机器学习:支持向量机SVM的SVC和SVR

    支持向量机SVM SVM的工作原理及分类 支持向量机的原理 线性可分的SVM 非线性可分的支持向量机 支持向量机分类SVC 支持向量机回归SVR SVR原理 SVR模型 时间序列曲线预测 SVM的工作 ...

  6. 机器学习(七)支持向量机svm中级篇

    上一篇博文中我们得到的最后求解方程是: 接着我们将详解它的求解方法.这一步涉及到拉格朗日求解问题,有点难,建议如果想学这个问题是怎么求解的,先去好好学学拉格朗日的对偶问题求解. 一.数学基础知识复习: ...

  7. 机器学习(六)支持向量机svm初级篇

    为了理解svm算法,我这边以2位空间的点数据集分类为例,在二维空间中,直线的一般公式为:Ax+By+c=0:然后我们希望通过已有的数据点,求出直线的A,B,C三个参数,这就是SVM算法的目的. (1) ...

  8. [机器学习-实践]支持向量机(SVM)从例子代码中学习

    [机器学习-原理篇]支持向量机(SVM)深入理解 1.用SVM的linear做鸢尾花分类 利用sklearn中自带的dataset,鸢尾花数据库为例,进行二分类. #载入鸢尾花数据集,datasets ...

  9. 机器学习:支持向量机SVM原理与理解

    引言 --"举牌子:Support Vector Machines " 一直在犹豫要不要写SVM,因为网上已经有很多详细的SVM原理的解释甚至详细推导,而这东西又庞大复杂,想了解的 ...

最新文章

  1. 微软北大联合提出换脸 AI 和脸部伪造检测器,演绎现实版「矛与盾」?
  2. java web系统拆分_Java系统中如何拆分同步和异步
  3. PC网页实现九宫格切图功能
  4. spark Rdd 操作transformaction和action等
  5. 【报错笔记】 启动tomcat服务器报错Context initialization failed
  6. MATLAB实现多元线性回归预测
  7. 博士毕业论文英文参考文献换行_不用写毕业论文?一年制硕士真的不是闹着玩的吗...
  8. matlab设计模拟高通滤波器
  9. android imageview 等比例放大缩小,imageView的使用(进行原样的保持和按照比例的缩放:)...
  10. Linux设备驱动模型-Uevent
  11. SVN下载及语言包安装
  12. python字符编码(一看就懂)
  13. java文档生成器_最好用的数据库文档生成工具
  14. 计算机打印怎么取消,电脑怎么取消打印任务_打印机取消打印任务的详细步骤...
  15. Android TV 认证简介
  16. 2D游戏平滑的迷雾战争效果
  17. html多个子页显示在一个页面,html多个html页面嵌套在一起
  18. 有一种存储英文单词的方法,是把单词的所有字母串在一个单链表上。为了节省一点空间,如果有两个单词有同样的后缀,就让它们共享这个后缀。下图给出了单词“loading”和“being”的存储形式。
  19. mysql级联删除_近百道MySQL面试题和答案(2020收藏版)(完结篇)
  20. 【FFmpeg+Qt开发】转码流程 H.264 转(mov、mp4、avi、flv)等视频格式 示例详解

热门文章

  1. amaplocation无法获取高度_kali一款高度可定制的WiFi钓鱼工具 WiFiPhisher
  2. pythonrandom函数_python之random函数
  3. pythonprint中文教程_python中使用print输出中文的方法
  4. efcore 批量_EFCore批量操作内幕
  5. python两个一维数组合并_python:16.合并两个排序的链表
  6. visual studio 设计器不显示_设计模式 | Iterator设计模式
  7. php安装redis扩展报错,CentOS 67下php5+安装redis扩展组件
  8. 相同Ip 不同端口配置Nginx反向代理Apache
  9. 日常提高PHP运行效率的习惯
  10. 临死之前我要写一本《中国哲学史——以自然主义和人道主义的矛盾为视角》...