统计学习方法c++实现之六 支持向量机(SVM)及SMO算法
前言
支持向量机(SVM)是一种很重要的机器学习分类算法,本身是一种线性分类算法,但是由于加入了核技巧,使得SVM也可以进行非线性数据的分类;SVM本来是一种二分类分类器,但是可以扩展到多分类,本篇不会进行对其推导一步一步罗列公式,因为当你真正照着书籍进行推导后你就会发现他其实没那么难,主要是动手。本篇主要集中与实现,即使用著名的序列最小最优化(SMO)算法进行求解,本篇实现的代码主要参考了Platt J. Sequential minimal optimization: A fast algorithm for training support vector machines[J]. 1998.这是SMO的论文,论文中详细解释了如何使用SMO算法,还有伪代码,我的C++程序就是根据伪代码实现的(没错,SMO算法我推不出来)。代码地址.
对于SVM的一些理解
首先,《统计学习方法》中对于SVM的讲解已经很好了,请务必跟着一步一步推导,这样你就会发现整个SVM的推导过程无非就是以下几步:
- 将分类器建模成n维空间中的超平面,但是这个超平面有个很重要的选取原则,那就是让所有样本点到超平面的距离都尽量大,也就是让距离超平面最近的点到超平面的距离达到最大,于是得出了约束最大化问题。
- 将问题简化到只和决定超平面的参数w有关,使用熟悉的拉格朗日数乘法将约束最优化问题变成一个式子,然后转化为对偶问题。
- 求解对偶问题的最优解a,然后根据原问题和对偶问题的关系由a求出w,此时就得到SVM的参数了。
1,2步都是需要推导的,唯独涉及实现的地方是第3步,我们实现的重点变成了如何快速的得到最优解a(a可是有N个分量的,N为训练样本数)。于是SMO算法就出现了。
再者关于核函数,之前看博客,有人理解成核函数是一种映射,即将非线性问题映射为线性问题,有人评论说这是不严谨的,核函数不是一种映射,当时很迷茫,但是现在看来,核函数是一种技巧,他让我们可以使用目前空间的内积来代表某个目标空间的内积。
具体的关于SVM的推导和核技巧的理解查看书籍就可以,自己推导一遍就都明白了。
序列最小最优化(SMO)算法
《统计学习方法》上对于SMO算法的讲解很清楚(跟原论文思路一样),就是将待优化的n个参数选两个作为优化对象,其他的固定,然后转化为二元最优化问题。道理我都懂,但是实现的时候遇到了很多麻烦,关键在于启发式的变量选取,于是便找到原论文,没想到Platt大神已经把伪代码写好了,于是,我就把他的伪代码用c++实现了一遍。这部分我对一些推导还是不明白,在这里就不献丑了,看代码吧,首先给出论文中的伪代码截图。
代码结构
c++实现
这部分主要列出伪代码的takestep部分各变量的更新代码。
int SVM::SMOTakeStep(int& i1, int& i2) {
//变量名跟伪代码中基本一样,这里用i1, i2代表数据点对应的的拉格朗日乘子,E每个样本点的预测输出与真值的误差
//存储在vector中,避免重复计算
...
...
...
double a1 = alpha[i1] + s * (alpha[i2] - a2);
double b1;
//please notice that the update equation is from <<统计学习方法>>p130, not the equation in paper
b1= -E[i1] - y1 * (a1 - alpha[i1]) * kernel(trainDataF[i1], trainDataF[i1]) -
y2 * (a2 - alpha[i2]) * kernel(trainDataF[i1], trainDataF[i2]) + b;
double b2;
b2 = -E[i2] - y1 * (a1 - alpha[i1]) * kernel(trainDataF[i1], trainDataF[i2]) -
y2 * (a2 - alpha[i2]) * kernel(trainDataF[i2], trainDataF[i2]) + b;
double bNew = (b1 + b2) / 2;
b = bNew;
w = w + y1 * (a1 - alpha[i1]) * trainDataF[i1] + y2 * (a2 - alpha[i2]) *
trainDataF[i2];
//this is the linear SVM case, this equation are from the paper equation 22
alpha[i1] = a1;
alpha[i2] = a2;
// vector<double> wtmp (indim);
// for (int i=0; i<trainDataF.size();++i)
// {
// auto tmp = alpha[i]*trainDataF[i]*trainDataGT[i];
// wtmp = wtmp+tmp;
// }
// w = wtmp;
E[i1] = computeE(i1);
E[i2] = computeE(i2);
return 1;
特别注意b的计算公式,这里被坑了好久,原论文的计算b1 ,b2的公式全是正号,因为论文中svm的超平面公式是\(wx-b\),这与书上的公式不同,所以导致我的算法一直不收敛,最后从头看论文才发现...
其他的实现都在这里,如果有问题欢迎交流。
统计学习方法c++实现之六 支持向量机(SVM)及SMO算法的更多相关文章
- 支持向量机原理(四)SMO算法原理
支持向量机原理(一) 线性支持向量机 支持向量机原理(二) 线性支持向量机的软间隔最大化模型 支持向量机原理(三)线性不可分支持向量机与核函数 支持向量机原理(四)SMO算法原理 支持向量机原理(五) ...
- SVM之SMO算法(转)
支持向量机(Support Vector Machine)-----SVM之SMO算法(转) 此文转自两篇博文 有修改 序列最小优化算法(英语:Sequential minimal optimizat ...
- 每月学习数理统计--《统计学习方法—李航》(3): SVM
1. SVM的最优化问题 2.拉格朗日乘数法,对偶条件KKT条件 3.软件隔支持向量机 4.非线性支持向量机,核函数 5.SMO算法 1. SVM的最优化问题 支持向量机(Support Vector ...
- 支持向量机(Support Vector Machine)-----SVM之SMO算法(转)
此文转自两篇博文 有修改 序列最小优化算法(英语:Sequential minimal optimization, SMO)是一种用于解决支持向量机训练过程中所产生优化问题的算法.SMO由微软研究院的 ...
- ML-求解 SVM 的SMO 算法
这算是我真正意义上认真去读的第一篇ML论文了, but, 我还是很多地方没有搞懂, 想想, 缓缓吧, 还是先熟练调用API 哈哈 原论文地址: https://www.microsoft.com/en ...
- 统计学习:线性可分支持向量机(SVM)
模型 超平面 我们称下面形式的集合为超平面 \[\begin{aligned} \{ \bm{x} | \bm{a}^{T} \bm{x} - b = 0 \} \end{aligned} \tag{ ...
- 《统计学习方法》笔记(8):AdaBoost算法
AdaBoost是最有代表性的提升算法之一.其基本思想可以表述为:多个专家的综合判断,要优于任意一个专家的判断. 1.什么是提升算法? "装袋"(bagging)和"提升 ...
- 《统计学习方法》笔记(9):EM算法和隐马尔科夫模型
EM也称期望极大算法(Expectation Maximization),是一种用来对含有隐含变量的概率模型进行极大似然估计的迭代算法.该算法可应用于隐马尔科夫模型的参数估计. 1.含有隐含参数的概率 ...
- 一步步教你轻松学支持向量机SVM算法之案例篇2
一步步教你轻松学支持向量机SVM算法之案例篇2 (白宁超 2018年10月22日10:09:07) 摘要:支持向量机即SVM(Support Vector Machine) ,是一种监督学习算法,属于 ...
随机推荐
- Django商城项目笔记No.8用户部分-注册接口实现
Django商城项目笔记No.8用户部分-注册接口实现 users的view.py中增加如下代码 class RegisterUserView(CreateAPIView): "" ...
- 博客系统实战——SprintBoot 集成Thymeleaf 实现用户增删查改(含源码)
近来在学习SprintBoot +Thymeleaf +Maven搭建自己的博客系统,故在学习过程中在此记录一下,也希望能给广大正在学习SprintBoot和Thymeleaf的朋友们一个参考. 以下 ...
- ES6对抽象工厂模式与策略模式结合的实践
这段代码是我在学习了java版的抽象工厂模式后,实现的ES6版抽象工厂,后期大幅修改,加入了策略模式,看起来很多逻辑看似繁琐,不必要写这么多,但是为了练习设计模式,所以才这样做.当所需的工厂种类增多后 ...
- BZOJ3676:[APIO2014]回文串(SAM,Manacher)
Description 考虑一个只包含小写拉丁字母的字符串s.我们定义s的一个子串t的“出 现值”为t在s中的出现次数乘以t的长度.请你求出s的所有回文子串中的最 大出现值. Input 输入只有一行 ...
- docker中使用的镜像加速器可以自己生成
只要你到该网址https://cr.console.aliyun.com/cn-hangzhou/mirrors登录(我使用的是支付宝帐号),然后你如下图操作,就能够看见你的加速器地址了,只要你登录就 ...
- ERC: Claim Holder #735 status:Discussion
EIP: Title: Claim Holder Author: Fabian Vogelsteller (@frozeman) Type: Standard Category: ERC Status ...
- linux服务器关闭ipv6 方法
第一个文件: /etc/sysconfig/network 第二个文件:如无此文件,vim添加 /etc/modprobe.d/disable_ipv6.conf
- WorldWind源码剖析系列:经纬度格网类LatLongGrid
经纬度格网类LatLongGrid继承自可渲染对象类RenderableObject,是WorldWind中用来在星球外表绘制经纬度格网的封装类.其类图如下所示. 绘制经纬网格的主体函数为Render ...
- ubuntu16.04下的htk安装编译
HTK(HMM Tools Kit)是一个剑桥大学开发的专门用于建立和处理HMM的实验工具包[1],主要应用于语音识别领域,也可以应用于语音合成.字符识别和DNA排序等领域.HTK经过剑桥大学.Ent ...
- visual studio 插件
一:VS10x Code Map(打开后台cs文件,插件列出了所有的字段.方法,方便当代码行多的时候查找,提升工作效率) 1:下载 https://marketplace.visualstudio.c ...