机器学习实战笔记3

来源:互联网 发布:ubuntu下安装wine 编辑:程序博客网 时间:2024/05/17 07:59

第6章 SVM

支持向量机是一种二分类模型,其基本模型是定义在特征空间上间隔最大的线性分类器,间隔最大使它有别于感知机;其核技巧使其成为非线性分类器

函数间隔:定义超平面(w,b)关于样本点(xi,yi)的函数间隔为

γi^=yi(wxi+b)

几何间隔:可以理解成点到面的距离,不会因为w,b的集体变化而变化(w,b集体变化,超平面不变),

公式为:γi=w||w||xi+b||w||

γ̂ =||w||γ

【注意到上面的几何间隔和函数间隔,也就是说如果等比例的改变w,b,超平面不变,对于函数间隔公式,左右两边同时变化,一定有w,b使得γ̂ =1】

线性可分支持向量机

线性可分支持向量机的最大间隔超平面可以表示为下面的约束最优化问题:

maxw,bγ

s.t.yi(w||w||xi+b||w||)γi=1,2,3,,N

转化为:

maxw,bγ̂ ||w||

s.t.yi(wxi+b)γ̂ i=1,2,,N

由上面所述,令γ̂ =1,且求1||w|| 的最大值与求12||w||2 的最小值等价,故而将上诉问题转化为如下:

minw,b12||w||2

s.t.yi(wxi+b)10,i=1,2,,N

将上式不等式转换为如下:

s.t.1yi(wxi+b)0,i=1,2,,N

构建拉格朗日函数,对每个不等式约束引进拉格朗日乘子

L(w,b,a)=12||w||2+i=1Nai(1yi(wxi+b))

其问题对应:

maxaminw,bL(w,b,a)

minw,bL(w,b,a)

wL(w,b,a)=wiNaiyixi=0

bL(w,b,a)=i=1Naiyi=0

解得:

w=i=1Naiyixi

i=1Naiyi=0

代入

maxaminw,bL(w,b,a)
得:

maxa12i=1Nj=1Naiajyiyj(xixj)+i=1Nai

将问题转化为如下:

mina12i=1Nj=1Naiajyiyj(xixj)i=1Nai

s.t.i=1Naiyi=0

ai0,i=1,2,,N

线性支持向量机

是线性可分支持向量机的扩展,对约束问题做如下改变

对约束条件加上松弛变量,变为:

yi(wxi+b)>=1ξi

同时对每个松弛变量ξi,需支付一个代价ξi ,目标函数变为:

12||w||2+Ci=1Nξi

这里的C>0,为惩罚参数,C值越大,对误分类的惩罚越大,C值越小,对误分类的惩罚越小

线性不可分的线性支持向量机的学习问题变为如下的凸二次规划问题:

minw,b,ξ12||w||2+Ci=1Nξis.t.yi(wxi+b)1ξi,i=1,2,,Nξi0,i=1,2,,N

同上面求解线性可分支持向量机最优化问题一样

不等式转化为小于等于的形式:

1ξiyi(wxi+b)0,i=1,2,,N

ξi0

转化为拉格朗日函数,添加拉格朗日乘子αi,μi

L(w,b,ξ,α,μ)=12||w||2+Ci=1Nξi+i=1Nαi(1ξiyi(wxi+b))i=1Nμiξi

求解

minw,b,ξL(w,b,ξ,α,μ)

wL(w,b,ξ,α,μ)=wi=1Nαiyixi=0

bL(w,b,ξ,α,μ)=i=1Nαiyi=0

ξL(w,b,ξ,α,μ)=CEαμ=0

上面这个式子等价如下:

CC..Cα1α2..αNμ1μ2..μN=00..0

Cαiμi=0

往回代,

minw,b,ξL(w,b,ξ,α,μ)=12i=1Nj=1Naiajyiyj(xixj)+i=1Nαi

原式:

maxα,μminw,b,ξL(w,b,ξ,α,μ)
由上式即对α求极大,并添加约束条件,如下:

maxα12i=1Nj=1Naiajyiyj(xixj)+i=1Nαis.t.i=1Naiyi=0Cαiμi=0αi0μi0

转化为最小值问题,并消去μ :

minα12i=1Nj=1Naiajyiyj(xixj)i=1Nαis.t.i=1Naiyi=00αiC

SMO算法

SMO算法是对上面凸二次规划的对偶问题的一种高效解决方法,具体如下:

每次选取两个参数α1,α2,其他变量为固定的,则对偶问题中的主以写为:

minα1,α2W(α1,α2)=12i=1Nj=1Naiajyiyj(xixj)i=1Nαi=f(α1,α2)+f(α3,α4,...,αN)=12(x1x1)α21+12(x2x2)α22+y1y2(x1x2)α1α2(α1+α2)+y1α1i=3Nyiαi(xix1)+y2α2i=3Nyiαi(xix2)s.t.α1y1+α2y2=i=3Nyiαi=ζ0αiC,i=1,2

关于二次规划问题就不详述了,直接讲算法原理

1.选取变量

第一个变量的选取看样本点是否满足KKT条件:

αi=0yig(xi)10<αi<Cyig(xi)=1αi=Cyig(xi)1g(xi)=j=1Nαjyj(xixj)+b

不满足的条件就两种情况:αi>0andyig(xi)1αi<Candyig(xi)1 ,

书中说道是在ε范围内进行,即上述不满足的情况变为如下

αi>0andyig(xi)1εαi<Candyig(xi)1ε

第二个变量的选取见统计学习方法中p129,E1为正,选取最小的Ei作为E2 ;E1为负,选取最大得Ei作为E2

2.关于边界条件的选取

二次规划在约束条件下对应的最小或最大值,见P126

3.新值的计算

其中η的求解,程序中直选取小于0的部分,η表示的是二阶导,如果大于0,表示没有极小值,极小值在边界,而当η=0的情况,书中说道比较复杂未考虑,可以参见

http://blog.csdn.net/luoshixian099/article/details/51227754

下面摘取一部分:

大部分情况下,有η=K11+K22−2K12>0。但是在如下几种情况下,αnew2需要取临界值L或者H.

  1. η<0,当核函数K不满足Mercer定理时,矩阵K非正定;
  2. η=0,样本x1与x2输入特征相同;

也可以如下理解,对(3)式求二阶导数就是η=K11+K22−2K12,
当η<0时,目标函数为凸函数,没有极小值,极值在定义域边界处取得。
当η=0时,目标函数为单调函数,同样在边界处取极值。
计算方法:
即当αnew2=L和αnew2=H分别带入(9)式中,计算出αnew1=L1和αnew1=H1,其中s=y1y2
这里写图片描述

带入目标函数(1)内,比较Ψ(α1=L1,α2=L)与Ψ(α1=H1,α2=H)的大小,α2取较小的函数值对应的边界点。
这里写图片描述
其中
这里写图片描述

顺便有一篇博客讲得还不错:http://blog.csdn.net/on2way/article/details/47730367

4.b和Ei的求解P130有讲到

具体程序如下:

from numpy import mat, shape, zeros, multiplydef loadDatas():    dataMat=[]    labelMat=[]    with open("testSet.txt",'r') as f:        dateline=f.readline()        while dateline:            lineArr=dateline.strip().split('\t')            dataMat.append([float(lineArr[0]),float(lineArr[1])])            labelMat.append(float(lineArr[2]))            dateline=f.readline()    return dataMat,labelMat#计算eidef calculEi(alphas,b,dataMatrix,labelMatrix):    eilist=[]    m=len(labelMatrix)    for i in range(m):        # 这个是g(xi),即拟合的y值;其中有个[i,:]表示获取第i行        gxi = float(multiply(alphas, labelMatrix).T * (dataMatrix * dataMatrix[i, :].T)) + b        ei = gxi - float(labelMatrix[i])  # 误差        eilist.append(ei)    return eilist#获取最大值对应的下标def getMaxIndex(eilist):    maxValue=eilist[0]    index=0    for i in range(len(eilist)):        if eilist[i]>maxValue:            maxValue=eilist[i]            index=i    return index#获取最小值对应的下标def getMinIndex(eilist):    minValue=eilist[0]    index=0    for i in range(len(eilist)):        if eilist[i]<minValue:            minValue=eilist[i]            index=i    return index#选取第二个变量def selectJFromEilist(ei,alphas,b,dataMat,labelMat):    eilist=calculEi(alphas,b,dataMat,labelMat)    j=0    if ei>0:j=getMaxIndex(eilist)    else:j=getMinIndex(eilist)    return j#经剪辑后的adef clipAlpha(al,H,L):    if al<L:al=L    elif al>H:al=H    return aldef smoSimple(dataMat,labelMat,C,toler,maxIter):    #转化为矩阵    dataMatrix=mat(dataMat)#    labelMatrix=mat(labelMat).transpose()#和.T的效果一样,转置    m,n=shape(dataMatrix)#获取数组的维度信息,这里是获取二维数组的行数和列数    alphas=mat(zeros((m,1)))#参数a,注意这个zeros函数,生成m行1列值为0的数组    b=0#参数b    iter=0#存储没有任何alpha改变的情况下遍历数据集的次数    while (iter<maxIter):        alphasChanged=0        for i in range(m):            eilist=calculEi(alphas,b,dataMatrix,labelMatrix)            ei=eilist[i]            #下面这个是找到不满足KKT条件的,(g(xi)-yi)*yi=yi*g(xi)-1            if(((labelMatrix[i]*ei<-toler) and (alphas[i]<C)) or ((labelMatrix[i]*ei>toler)and(alphas[i]>0))):                j=selectJFromEilist(ei)                ej=eilist[j]                #存取old变量                alphasIold=alphas[i]                alphasJold=alphas[j]                #确定边界值                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])                if L==H:continue#L=H表明新的值被固定,不能改变了,故而没有必要进行下面的过程                eta=2.0*dataMatrix[i,:]*dataMatrix[j,:].T-dataMatrix[i,:]*dataMatrix[i,:].T-dataMatrix[j,:]*dataMatrix[j,:].T                # 书中说到此处为简化过程,详见我的文字说明                if eta>=0:continue                alphas[j]-=labelMat[j]*(ei-ej)/eta                alphas[j]=clipAlpha(alphas[j],H,L)#剪辑                #如果变化很小,则从新选取                if (abs(alphas[j]-alphasJold)<0.00001):                    print("j not moving enough")                    continue                alphas[i]+=labelMat[j]*labelMat[i]*(alphasJold-alphas[j])                b1=b-ei-labelMat[i]*dataMatrix[i,:]*dataMatrix[i,:].T*(alphas[i]-alphasIold)-labelMat[j]*dataMatrix[j,:]*dataMatrix[i,:].T*(alphas[j]-alphasJold)                b2=b-ej-labelMat[i]*dataMatrix[i,:]*dataMatrix[j,:].T*(alphas[i]-alphasIold)-labelMat[j]*dataMatrix[j,:]*dataMatrix[j,:].T*(alphas[j]-alphasJold)                if (alphas[i]>0)and(alphas[j]<C):b=b1                elif (alphas[j]>0)and(alphas[j]<C):b=b2                else:b=(b1+b2)/2                alphasChanged+=1        if(alphasChanged==0):iter+=1        else:iter=0    return b,alphas

关于SMO算法参见原论文:Sequential Minimal Optimization: A Fast

Algorithm for Training Support Vector Machines

SVM到此结束。。。累!