SMO算法总结

1。概述

SMO(Sequentil Minimal 优化组合算法用于支集用无线电引导机MAC达到目标二重的成绩,即
min 12Ni=1Nj=1αiαjyiyjK(xi,xj)Ni=1αi
s.t.αiyi=0
0αiyiC
在这人成绩上,变量是拉格朗日乘子。α,一个人αi对应于采样点(xi,yi),变量的总额等同n的范本数。。
SMO算法是一种探试法算法,其根本思惟是:假使变量的全部的解确信的KKT需要量,即:

αi0yif(xi)1+ξ0αi(yif(xi)1+ξ)=0μi0ξi0μiξi=0

假使全部的变量的全部的解都慢的KKT需要量,在那附近获益优化组合成绩的解。,鉴于KKT需要量是这人OpTIM的一个人充要需要量。

不同的,选择两个变量,指出错误倚靠变量,反驳这两个变量,we的所有格形式结构零件了两个放映成绩。,两个放映成绩的两个变量的解适宜是C,要紧的是,这两个变量造成解析法求解。。全部SMO算法由两宗派结合,宁愿宗派执意选择这两个变量的探试法的方式,次要的宗派是求解这两个变量的剖析方式。。

求解二阶放映的方式2。双变量

作为每个选择的末后α1α2这两个变量,剩下的变量可以名声常数。,从此处,we的所有格形式可以用O将优化组合成绩改写为优化组合成绩。,
结局,你可以获益它α2修复方案
αnew,unc2=αold2+y2(E1E2)η
Ei=f(xi)yi
η=K11+K222K12
鉴于有限度局限,因而we的所有格形式葡萄汁汇编这人receiver 收音机。
那时的持续地修复α1按物价指数变动工资的b与多样性E

3的选择方式。变量

1。宁愿变量的选择方式

SMO表现宁愿个人变量选择程序是外环。,外环葡萄汁选择一个人违背KKT需要量的变量。,详细来说,若
αi=0,因而经过αi+μi=C可知μi=C
也鉴于μiξi=0,因而ξi=0
也执意说,确信的KKT需要量以确信的
yif(xi)1
可以获益相等的数量的由来程序。
0<αi<C  yif(xi)=1
0<αi=C  yif(xi)1
假使变量违背KKT需要量,让we的所有格形式选择它作为宁愿个人变量,
在试验程序中,外环率先遍历全部的变量。,一个人违背KKT需要量的变量将选择次要的个变量,那时的遍历全部集中一次,
那时的在全部的非边线上遍历同样的事物的非边线变量。,它断言确信的
0<αi<C
的变量,为什么左右穿越,鉴于屡次优化组合程序,边线变量感动停留在边线上。,非边线变量关于动摇,探试法算法是鉴于节省工夫的。,而且算法会一向在非边线变量集中上遍历,直到全部的非边线变量确信的KKT需要量(自洽)
随后算法持续在全部集中上遍历寻觅违背KKT需要量的变量作为优化组合的宁愿个人变量,要紧的是要注意到,该算法至多遍历全部集中。,虽然在一组非边线变量上屡次遍历是可能性的。
选择宁愿个人变量的法典如次:

defsmo(Mac 操作系统), maxIter,):
    iter = 0
    entireSet = True
    numChanged = 0while (ITER) < maxIter) and ((numChanged > 0) or (entireSet)):
        numChanged == 0
        iter += 1if entireSet:
            for i in range():
                numChanged += innerL(Mac 操作系统), i)
        else:
            nonBounds = 非零((a) > 0) * (.A < ))[0]
            for i in nonBounds:
                numChanged += innerL(Mac 操作系统), i)
        if entireSet:
            entireSet = Falseelif numChanged == 0:
            entireSet = True

MaxIter是迭代的最大数。

2。次要的变量选择方式

它表现宁愿个人变量的选择。,那时的是次要的个变量的选择
SMO表现选择次要的个变量的程序是内地的流通。,次要的个变量的选择基准是期待。α2有尽量性大的使不同,由关于αnew2计算方案是已知的。,αnew2依赖于E1E2η
模型的普拉特是计算内核F太从容举行了。,因而就以|E1E2|选择山峰作为选择基准,虽然嗨适宜对内核矩阵举行预处理期间的。。
在这点上,要优化组合的两个变量被选择。
但嗨有一个人小成绩。,假使η为零,因而这将是一个人成绩,也执意说,假使两个变量的特点完全相等的数量,因而它会造成η为零,这是重行选择次要的个变量。。
详细方式是,宁愿次遍历非边线元素,注意到有随机的状态选择。,这是为了领先算法从初期的。,假使未发现非边线元素η大于零的次要的变量,再翻一遍,假使这次未发现,那时的保持早已选择的宁愿个人变量。
法典如次:

