机器学习实战-第六章(支持向量机)

来源:互联网 发布:ug电极编程绘图 编辑:程序博客网 时间:2024/04/30 21:54

支持向量机详解:解密SVM系列 理解SVM的三层境界

1 拉格朗日乘子法(等式约束):
目标函数:f(x)=b+wTxi+(αihi),s.t. hi=0
最优解条件:hxi=0

2 kkt(不等式约束):
目标函数:f(x)=b+wTxi+(αigi)+(βihi),s.t. hi=0,gi0
最优解条件:
fxi=0,(αigi)=0,αi0(αigi)=0,gi0,αi0αigi=0

3 SVM:
思想:在两类数据中间找一个超平面b+wTx=0作为分类器,使得两类数据距该超平面的平均距离最远。
目标函数:min 12wTw,s.t. 1yi(wTxi+b)0 注意:这里w才是未知量,而不是x
kkt:
min L(w,b,α)=12wTw+[αi(1yi(wTxi+b)],s.t. gi=1yi(wTxi+b)0
最优解条件:
Lw=0w=(αiyixi)
Lb=0(αiyi)=0
(αigi)=0 注意:与(αiyi)=0相区别
αi0
(αigi)=0,αi0,gi0αigi=0
w=(αiyixi),(αiyi)=0代回到L(w,b,α)中去(对偶性):
max W(α)=αi12(αiyiαjyjxixj),s.t. αi0,(αiyi)=0,αigi=0
此时问题由求最优的w,b变成求最优的α

4 加入松弛变量
目标函数:min 12wTw+Cϵi,s.t 1ϵiyi(wTxi+b)0,ϵi0
ktt:
min L(w,b,α,β)=12wTw+[αi(1ϵiyi(wTxi+b)]+[βi(0ϵi)]
s.t. gi=1ϵiyi(wTxi+b)0,hi=0ϵi=ϵi0,ϵi0
最优解条件:
Lw=0w=(αiyixi)
Lb=0(αiyi)=0
Lϵ=0Cαiβi=0
(αigi)=0,(βihi)=0
αi0,βi0
(αigi)=0,αi0,gi0αigi=0
Cαiβi=0,αi0,βi00αiC
w=(αiyixi),(αiyi)=0代回到L(w,b,α,β)中去(对偶性):
max W(α)=αi12(αiyiαjyjxixj),s.t. 0αiC,(αiyi)=0,αigi=0
此时问题由求最优的w,b变成求最优的α,与不加松弛变量相比只是多了一个αiC

5 SMO算法:
给定一组α的初始值,保证0αiC,一般令αi=0,根据这组α可以得到相应的w,b,即一个超平面,如图:
一次求解后
但是这个超平面还不是最优的,相对于这个超平面,所有数据点可以分为3类:
yi(wTxi+b)>1(分对了)
yi(wTxi+b)=1(在两个边界面上)
yi(wTxi+b)<1(在两个边界面之间)
现在就要根据yi(wTxi+b)的值调整α,我们希望通过调整使得所有的点都满足1yi(wTxi+b)0。对于yi(wTxi+b)1的点由前面内容可知还需满足αigi=0,(注意:仔细看前面介绍,这个条件是对于符合约束条件1yi(wTxi+b)0的点才要求满足的!!!)而对于yi(wTxi+b)<1这部分点,偏离的最远,所以要让αi取最大值C才能尽可能的调整回来。综上所述,对于3类数据点:
yi(wTxi+b)>1αigi0αi0
yi(wTxi+b)=1
yi(wTxi+b)<1αi<C
如何进行调整:
随机两个不满足ktt条件的为一组,由(αiyi)=0可知:αnew1y1+αnew2y2=αold1y1+αold2y2=ϵ,结合0αiC可知αi上下限:
ify1y2L=max(0,αold2αold1),H=min(C,C+αold2αold1)ify1=y2L=max(0,αold2+αold1C),H=min(C,αold2+αold1)
具体值:
αnew2=αold2y2(E1E2)ηEi=uiyiη=2K(x1,x2)K(x1,x1)K(x2,x2),K
αnew1=αold1+y1y2(αold2αnew2)
w=(αiyixi)
bnew1=boldE1y1(αnew1αold1)K(x1,x1)y2(αnew2αold2)K(x1,x2)bnew2=boldE2y1(αnew1αold1)K(x1,x2)y2(αnew2αold2)K(x2,x2)
b=b1,b2,(b1+b2)/2if0αnew1Cif0αnew2Cothers

7 简易的SMO代码:

from numpy import *def loadDataSet(filename):    dataSet = [];labels = []    fr = open(filename)    for line in fr.readlines():        line = line.strip().split('\t')        dataSet.append([float(line[0]),float(line[1])])        labels.append(float(line[2]))    return dataSet,labelsimport randomdef selectJrand(i,m):    j=i    while(j==i):        j = int(random.uniform(0,m))    return jdef clipAlpha(aj,H,L):    if aj>H:        aj = H    if aj<L:        aj = L    return ajdef smoSimle(dataSet,labels,C,toler,maxIter):    iter = 0    m,n = shape(dataSet)    alphas = mat(zeros((m,1)))    dataMat = mat(dataSet)    labelsMat = mat(labels).transpose()    b = 0    while(iter<maxIter):        alphaPairsChanged = 0        for i in range(m):            fXi = float(multiply(alphas,labelsMat).T*(dataMat*dataMat[i,:].T))+b            Ei = fXi - float(labelsMat[i])            if ((labelsMat[i]*Ei<-toler) and (alphas[i]<C)) or ((labelsMat[i]*Ei>toler) and (alphas[i]>0)):                j = selectJrand(i,m)                fXj = float(multiply(alphas, labelsMat).T * (dataMat * dataMat[j, :].T)) + b                Ej = fXj - float(labelsMat[j])                alphaIold = alphas[i].copy()                alphaJold = alphas[j].copy()                if (labelsMat[i]!=labelsMat[j]):                    L = max(0,alphas[j]-alphas[i])                    H = min(C,C+alphas[j]-alphas[i])                else:                    L = max(0,alphas[i]+alphas[j]-C)                    H = min(C,alphas[i]+alphas[j])                if L == H:                    print 'L == H'                    continue                eta = 2.0*dataMat[i,:]*dataMat[j,:].T-dataMat[i,:]*dataMat[i,:].T-dataMat[j,:]*dataMat[j,:].T                if eta>=0:                    print 'eta>=0'                    continue                alphas[j] -= labelsMat[j]*(Ei-Ej)/eta                alphas[j] = clipAlpha(alphas[j],H,L)                if (abs(alphas[j]-alphaJold)<0.00001):                    print 'j not moving enough!'                    continue                alphas[i] += labelsMat[i]*labelsMat[j]*(alphaJold-alphas[j])                b1 = b-Ei-labelsMat[i]*(alphas[i]-alphaIold)*dataMat[i,:]*dataMat[i,:].T-labelsMat[j]*(alphas[j]-alphaJold)*dataMat[i,:]*dataMat[j,:].T                b2 = b-Ej-labelsMat[i]*(alphas[i]-alphaIold)*dataMat[i,:]*dataMat[j,:].T-labelsMat[j]*(alphas[j]-alphaJold)*dataMat[j,:]*dataMat[j,:].T                if ((0<alphas[i]) and (alphas[i]<C)):                    b = b1                elif ((0<alphas[j]) and (alphas[j]<C)):                    b = b2                else:                    b = (b1+b2)/2.0                alphaPairsChanged+=1                print "iter: %d i:%d, pairs changed %d" % (iter, i, alphaPairsChanged)        if (alphaPairsChanged == 0):            iter += 1        else:            iter = 0        print "iteration number: %d" % iter    return b, alphas
0 0