支持向量机是我学习机器学习时期最重要的分类算法(没有之一),但是每次都似懂若无的感觉。其中用到了间隔最大化、对偶问题求解等等步骤。其中,支持向量机的学习问题可以形式化为求解凸二次规划问题,有许多最优化算法可以用于这个问题求解。当样本容量很大时,这些方法往往变得非常低效。本章还涉及支持向量机的最优化求解方法。
==================================================================
序列最小最优算法(sequential minimal optimization,SMO)是一种启发式方法,其基本思路是:如果所有变量的解都满足此最优化问题的KKT条件,那么这个最优化问题的解就得到了。因为KKT条件是该优化问题的充分必要条件。否则,选择两个变量,固定其他变量,针对这两个变量构建一个二次规划问题,这个二次规划问题关于这两个变量的解应该更接近原始二次规划问题的解,因为这会使得原始二次规划问题的目标函数值变得更小。
整个SMO算法包括两个部分:求解两个变量二次规划的解析方法和选择变量的启发式方法。
——李航《统计学习方法》
1.简化版的SMO
原版SMO算法需要在外循环确定要优化的alpha对。简化版的SMO首先在数据集上遍历每一个alpha,然后在剩下的alpha中随机选择另一个alpha,构建alpha对。
+++++++++++++++++++++++++++++++++++++++++
简化版的SMO的伪代码如下:
创建一个alpha向量并将其初始化为0向量
当迭代次数下去最大迭代次数时(外循环):
对数据集中的每个数据向量(内循环):
如果该数据向量可以被优化:
随机选择另外一个数据向量
同时优化这两个向量
如果这两个向量都不能被优化,退出内循环
如果所有向量都没被优化,增加迭代数目,继续下一次循环
+++++++++++++++++++++++++++++++++
辅助函数:
from numpy import *
def loadDataSet(filename):
dataMat=[]
labelMat=[]
fr=open(filename)
for line in fr.readlines():
lineArr=line.strip().split('\t')
dataMat.append([float(lineArr[0]),float(lineArr[1])])
labelMat.append(float(lineArr[2]))
return dataMat,labelMat
def selectJrand(i,m):
#i是第一个alpha的下标,m都是alpha的总个数
j=i
while(j==i):
#j是第二个alpha的下标
#如果j与i相同,则重新选取一个
j=int(random.uniform(0,m))
return j
def clipAlpha(aj,H,L):
#设置上下界限
if aj>H:
aj=H
if L>aj:
aj=L
return aj
简化版的SMO算法:
<pre name="code" class="python">def smoSimple(dataMatIn,classlabels,C,toler,maxIter):
#函数输入:数据、标签集、常数、容错率、最大循环次数
dataMatrix=mat(dataMatIn)
labelMat=mat(classlabels).transpose()
b=0
m,n=shape(dataMatrix)
#m表示样本个数,n表示特征维度
alphas=mat(zeros((m,1)))
iter=0
while(iter<maxIter):
#外循环
alphaPairsChanged=0
for i in range(m):
fXi=float(multiply(alphas,labelMat).T*(dataMat