defsecondChoiceJ(Mac 操作系统), i):
    nonBounds = 非零((a) > 0) * (.A < ))[0]
    m = len(nonBounds)
    st = int((0, m))
    for i in 徘徊(m)
        j = nonBounds[(st+i) % m]
        if (j == i): continue
        kIi = [i, i]
        kIj = [i, j]
        kJj = [j, j]
        eta = kIi + kJj - 2*kIj
        if (埃塔) > 0):
            return j
    
    bounds = 非零((a) == 0) + (.A == ))[0]
    m = 莱恩(界)
    st = int((0, m))
    for i in 徘徊(m)
        j = bounds[(st+i) % m]
        if (j == i): continue
        kIi = [i, i]
        kIj = [i, j]
        kJj = [j, j]
        eta = kIi + kJj - 2*kIj
        if (埃塔) > 0):
            return j
    return -1

4。预测出口

预测重大聚会为
f(x)=Nj=1αiyiK(xj,x)+b
假使它是一个人直线的核重大聚会,可提早可作为基础的wb,那时的将预测值整齐的出口到出口端。,不同的,计算
Nj=1αiyiK(xj,x)

上面是Python法典,可以运用直线的核或高斯核重大聚会。

from numpy import *


defloadData(名字):
    dataSet = []
    labels = []
    fr = open(名字)
    for line in fr.readlines():
        lineArr = ().split(''\t'')
        n = len(lineArr)
        fltLine = 列表(图), lineArr[0:n-1]))
        (fltLine)
        (float(lineArr[-1]))
    return dataSet, labels


defkernelTrans(X, A, kTup):
    m, n = X.shape
    K = 垫(零点)(m), 1)))
    if kTup[0] == : K = X*A.T
    elif kTup[0] == 径向基重大聚会:
        for j in 徘徊(m)
            deltaRow = X[j, :] - A
            K[j] = deltaRow * ()
        K = EXP(K)1*kTup[1]**2))
    else: raise NameError(无法识别 内核)
    return K

classoptStruct:def__init__(私利), dataSet, labels, C, eps, kTup):
        self.X = dataSet
        self.Y = labels.T
        self.C = C
        self.eps = eps
        , self.n = 使成形(标明集)
        self.alphas = 垫子(零点), 1)))
        self.b = 0
        self.eCache = 垫子(零点), 2)))
         = 垫子(零点), )))
        for i in range():
            [:, i] = kernelTrans(私利).X, self.X[i, :], kTup)

defcalcEk(Mac 操作系统), k):
    fXk = multiply(, ).T*[:, k] + oS.b
    return fXk - [k]


defupdateEk(Mac 操作系统), k):
    Ek = calcEk(Mac 操作系统), k)
    [k] = [1, Ek


defselectJrand(i, m):
    j = i
    while j == i:
        j = int((0, m))
    return j


defselectJ(Mac 操作系统), i, 颖娃):
    maxK = -1
    maxDelta = -1
    Ej = 0
    [i] = [1, Ei
    
    validEcacheList = nonzero([:, 0a)0]
    if len(validEcacheList) > 1:
        for k in validEcacheList:
            if k == i: continue
            Ek = calcEk(Mac 操作系统), k)
            变量增量 = abs(Ek-颖娃)
            if 变量增量 > maxDelta:
                maxDelta = 变量增量
                maxK = k
                Ej = Ek
        return maxK, Ej
    else:
        j = selectJrand(i, )
        Ej = calcEk(Mac 操作系统), j)
        return j, Ej


