关键字(keywords):SVM 支持向量机 SMO算法 实现 机器学习

假设对SVM原理不是非常懂的,能够先看一下入门的视频,对帮助理解非常实用的,然后再深入一点能够看看这几篇入门文章,作者写得挺具体,看完以后SVM的基础就了解得差点儿相同了,再然后买本《支持向量机导论》作者是Nello Cristianini 和 John Shawe-Taylor,电子工业出版社的。然后把书本后面的那个SMO算法实现就基本上弄懂了SVM是怎么一回事,最后再编写一个SVM库出来,比方说像libsvm等工具使用,呵呵,差点儿相同就这样。这些是我学习SVM的整个过程,也算是经验吧。

以下是SVM的简化版SMO算法,我将结合Java代码来解释一下整个SVM的学习训练过程,即所谓的train训练过程。那么什么是SMO算法呢?

SMO算法的目的无非是找出一个函数f(x),这个函数能让我们把输入的数据x进行分类。既然是分类肯定须要一个评判的标准,比方分出来有两种情况A和B,那么怎么样才干说x是属于A类的,或不是B类的呢?就是须要有个边界,就好像两个国家一样有边界,假设边界越明显,则就越easy区分,因此,我们的目标是最大化边界的宽度,使得很easy的区分是A类还是B类。

在SVM中,要最大化边界则须要最小化这个数值:

w:是參量,值越大边界越明显

C代表惩处系数,即假设某个x是属于某一类,可是它偏离了该类,跑到边界上后者其它类的地方去了,C越大表明越不想放弃这个点,边界就会缩小

代表:松散变量

但问题似乎还不好解,又由于SVM是一个凸二次规划问题,凸二次规划问题有最优解,于是问题转换成下列形式(KKT条件):

…………(1)

这里的ai是拉格朗日乘子(问题通过拉格朗日乘法数来求解)

对于(a)的情况,表明ai是正常分类,在边界内部(我们知道正确分类的点yi*f(xi)>=0)

对于(b)的情况,表明了ai是支持向量,在边界上

对于(c)的情况,表明了ai是在两条边界之间

而最优解须要满足KKT条件,即满足(a)(b)(c)条件都满足

下面几种情况出现将会出现不满足:

yiui<=1可是ai

yiui>=1可是ai>0则是不满足的而原本ai=0

yiui=1可是ai=0或者ai=C则表明不满足的,而原本应该是0

所以要找出不满足KKT的这些ai,并更新这些ai,但这些ai又受到另外一个约束,即

因此,我们通过还有一个方法,即同一时候更新ai和aj,满足下面等式

就能保证和为0的约束。

利用yiai+yjaj=常数,消去ai,可得到一个关于单变量aj的一个凸二次规划问题,不考虑其约束0<=aj<=C,能够得其解为:

 ………………………………………(2)

这里

………………(3)

表示旧值,然后考虑约束0<=aj<=C可得到a的解析解为:

…………(4)

对于

那么怎样求得ai和aj呢?

对于ai,即第一个乘子,能够通过刚刚说的那几种不满足KKT的条件来找,第二个乘子aj能够找满足条件

…………………………………………………………………………(5)

b的更新:

在满足条件:

下更新b。……………(6)

最后更新全部ai,y和b,这样模型就出来了,然后通过函数:

……………………………………………………(7)

输入是x,是一个数组,组中每个值表示一个特征。

输出是A类还是B类。(正类还是负类)

下面是基本的代码段:

/*

* 默认输入參数值

* C: regularization parameter

* tol: numerical tolerance

* max passes

*/

double C = 1; //对不在界内的惩处因子

double tol = 0.01;//容忍极限值

int maxPasses = 5; //表示没有改变拉格朗日乘子的最多迭代次数

/*

* 初始化a[], b, passes

*/

double a[] = new double[x.length];//拉格朗日乘子

this.a = a;

//将乘子初始化为0

for (int i = 0; i < x.length; i++) {

a[i] = 0;

}

int passes = 0;

