SVM算法计算到后面是一个带约束条件的优化问题
这里的SMO(Sequential Minimal Optimization)序列最小化算法就是一个二次规划优化算法,可以用来解决上面的问题。SMO算法是由John C.Platt在1998年提出的。SMO算法的目标就是求出一些列的alpha和b,一旦求出这些alpha,就可以计算出权重向量,并求出分割超平面。SMO算法的工作原理是:每次循环中选择两个alpha进行优化处理。一旦找到一对合适的alpha,那么就增大其中一个,同时减少另一个。那么为什么每次都要选择两个alpha进行优化呢,我们可以看到以上公式中有一个约束条件:
因此,如果只改变其中一个alpha,那么这个约束条件就无法满足,因此需要选择2个alpha同时进行优化,并且增大其中一个,另一个也要减小相同的大小。这里选择alpha的方式采用启发方式,具体步骤:先通过外循环来选择第一个alpha,选择过程会在两种方式下交替:一种方式是在所有数据集上进行单遍扫描,另一种是在非边界alpha中实现单遍扫描,这里的非边界alpha是指大于0小于C的alpha的值,这里的C是自己设定的,之后,在选择完第一个alpha后,算法会通过一个内循环来选择第二个alpha,通过最大步长的方式来选择第二个alpha,假设Ej是Xj的估计值与实际值的误差,j是第二个alpha的编号,i是第一个alpha的编号,那么则选取Ei-Ej最大的那个alpha来作为第二个优化的值。
代码如下:
首先,定义一个类:
class optStruct:
def __init__(self,dataMatIn, classLabels, C, toler): # 构造函数
self.X = dataMatIn
self.labelMat = classLabels
self.C = C
self.tol = toler
self.m = shape(dataMatIn)[0]
self.alphas = mat(zeros((self.m,1)))
self.b = 0
self.eCache = mat(zeros((self.m,2))) #用于存储误差E
<span style="white-space:pre"> </span>self.K = mat(zeros((self.m,self.m)))#计算向量经过核函数的值
for i in range(self.m):