一、支持向量机原理
1.1 间隔和支持向量
1.2 对偶问题
对式6.6,利用拉格朗日乘子法得到其对偶问题:
首先得拉格朗日函数:
最后利用式6.9消去6.8中的w和b,得对偶问题:
二、 SMO算法(Sequential Minimal Optimization)
2.1 SMO原理
SMO是一个二次规划算法,能高效的解决上述问题。其思路:
2.2 简化版SMO算法
代码实现:
# -*- coding: utf-8 -*-
"""
Created on Mon Apr 23 19:42:07 2018
**************************SMO****************************
@author: lizihua
"""
import numpy as np
from numpy import mat,zeros,shape,multiply,nonzero,arange
import matplotlib
import matplotlib.pyplot as plt
from matplotlib.patches import Circle
#SMO算法中的辅助函数
#加载数据,获取数据集(X1,X2)和标签(y)
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
#返回一个范围在[0,m)之间的整数,且不等于j值
def selectJrand(i,m):
j=i
while(j==i):
j=int(np.random.uniform(0,m))
return j
#使得alpha的值始终在(L,H)开区间内
def clipAlpha(aj,H,L):
if aj > H:
aj = H
if L > aj:
aj = L
return aj
#简化版的SMO算法
def smoSimple(dataMatIn,classLabels,C,toler,maxIter):
dataMatrix = mat(dataMatIn);
labelMat = mat(classLabels).transpose()
m,n = shape(dataMatrix)
b=0;
alphas =mat(zeros((m,1)))
iter = 0
while (iter < maxIter):
alphaPairsChanged = 0 #用来记录alpha是否被优化
for i in range(m):
#f(xi)=w.T+b=(a*y).T*(X*Xi.T)+b(矩阵形式)
fXi = float(multiply(alphas,labelMat).T*(dataMatrix*(dataMatrix[i,:].T)))+b
#误差Ei,若误差|Ei|<toler,则认为误差很小,可忽略。
Ei = fXi - float(labelMat[i])
#需满足0<alphas[i]<C,且误差很大,即|Ei|>toler
if ((labelMat[i]*Ei) < -toler and (alphas[i] < C)) or ((labelMat[i]*Ei>toler) and (alphas[i]>0)):
#选取一个等于i的j值,使得aj和ai成为一对alpha对
j = selectJrand(i,m)
#同上
fXj = float(multiply(alphas,labelMat).T*(dataMatrix*dataMatrix[j,:].T))+b
Ej = fXj - float(labelMat[j])
alphaIOld = alphas[i].copy()
alphaJOld = alphas[j].copy()
#保证了alpha在0~C之间,L< aj < H,最终推出 0 <ai,aj < C
if (labelMat[i] !=labelMat[j]):
L = max(0,alphas[j]-alphas[i])
H = min(C,C + alphas[j]-alphas[i])
else:
L = max(0,alphas[j]+alphas[i]-C)
H = min(C,alphas[j]+alphas[i])
#L==H意味:ai和aj在边界上,无需优化
#|aj-ai|=C ==>ai=0,aj=C或aj=0,ai=C
#ai+aj=0或2C ==>ai=0,aj=0或aj=C,ai=C
if L==H:
print("L==H")
continue
eta = 2.0 *dataMatrix[i,:]*dataMatrix[j,:].T-dataMatrix[i,:]*dataMatrix[i,:].T-dataMatrix[j,:]*dataMatrix[j,:].T
#eta>=0,则退出当前迭代过程
if eta >=0:
print("eta>0")
continue
alphas[j] -= labelMat[j]*(Ei-Ej)/eta