while (passes < maxPasses) {

//表示改变乘子的次数(基本上是成对改变的)

int num_changed_alphas = 0;

for (int i = 0; i < x.length; i++) {

//表示特定阶段由a和b所决定的输出与真实yi的误差

//參照公式(7)

double Ei = getE(i);

/*

* 把违背KKT条件的ai作为第一个

* 满足KKT条件的情况是:

* yi*f(i) >= 1 and alpha == 0 (正确分类)

* yi*f(i) == 1 and 0

* yi*f(i) <= 1 and alpha == C (在边界之间)

*

*

*

* ri = y[i] * Ei = y[i] * f(i) - y[i]^2 >= 0

* 假设ri < 0而且alpha < C 则违反了KKT条件

* 由于原本ri < 0 应该相应的是alpha = C

* 同理,ri > 0而且alpha > 0则违反了KKT条件

* 由于原本ri > 0相应的应该是alpha =0

*/

if ((y[i] * Ei < -tol && a[i] < C) ||

(y[i] * Ei > tol && a[i] > 0))

{

/*

* ui*yi=1边界上的点 0 < a[i] < C

* 找MAX|E1 - E2|

*/

int j;

/*

* boundAlpha表示x点处于边界上所相应的

* 拉格朗日乘子a的集合

*/

if (this.boundAlpha.size() > 0) {

//參照公式(5)

j = findMax(Ei, this.boundAlpha);

} else

//假设边界上没有,就随便选一个j != i的aj

j = RandomSelect(i);

double Ej = getE(j);

//保存当前的ai和aj

double oldAi = a[i];

double oldAj = a[j];

/*

* 计算乘子的范围U, V

* 參考公式(4)

*/

double L, H;

if (y[i] != y[j]) {

L = Math.max(0, a[j] - a[i]);

H = Math.min(C, C - a[i] + a[j]);

} else {

L = Math.max(0, a[i] + a[j] - C);

H = Math.min(0, a[i] + a[j]);

}

/*

* 假设eta等于0或者大于0 则表明a最优值应该在L或者U上

*/

double eta = 2 * k(i, j) - k(i, i) - k(j, j);//公式(3)

if (eta >= 0)

continue;

a[j] = a[j] - y[j] * (Ei - Ej)/ eta;//公式(2)

if (0 < a[j] && a[j] < C)

this.boundAlpha.add(j);

if (a[j] < L)

a[j] = L;

else if (a[j] > H)

a[j] = H;

if (Math.abs(a[j] - oldAj) < 1e-5)

continue;

a[i] = a[i] + y[i] * y[j] * (oldAj - a[j]);

if (0 < a[i] && a[i] < C)

this.boundAlpha.add(i);

/*

* 计算b1, b2

* 參照公式(6)

*/

double b1 = b - Ei - y[i] * (a[i] - oldAi) * k(i, i) - y[j] * (a[j] - oldAj) * k(i, j);

double b2 = b - Ej - y[i] * (a[i] - oldAi) * k(i, j) - y[j] * (a[j] - oldAj) * k(j, j);

if (0 < a[i] && a[i] < C)

b = b1;

else if (0 < a[j] && a[j] < C)

b = b2;

else

b = (b1 + b2) / 2;

num_changed_alphas = num_changed_alphas + 1;

}

}

if (num_changed_alphas == 0) {

passes++;

} else

passes = 0;

}

return new SVMModel(a, y, b);

执行后的结果还算能够吧,測试数据主要是用了libsvm的heart_scale的数据。

预測的正确率达到73%以上。

假设我把核函数从线性的改为基于RBF将会更好点。

最后,说到SVM算法实现包,应该有非常多,包含svm light,libsvm,有matlab本身自带的svm工具包等。

另外,完整的代码,我将上传到CSDN下载地址上提供下载。

如理解有误敬请指正!谢谢!

我的其它博客:

