SVM算法实现(一)

关键字(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<C则是不满足的,而原本ai=C
yiui>=1可是ai>0则是不满足的而原本ai=0
yiui=1可是ai=0或者ai=C则表明不满足的,而原本应该是0<ai<C
所以要找出不满足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<alpha < C (在边界上的支持向量)
* 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下载地址上提供下载。

点击这里下载

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

我的邮箱:[email protected]

我的其它博客:

百度:http://hi.baidu.com/futrueboy/home

javaeye:http://futrueboy.javaeye.com/

CSDN: http://blog.csdn.net/techq

时间: 2024-10-14 05:51:36

SVM算法实现(一)的相关文章

SVM算法

摘要:SVM(支持向量机)算法是一种典型的监督式学习算法.介绍SVM算法的思想和应用. 关键词:机器学习   SVM    支持向量机 SVM(Support Vector Machine)支持向量机,简称SV机,一种监督式学习算法,广泛地应用于统计分类和回归分析中. SVM算法的思想可以概括为两点. 第一点:SVM是针对线性可分情况进行分析,对于线性不可分的情况,通过使用非线性映射算法将低维输入空间线性不可分的样本映射到高维特征空间使其线性可分,从而使得高维特征空间采用采用线性算法对样本的非线

SVM算法推导

1,SVM算法的思考出发点 SVM算法是一种经典的分类方法.对于线性可分问题,找到那个分界面就万事大吉了.这个分界面可以有很多,怎么找呢?SVM是要找到最近点距离最远的那个分界面.有点绕,看下面的图就明白了 为了推导简单,我们先假设样本集是完全线性可分的,也就一个分界面能达到100%的正确率. 2,线性可分的情况 (1)优化目标的建立 最近点距离最远的分界面,这句话得用数学式子表示出来,这样才能用数学工具进行求解. 首先,假设分界面是y=wx+b,点\(x_i\)距离平面的距离用数学表达是\(\

机器学习笔记—svm算法(上)

本文申明:本文原创,如转载请注明原文出处. 引言:上一篇我们讲到了logistic回归,今天我们来说一说与其很相似的svm算法,当然问题的讨论还是在线性可分的基础下讨论的. 很多人说svm是目前最好的分类器,那我们就来看看我们的svm好在哪里. 一:初识svm 问题:用一条直线把下图的圆球和五角星分离开来. 解答:有N种分法,如下图: 附加题:找出最佳分类? 解答:如图: Exe me?鬼知道哪一条是最佳?? 等等这个最佳分类是不是等价于,地主让管家给两个儿子分地,是不是只要让两家之间一样多就可

程序员训练机器学习 SVM算法分享

http://www.csdn.net/article/2012-12-28/2813275-Support-Vector-Machine 摘要:支持向量机(SVM)已经成为一种非常受欢迎的算法.本文主要阐述了SVM是如何进行工作的,同时也给出了使用Python Scikits库的几个示例.SVM作为一种训练机器学习的算法,可以用于解决分类和回归问题,还使用了kernel trick技术进行数据的转换,再根据转换信息在可能的输出之中找到一个最优的边界. [CSDN报道]支持向量机(Support

python 实现 svm算法

svm算法,说到底就是二次优化问题. 带有约束的二次优化问题. 1.线性优化问题,课件Leture5-QP 参考 https://www.coin-or.org/PuLP/CaseStudies/a_blending_problem.html python代码: # problemdef qp_test1(): prob = LpProblem("qp_test1", LpMinimize) x1 = LpVariable("x1", 0, None, LpInte

从Loagistic 到 SVM算法

SVM(支持向量机),一种二类分类器,之所以称之为向量机,是因为它本身就产生一个二值决策结果,即使一种决策"机",支持向量机的泛化错误低(具有结构风险最小),具有很强的学习能力,因此很多人认为它是最好的监督学习算法. SVM与Logistic回归的联系: logistic回归的目的就是从特征值中学习出一个0/1分类模型.而这个模型的输入是将特征的线性组合作为自变量,由于sigmod函数的自变量具有从负无穷到正无穷的输入范围,因此它可以把任何一个输入映射到0/1 sigmod函数的形式化

SVM算法入门

转自:http://blog.csdn.net/yangliuy/article/details/7316496SVM入门(一)至(三)Refresh 按:之前的文章重新汇编一下,修改了一些错误和不当的说法,一起复习,然后继续SVM之旅. (一)SVM的简介 支持向量机(Support Vector Machine)是Cortes和Vapnik于1995年首先提出的,它在解决小样本.非线性及高维模式识别中表现出许多特有的优势,并能够推广应用到函数拟合等其他机器学习问题中[10]. 支持向量机方法

转载:scikit-learn学习之SVM算法

转载,http://blog.csdn.net/gamer_gyt 目录(?)[+] ====================================================================== 本系列博客主要参考 Scikit-Learn 官方网站上的每一个算法进行,并进行部分翻译,如有错误,请大家指正 转载请注明出处,谢谢 =====================================================================

Spark MLlib SVM算法

1.1 SVM支持向量机算法 支持向量机理论知识参照以下文档: 支持向量机SVM(一) http://www.cnblogs.com/jerrylead/archive/2011/03/13/1982639.html 支持向量机SVM(二) http://www.cnblogs.com/jerrylead/archive/2011/03/13/1982684.html 支持向量机(三)核函数 http://www.cnblogs.com/jerrylead/archive/2011/03/18/

scikit-learn学习之SVM算法

====================================================================== 本系列博客主要参考 Scikit-Learn 官方网站上的每一个算法进行,并进行部分翻译,如有错误,请大家指正 转载请注明出处,谢谢 ====================================================================== 机器学习中的算法(2)-支持向量机(SVM)基础 关于SVM一篇比较全介绍的博文