defsecondChoiceJ(Mac 操作系统), i):
    nonBounds = 非零((a) > 0) * (.A < ))[0]
    m = len(nonBounds)
    st = int((0, m))
    for i in 徘徊(m)
        j = nonBounds[(st+i) % m]
        if (j == i): continue
        kIi = [i, i]
        kIj = [i, j]
        kJj = [j, j]
        eta = kIi + kJj - 2*kIj
        if (埃塔) > 0):
            return j
    
    bounds = 非零((a) == 0) + (.A == ))[0]
    m = 莱恩(界)
    st = int((0, m))
    for i in 徘徊(m)
        j = bounds[(st+i) % m]
        if (j == i): continue
        kIi = [i, i]
        kIj = [i, j]
        kJj = [j, j]
        eta = kIi + kJj - 2*kIj
        if (埃塔) > 0):
            return j
    return -1definnerL(Mac 操作系统), i):
    Ei = calcEk(Mac 操作系统), i)
    if (([i] < ) and (Ei) < )) or (([i] > 0) and (Ei) > )):
        j, Ej = selectJ(Mac 操作系统), i, 颖娃)
        alphaIold = [一份]正本
        alphaJold = [J]拷贝
        s = [i] * [j]
        if s < 0:
            L = max(0, alphaJold-alphaIold)
            H = min(, +alphaJold-alphaIold)
        else:
            L = max(0, alphaJold+alphaIold-)
            H = min(, alphaJold+alphaIold)
        if (L == H):
            return0
        kIi = [i, i]
        kIj = [i, j]
        kJj = [j, j]
        eta = kIi + kJj - 2*kIj
        if (埃塔) <= 0):
            return0
            j = secondChoiceJ(Mac 操作系统), i)
            if j < 0: return0
            alphaJold = [J]拷贝
            s = [i] * [j]
            if s < 0:
                L = max(0, alphaJold-alphaIold)
                H = min(, +alphaJold-alphaIold)
            else:
                L = max(0, alphaJold+alphaIold-)
                H = min(, alphaJold+alphaIold)
            if (L == H):
                return0
            kIj = [i, j]
            kJj = [j, j]
            eta = kIi + kJj - 2*kIj

        aJ = alphaJold + [j]*(Ei Ej)/η
        if aJ > H: aJ = H
        elif aJ < L: aJ = L
        [j] = aJ

        if (ABS(J-Alpjod) < ):
            return0
        [i] = alphaIold + s*(alphaJold-[j])
        bi = -Ei - [i]*kIi*([i]-alphaIold) - [j]*kIj*([j]-alphaJold) + oS.b
        bj = -Ej - [i]*kIj*([i]-alphaIold) - [j]*kJj*([j]-alphaJold) + oS.b
        if (0 < [i]) and ( > [i]):
            oS.b = bi
        elif (0 < [j]) and ( > [j]):
            oS.b = bj
        else:
            oS.b = (bi+bj)/2.0
        updateEk(Mac 操作系统), i)
        updateEk(Mac 操作系统), j)
        return1return0defsmo(Mac 操作系统), maxIter, kTup=(, 0)):
    iter = 0
    entireSet = True
    numChanged = 0while (ITER) < maxIter) and ((numChanged > 0) or (entireSet)):
        numChanged == 0
        iter += 1if entireSet:
            for i in range():
                numChanged += innerL(Mac 操作系统), i)
        else:
            nonBounds = 非零((a) > 0) * (.A < ))[0]
            for i in nonBounds:
                numChanged += innerL(Mac 操作系统), i)
        if entireSet:
            entireSet = Falseelif numChanged == 0:
            entireSet = TruedeftestRbf(K1)):
    dataSet, labels = loadData('''')
    dataSet = 标明集(MAT)
    labels = 垫子(拉环)
    oS = optStruct(dataSet, labels, 200, , (径向基重大聚会, K1)
    smo(Mac 操作系统), 100, (径向基重大聚会, K1)
    
    svInd = 非零(A) > 0)[0]
    sVs = [svInd]
    labelSV = [svInd]
    print (那边 are %d support 用无线电引导 % len(svInd))

    
    errorCount = 0for i in range():
        kernelEval = kernelTrans(sVs, [i, :], (径向基重大聚会, K1)
        predict =  * multiply(labelSV, [svInd]) + oS.b
        if 标记(预测) != 标记[(i)]
            errorCount += 1print (锻炼 error rate is: %f'' % (float(errorCount)/))

    
    dataArr, labelArr = loadData('''')
    errorCount = 0
    dataMat = mat(dataArr)
    labelMat = 垫(T)
    m, n = shape(dataMat)
    for i in 徘徊(m)
        kernelEval = kernelTrans(sVs, dataMat[i, :], (径向基重大聚会, K1)
        predict =  * multiply(labelSV, [svInd]) + oS.b
        if 标记(预测) != 标记(拉环)
            errorCount += 1print (试验 error rate is %f'' % (漂(Error Curt)/m)

testRbf()

发表评论

电子邮件地址不会被公开。 必填项已用*标注