- 转载请注明作者和出处:http://blog.csdn.net/u011475210
- 代码地址:https://github.com/WordZzzz/ML/tree/master/Ch06
- 操作系统:WINDOWS 10
- 软件版本:python-3.6.2-amd64
- 编 者:WordZzzz
前言
SVM有很多实现,但我们只关注其中最流行的一种实现,即序列最小优化( Sequential MInimal Optimization,SMO )算法。
下面我们就开始讨论SMO算法,本篇博文先给出一个简化的版本,以便我们能够正确理解它的工作流程。
Platt的SMO算法
1996年,伟大的John Platt发布了一个称为SMO的强大算法,用于训练SVM。Platt的SMO算法是将大优化问题分解为多个小优化问题来求解的。这些小优化问题往往很容易求解,并且对它们进行顺序来求解的结果与将他们作为整体来求解的结果是完全一致的,但是求解时间却大大缩短。
SMO算法的目标是求出一系列alpha和b,一旦求出了这些alpha,就很容易计算出权重向量w并得到分隔超平面。
SMO的工作原理是:每次循环中选择两个alpha进行优化处理。一旦找到一对合适的alpha,那么就增大其中一个同时减小另一个。这里所谓的“合适”就是指两个alpha必须要符合一定的条件,条件之一就是这两个alpha必须要在间隔边界之外,另一个条件则是这两个alpha还没有进行过区间化处理或者不在边界上。
应用简化版SMO算法处理小规模数据集
Platt SMO算法中的外循环确定要优化的最佳alpha对。而简化版会跳过这一部分,首先在数据集上遍历每一个alpha,然后在剩下的alpha集合中随机选择另一个alpha来构成alpha对。这里有一点相当重要,就是我们要同时改变两个alpha,因为我们需要满足一个约束条件:
1 | $$ |
由于改变一个alpha可能会导致该约束条件失效,因为需要同时改变两个alpha,一增一减,改变的量相同。
在实现简化版SMO之前,我们需要先构造几个辅助函数。打开文本编辑器,将下面的代码加入svmMLiA.py中。
1 | #!/usr/bin/env python |
首先是我们熟悉的老哥loadDataSet(),用来打开文件并对其进行解析,从而得到每行的类别标签和整个数据矩阵;然后是selectJrand(),用来随机选择第二个alpha的下标(只要和第一个alpha下标不一样就行);最后一个是clipAlpha()函数,用于设定阈值,限制alpha的值。
1 | reload(svmMLiA) |
简化版SMO伪代码:
1 | 创建一个alpha向量并将其初始化为0向量 |
下述代码是SMO算法中的一个有效版本,如果看不懂,可以先找SVM的公式推导看看。打开文本编辑器,将下面的代码加入svmMLiA.py中。
1 | def smoSimple(dataMatIn, classLabels, C, toler, maxIter): |
运行结果如下:
1 | reload(svmMLiA) |
上述过程可能需要几分钟才会收敛,一旦运行结束,我们就可以对结果进行查看:
1 | b |
由于SMO算法的随机性,每次运行之后得到的结果不尽相同。alphas[alphas > 0]命令是数组过滤的一个实例,得到仅仅包含大于0的值的矩阵,而且它只对NumPy类型有用,却并不适用于Python中的正则表。
我们在数据集上把这些支持向量画出来:
希望通过本篇博文,大家对SMO的工作流程有了一定得了解,至于完成版的SMO,WordZzzz将会在下一篇博文介绍给大家。
系列教程持续发布中,欢迎订阅、关注、收藏、评论、点赞哦~~( ̄▽ ̄~)~
完的汪(∪。∪)。。。zzz