统计学习方法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) ,是一种监督学习算法,属于 ...
随机推荐
- FinalShell使用---Xshell的良心国产软件
最近发现了一款同类产品FinalShell,还是一块良心国货.初步体验了一下,确实是良心之作.且免费(通用版),支持国货. FinalShell是一体化的的服务器,网络管理软件,不仅是ssh客户端,还 ...
- MySQL基础之 AUTO_INCREMENT
AUTO_INCREMENT AUTO_INCREMENT是mysql唯一扩展的完整性约束,当为数据库表中插入新纪录时,字段上的值会自动生成唯一的ID,再具体设置AUTO_INCREMENT约束时,一 ...
- Alpha冲刺报告(11/12)(麻瓜制造者)
今日已完成 邓弘立: 整合了主页的功能 符天愉: 大致上完成了留言部分的添加,删除,查询功能 江郑: 测试了剩余四个查询,一个添加接口,也搞定了接口说明. 刘双玉: 测试了剩余四个查询,一个添加接口, ...
- digital ocean 内存不足时增加swap文件的方法
买了比较低配的digitalocean 云主机,在执行composer update的时候出现内存不足的问题,但是内存大小已经固定了,除非加钱,还有别的方法吗? 有,增加swap分区,这样就可以弥补内 ...
- 原生js返回顶部(匀速、由快到慢)
在项目中我们经常有需求要求页面滚动到一定位置时出现返回顶部按钮,点击即返回顶部. 方法一: 锚点,这是最简单的.(a标签的href属性等于一直要到达位置元素的id值) 方法二: js直接给页面根节点设 ...
- php可逆加密解密
函数: function encrypt($data, $key) { $prep_code = serialize($data); $block = mcrypt_get_block_size('d ...
- 服务器 一 MQTT服务器硬件
目的: 实现手机4G网络控制单片机,需要搭建服务器,手机或者各种控制端远程控制. 本教程 1 MQTT服务器硬件模块 2 MQTT服务器电脑搭建 2.1自己搭建 2.2租阿里云服务器 2 MQTT服 ...
- pyspider爬取数据存入redis--1.安装驱动
首先安装pyredis的驱动 wget https://pypi.python.org/packages/source/r/redis/redis-2.9.1.tar.gz 解压并cd python ...
- HDU 3072 Intelligence System(tarjan染色缩点+贪心+最小树形图)
Intelligence System Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Othe ...
- neo4j用collect 代替union 并实行分页
MATCH pa=(j:User)-[r:PostLikeRel|:ReplyRel|:RetweetRel]->(m:User{guid:"f092a1dc6c23b26b020bd ...