svm算法 java实现_SVM算法实现(一)相关推荐

  1. JAVA分析html算法(JAVA网页蜘蛛算法)

    近来有些朋友在做蜘蛛算法,或者在网页上面做深度的数据挖掘.但是遇到复杂而繁琐的html页面大家都望而却步.因为很难获取到相应的数据. 最古老的办法的是尝试用正则表达式,估计那么繁琐的东西得不偿失,浪费 ...

  2. 特征选择算法java实现_relief算法特征选择

    1.[文件] Relief算法程序.txt ~ 6KB 下载(44) package com.relief.algorithm; import java.util.Random; import jav ...

  3. 算法 | Java 常见排序算法(纯代码)

    目录 汇总 1. 冒泡排序 1. 冒泡排序 每轮循环确定最值: public void bubbleSort(int[] nums) { int temp; boolean isSort = fals ...

  4. java实现棋盘覆盖算法,java 棋盘覆盖算法

    import java.util.Scanner; /** 棋盘覆盖 */ public class Arithmetic { /** 被覆盖后显示的数字,会根据覆盖的顺序有所递增 */ privat ...

  5. bm25算法Java代码_BM25算法在Lucene中的应用

    Lucene是apache软件基金会jakarta项目组的一个子项目,是一个用Java写的全文检索引擎工具包,可以方便的集成到系统中提以提供高效的检索能力,Lucene核心功能分为建索和检索两部分.而 ...

  6. 数据结构及算法 | Java数据结构——回溯算法之子集树

    1.介绍一下子集树,什么是子集树? 当所给问题是从n个元素的集合S中找出满足某些条件或者性质的子集时,解空间是子集树: 比如典型的0-1背包问题-----and-----轮船装载问题: 解空间 就是指 ...

  7. l bfgs算法java代码_L-BFGS算法介绍

    本文由作者林洋港授权网易云社区发布. 一. L-BFGS是什么 L-BFGS是解无约束非线性规划问题最常用的方法,具有收敛速度快.内存开销少等优点,在机器学习各类算法中常有它的身影.简单的说,L-BF ...

  8. 通过网页查看服务器算法,java分析html算法(java网页蜘蛛算法示例)

    遇到复杂而繁琐的html页面大家都望而却步.因为很难获取到相应的数据. 最古老的办法的是尝试用正则表达式,估计那么繁琐的东西得不偿失,浪费我们宝贵的时间. 第二个办法用开源组织htmlparser的包 ...

  9. java md5算法,JAVA实现MD5算法

    该楼层疑似违规已被系统折叠 隐藏此楼查看此楼 package org.zcq100.Other; public class MD5 { static final int S11 = 8; static ...

最新文章

  1. ocr 超时小票识别_【FreeOCR(文字扫描识别软件)和小票打印机测试工具哪个好用】FreeOCR(文字扫描识别软件)和小票打印机测试工具对比-ZOL下载...
  2. SQL Server中 sysobjects、syscolumns、systypes
  3. C#网络编程(基本概念和操作) - Part.1[转自JimmyZhang博客]
  4. java判断对象已经被回收_Java中JVM判断对象已死的基本算法分析
  5. [设计模式-行为型]迭代器模式(Iterator)
  6. linux查看磁盘io性能
  7. 手机端仿ios的银行下拉脚本五
  8. php carbon,laravel Carbon函数
  9. @Value(#{})与@Value(${})的区别
  10. 设置y轴刻度_Origin中如何设置坐标轴单位长度相等? axisisometric
  11. PADS2007快捷键、无模命令大全
  12. java练习项目 拼图游戏
  13. 小白软件测试入门基础--测试用例
  14. 电气潮流运算Matlab怎么编程,基于Matlab的电力系统潮流编程计算
  15. 4.2 Ansible中的常用模块
  16. ColorPicker一款安卓取色器,模仿ps取色板
  17. round( )函数:四舍五入
  18. 在VMware Horizo​​n DaaS中的租户设备上重新初始化fdb和edb
  19. Java游戏 斗地主
  20. Office2016的PPT放映幻灯片放映卡死解决方法

热门文章

  1. C#LeetCode刷题之#345-反转字符串中的元音字母​​​​​​​(Reverse Vowels of a String)
  2. Anaconda简介:它是什么,以及如何安装
  3. 自然语言处理实践Task2
  4. PLSQL Developer 安装与配置
  5. Python网络编程——socket套接字实现UDP/TCP信息传输
  6. Java基础语法初学者了解
  7. 我的在win10下安装tensorflow的过程
  8. VS2010新建Web网站与新建Web应用程序的区别
  9. 《scikit-learn》交叉验证
  10. 漫步数学分析十五——连续