예제 #1
0
def innerL(i, oS):
    Ei = calcEk(oS, i)
    if ((oS.labelMat[i]*Ei < -oS.tol) and (oS.alphas[i] < oS.C)) or ((oS.labelMat[i]*Ei > oS.tol) and (oS.alphas[i] > 0)):
        j,Ej = selectJ(i, oS, Ei) #this has been changed from selectJrand
        alphaIold = oS.alphas[i].copy(); alphaJold = oS.alphas[j].copy();
        if (oS.labelMat[i] != oS.labelMat[j]):
            L = max(0, oS.alphas[j] - oS.alphas[i])
            H = min(oS.C, oS.C + oS.alphas[j] - oS.alphas[i])
        else:
            L = max(0, oS.alphas[j] + oS.alphas[i] - oS.C)
            H = min(oS.C, oS.alphas[j] + oS.alphas[i])
        if L==H: print("L==H"); return 0
        eta = 2.0 * oS.K[i,j] - oS.K[i,i] - oS.K[j,j] #changed for kernel
        if eta >= 0: print("eta>=0"); return 0
        oS.alphas[j] -= oS.labelMat[j]*(Ei - Ej)/eta
        oS.alphas[j] = clipAlpha(oS.alphas[j],H,L)
        updateEk(oS, j) #added this for the Ecache
        if (abs(oS.alphas[j] - alphaJold) < 0.00001): print( "j not moving enough"); return 0
        oS.alphas[i] += oS.labelMat[j]*oS.labelMat[i]*(alphaJold - oS.alphas[j])#update i by the same amount as j
        updateEk(oS, i) #added this for the Ecache                    #the update is in the oppostie direction
        b1 = oS.b - Ei- oS.labelMat[i]*(oS.alphas[i]-alphaIold)*oS.K[i,i] - oS.labelMat[j]*(oS.alphas[j]-alphaJold)*oS.K[i,j]
        b2 = oS.b - Ej- oS.labelMat[i]*(oS.alphas[i]-alphaIold)*oS.K[i,j]- oS.labelMat[j]*(oS.alphas[j]-alphaJold)*oS.K[j,j]
        if (0 < oS.alphas[i]) and (oS.C > oS.alphas[i]): oS.b = b1
        elif (0 < oS.alphas[j]) and (oS.C > oS.alphas[j]): oS.b = b2
        else: oS.b = (b1 + b2)/2.0
        return 1
    else: return 0
예제 #2
0
 def innerL(i, os):
     Ei = optStruct.calcEk(os, i)
     if ((os.labelMat[i] * Ei < -os.tol) and (os.alphas[i] < os.C)) or ((os.labelMat[i] * Ei > os.tol) and (os.alphas[i] > 0)):
         j, Ej = optStruct.selectJ(i, os, Ei)
         alphaIold = os.alphas[i].copy()
         alphaJold = os.alphas[j].copy()
         if(os.labelMat[i] != os.alphas[j]):
             L = max(0, os.alphas[j] - os.alphas[i])
             H = min(os.C, os.C + os.alphas[j] - os.alphas[i])
         else:
             L = max(0, os.alphas[j] + os.alphas[i] - os.C)
             H = min(os.C, os.C + os.alphas[j] + os.alphas[i])
         if L == H:print('L == H');reutrn (0)
         eta = 2.0 *os.X[i, :] * os.X[j, :].T - os.X[i, :]* os.X[i, :].T - os.X[j, :] * os.X[j, :].T
         if eta >= 0:print(eta >= 0);return(0)
         os.alphas[j] -= os.labelMat[j] * (Ei - Ej )/eta
         os.alphas[j] -= svmMLiA.clipAlpha(os.alphas[j], H, L)
         optStruct.updateEk(os, j)
         if(abs(os.alphas[j] - alphaJold) < 0.00001):
             print('j not moving enough'); return(0)
         os.alphas[i] += os.labelMat[j] * os.labelMat[i] *(alphaJold - os.alphas[j])
         updateEk(os, i)
         b1 = os.b - Ej - os.labelMat[i] * (os.alphas[i] - alphaIold) * os.X[i, :] * os.X[i, :].T -os.labelMat[j] * (os.alphas[j] - alphaJold) * os.X[i, :]*os.X[j,:].T
         b2 = os.b - Ej - os.labelMat[i] * (os.alphas[i] - alphaIold) * os.X[i, :] * os.X[j, :].T - os.labelMat[
             j] * (os.alphas[j] - alphaJold) * os.X[j, :] * os.X[j, :].T
         if( 0 < os.alphas[i]) and (os.C > os.alphas[i]) :os.b = b1
         elif(o < os.alphas[j]) and (os.C > os.alphas[j]): os.b = b2
         else:os.b =(b1 + b2)/2
         return 1
     else:
         return 0
예제 #3
0
def innerLK(i, oS):
    # 计算误差
    Ei = calcEkK(oS, i)
    # 违背kkt条件
    if ((oS.labelMat[i] * Ei < -oS.tol) and
        (oS.alphas[i] < oS.C)) or ((oS.labelMat[i] * Ei > oS.tol) and
                                   (oS.alphas[i] > 0)):
        j, Ej = selectJK(i, oS, Ei)  #this has been changed from selectJrand
        alphaIold = oS.alphas[i].copy()
        alphaJold = oS.alphas[j].copy()
        # 计算上下界
        if (oS.labelMat[i] != oS.labelMat[j]):
            L = max(0, oS.alphas[j] - oS.alphas[i])
            H = min(oS.C, oS.C + oS.alphas[j] - oS.alphas[i])
        else:
            L = max(0, oS.alphas[j] + oS.alphas[i] - oS.C)
            H = min(oS.C, oS.alphas[j] + oS.alphas[i])
        if L == H:
            print("L==H")
            return 0
        # 计算两个alpha值
        eta = 2.0 * oS.X[i, :] * oS.X[j, :].T - oS.X[i, :] * oS.X[
            i, :].T - oS.X[j, :] * oS.X[j, :].T
        if eta >= 0:
            print("eta>=0")
            return 0
        oS.alphas[j] -= oS.labelMat[j] * (Ei - Ej) / eta
        oS.alphas[j] = svmMLiA.clipAlpha(oS.alphas[j], H, L)
        updateEkK(oS, j)  #added this for the Ecache
        if (abs(oS.alphas[j] - alphaJold) < 0.00001):
            print("j not moving enough")
            return 0
        oS.alphas[i] += oS.labelMat[j] * oS.labelMat[i] * (
            alphaJold - oS.alphas[j])  #update i by the same amount as j
        updateEkK(
            oS, i
        )  #added this for the Ecache                    #the update is in the oppostie direction
        #
        # 在这两个alpha值情况下,计算对应的b值
        # 注,非线性可分情况,将所有内积项替换为核函数K[i,j]
        b1 = oS.b - Ei - oS.labelMat[i] * (oS.alphas[i] - alphaIold) * oS.X[
            i, :] * oS.X[i, :].T - oS.labelMat[j] * (
                oS.alphas[j] - alphaJold) * oS.X[i, :] * oS.X[j, :].T
        b2 = oS.b - Ej - oS.labelMat[i] * (oS.alphas[i] - alphaIold) * oS.X[
            i, :] * oS.X[j, :].T - oS.labelMat[j] * (
                oS.alphas[j] - alphaJold) * oS.X[j, :] * oS.X[j, :].T
        if (0 < oS.alphas[i]) and (oS.C > oS.alphas[i]): oS.b = b1
        elif (0 < oS.alphas[j]) and (oS.C > oS.alphas[j]): oS.b = b2
        else: oS.b = (b1 + b2) / 2.0
        # 如果有alpha对更新
        return 1
    # 否则返回0
    else:
        return 0
예제 #4
0
def innerLL(i, oS):
    Ei = calcEkK(oS, i)
    # 如果标签与误差相乘之后在容错范围之外,且超过各自对应的常数值,则进行优化
    if ((oS.labelMat[i] * Ei < -oS.tol) and (oS.alphas[i] < oS.C)) or ((oS.labelMat[i] * Ei > oS.tol) and (oS.alphas[i] > 0)):
        # 启发式选择第二个alpha值
        j, Ej = selectJJ(i, oS, Ei)
        # 利用copy存储刚才的计算值,便于后期比较
        alphaIold = oS.alphas[i].copy()
        alphaJold = oS.alphas[j].copy()
        # 保证alpha在0和C之间
        if (oS.labelMat[i] != oS.labelMat[j]):
            L = max(0, oS.alphas[j] - oS.alphas[i])
            H = min(oS.C, oS.C + oS.alphas[j] - oS.alphas[i])
        else:
            L = max(0, oS.alphas[j] + oS.alphas[i] -oS.C)
            H = min(oS.C, oS.alphas[j] + oS.alphas[i])
        if L == H:
            # print('L==H')
            return 0
        eta = 2.0 * oS.K[i, j] - oS.K[i, i] - oS.K[j, j]
        if eta >= 0:
            # print('eta>=0')
            return 0
        oS.alphas[j] -= oS.labelMat[j] * (Ei - Ej) / eta
        # 对新的alphas[j]进行阈值处理
        oS.alphas[j] = svm.clipAlpha(oS.alphas[j], H, L)
        # 更新误差缓存
        updateEkK(oS, j)
        # 如果新旧值差很小,则不做处理跳出本次循环
        if (abs(oS.alphas[j] - alphaJold) < 0.00001):
            # print('j not moving enough')
            return 0
        # 对i进行修改,修改量相同,但是方向相反
        oS.alphas[i] += oS.labelMat[j] * oS.labelMat[i] * (alphaJold - oS.alphas[j])
        updateEkK(oS, i)
        b1 = oS.b - Ei - oS.labelMat[i] * (oS.alphas[i] - alphaIold) * oS.K[i, i] - oS.labelMat[j] * (
                oS.alphas[j] - alphaJold) * oS.K[i, j]
        b2 = oS.b - Ej - oS.labelMat[i] * (oS.alphas[i] - alphaIold) * oS.K[i, j] - oS.labelMat[j] * (
                oS.alphas[j] - alphaJold) * oS.K[j, j]
        # 谁在0到C之间,就听谁的,否则就取平均值
        if (0 < oS.alphas[i]) and (oS.C > oS.alphas[i]):
            oS.b = b1
        elif (0 < oS.alphas[j]) and (oS.C > oS.alphas[j]):
            oS.b = b2
        else:
            oS.b = (b1 + b2) / 2.0
        return 1
    else:
        return 0
예제 #5
0
def innerLoop(i, oS):
    Ei = calcEk(oS, i)
    if (oS.labelMat[i] * Ei < -oS.tol and oS.alphas[i] < oS.C) or (oS.labelMat[i] * Ei > oS.tol and oS.alphas[i] > 0):
        j, Ej = selectJ(i, oS, Ei)
        alphaIOld = oS.alphas[i].copy()
        alphaJOld = oS.alphas[j].copy()
        if oS.labelMat[i] != oS.labelMat[j]:
            L = max(0, oS.alphas[j] - oS.alphas[i])
            H = min(oS.C, oS.C + oS.alphas[j] - oS.alphas[i])
        else:
            L = max(0, oS.alphas[j] + oS.alphas[i] - oS.C)
            H = min(oS.C, oS.alphas[j] + oS.alphas[i])
        if L == H:
            print('L == H')
            return 0
        eta = 2.0 * oS.X[i, :] * oS.X[j, :].T - oS.X[i, :] * oS.X[i, :].T - oS.X[j, :] * oS.X[j, :].T
        if eta >= 0:
            print('eta >= 0')
            return 0
        oS.alphas[j] -= oS.labelMat[j] * (Ei - Ej) / eta
        oS.alphas[j] = svmMLiA.clipAlpha(oS.alphas[j], H, L)
        updateEK(oS, j)
        if abs(oS.alphas[j] - alphaJOld) < 0.00001:
            print('j not moving enough')
            return 0
        oS.alphas[i] += oS.labelMat[j] * oS.labelMat[i] * (alphaJOld - oS.alphas[j])
        updateEK(oS, i)
        b1 = oS.b - Ei - oS.labelMat[i] * (oS.alphas[i] - alphaIOld) * oS.X[i, :] * oS.X[i, :].T - oS.labelMat[
            j] * (oS.alphas[j] - alphaJOld) * oS.X[i, :] * oS.X[j, :].T
        b2 = oS.b - Ej - oS.labelMat[i] * (oS.alphas[i] - alphaIOld) * oS.X[i, :] * oS.X[j, :].T - oS.labelMat[
            j] * (oS.alphas[j] - alphaJOld) * oS.X[j, :] * oS.X[j, :].T
        if 0 < oS.alphas[i] < oS.C:
            oS.b = b1
        elif 0 < oS.alphas[j] < oS.C:
            oS.b = b2
        else:
            oS.b = (b1 + b2) / 2.0
        return 1
    else:
        return 0
예제 #6
0
def smoSimple(dataMatIn, classLabels, C, toler, maxIter):
    import numpy as np
    dataMatrix = np.mat(dataMatIn)
    labelMat = np.mat(classLabels).transpose()
    #print(labelMat.shape,'显示维度')
    b = 0
    m, n = np.shape(dataMatrix)
    alphas = np.mat(np.zeros((m, 1)))  #初始化alpha的值
    iter = 0
    while (iter < maxIter):
        alphaPairsChanged = 0  #更新成功标志
        for i in range(m):
            fXi=float(np.multiply(alphas,labelMat).T*\
                      (dataMatrix*dataMatrix[i,:].T))+b
            Ei = fXi - float(labelMat[i])  #计算第一个变量的误差
            if ((labelMat[i]*Ei<-toler) and (alphas[i]<C)) or \
                    ((labelMat[i]*Ei>toler) and \
                    (alphas[i]>0)):
                j = selectJrand(i, m)  #随机选择第二个变量
                fXj=float(np.multiply(alphas,labelMat).T*\
                    (dataMatrix*dataMatrix[j,:].T))+b#计算第二个变量的误差
                Ej = fXj - float(labelMat[j])
                alphaIold = alphas[i].copy()  #保存旧的alpha值
                alphaJold = alphas[j].copy()  #保存旧的alpha值
                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:
                    print('L==H')
                    continue
                eta=2.0*dataMatrix[i,:]*dataMatrix[j,:].T-\
                    dataMatrix[i,:]*dataMatrix[i,:].T-\
                    dataMatrix[j,:]*dataMatrix[j,:].T#计算2k12-k11-k22
                if eta >= 0:
                    print('eta>=0')
                    continue
                alphas[j] -= labelMat[j] * (Ei - Ej) / eta  #计算alpha1^new,unc
                alphas[j] = clipAlpha(alphas[j], H, L)  #计算alpha1^new
                if (abs(alphas[j] - alphaJold) < 0.00001):                    print\
('j not moving enough')
                    continue  #设置终止条件
                alphas[i]+=labelMat[j]*labelMat[i]*\
                           (alphaJold-alphas[j])#计算alpha2^new
                b1=b-Ei-labelMat[i]*(alphas[i]-alphaJold)*\
                    dataMatrix[i,:]*dataMatrix[i,:].T-\
                    labelMat[j]*(alphas[j]-alphaJold)*\
                    dataMatrix[i,:]*dataMatrix[j,:].T#计算b1^new
                b2=b-Ej-labelMat[i]*(alphas[i]-alphaIold)*\
                    dataMatrix[i,:]*dataMatrix[j,:].T-\
                    labelMat[j]*(alphas[j]-alphaJold)*\
                    dataMatrix[j,:]*dataMatrix[j,:].T#计算b2^new
                if (0 < alphas[i]) and (C > alphas[i]): b = b1
                elif (0 < alphas[i]) and (C > alphas[i]): b = b2
                else: b = (b1 + b2) / 2.0  #确定最终的b
                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
예제 #7
0
def innerL(i, oS):
    """
    优化的SMO算法
    Parameters:
        i - 标号为i的数据的索引值
        oS - 数据结构
    Returns:
        1 - 有任意一对alpha值发生变化
        0 - 没有任意一对alpha值发生变化或变化太小
    """
    #步骤1:计算误差Ei
    Ei = calcEk(oS, i)
    #优化alpha,设定一定的容错率。
    if ((oS.labelMat[i] * Ei < -oS.tol) and
        (oS.alphas[i] < oS.C)) or ((oS.labelMat[i] * Ei > oS.tol) and
                                   (oS.alphas[i] > 0)):
        #使用内循环启发方式2选择alpha_j,并计算Ej
        j, Ej = selectJ(i, oS, Ei)
        #保存更新前的aplpha值,使用深拷贝
        alphaIold = oS.alphas[i].copy()
        alphaJold = oS.alphas[j].copy()
        #步骤2:计算上下界L和H
        if (oS.labelMat[i] != oS.labelMat[j]):
            L = max(0, oS.alphas[j] - oS.alphas[i])
            H = min(oS.C, oS.C + oS.alphas[j] - oS.alphas[i])
        else:
            L = max(0, oS.alphas[j] + oS.alphas[i] - oS.C)
            H = min(oS.C, oS.alphas[j] + oS.alphas[i])
        if L == H:
            print("L==H")
            return 0
        #步骤3:计算eta
        eta = 2.0 * oS.X[i, :] * oS.X[j, :].T - oS.X[i, :] * oS.X[
            i, :].T - oS.X[j, :] * oS.X[j, :].T
        if eta >= 0:
            print("eta>=0")
            return 0
        #步骤4:更新alpha_j
        oS.alphas[j] -= oS.labelMat[j] * (Ei - Ej) / eta
        #步骤5:修剪alpha_j
        oS.alphas[j] = sm.clipAlpha(oS.alphas[j], H, L)
        #更新Ej至误差缓存
        updateEk(oS, j)
        if (abs(oS.alphas[j] - alphaJold) < 0.00001):
            print("alpha_j变化太小")
            return 0
        #步骤6:更新alpha_i
        oS.alphas[i] += oS.labelMat[j] * oS.labelMat[i] * (alphaJold -
                                                           oS.alphas[j])
        #更新Ei至误差缓存
        updateEk(oS, i)
        #步骤7:更新b_1和b_2
        b1 = oS.b - Ei - oS.labelMat[i] * (oS.alphas[i] - alphaIold) * oS.X[
            i, :] * oS.X[i, :].T - oS.labelMat[j] * (
                oS.alphas[j] - alphaJold) * oS.X[i, :] * oS.X[j, :].T
        b2 = oS.b - Ej - oS.labelMat[i] * (oS.alphas[i] - alphaIold) * oS.X[
            i, :] * oS.X[j, :].T - oS.labelMat[j] * (
                oS.alphas[j] - alphaJold) * oS.X[j, :] * oS.X[j, :].T
        #步骤8:根据b_1和b_2更新b
        if (0 < oS.alphas[i]) and (oS.C > oS.alphas[i]):
            oS.b = b1
        elif (0 < oS.alphas[j]) and (oS.C > oS.alphas[j]):
            oS.b = b2
        else:
            oS.b = (b1 + b2) / 2.0
        return 1
    else:
        return 0
예제 #8
0
def smoSimple(dataMatIn, classLabels, C, toler, maxIter):
    #转换为numpy的mat存储
    dataMatrix = np.mat(dataMatIn)
    labelMat = np.mat(classLabels).transpose()
    #初始化b参数,统计dataMatrix的维度
    b = 0
    m, n = np.shape(dataMatrix)
    #初始化alpha参数,设为0
    alphas = np.mat(np.zeros((m, 1)))
    #初始化迭代次数
    iter_num = 0
    #最多迭代matIter次
    while (iter_num < maxIter):
        alphaPairsChanged = 0
        for i in range(m):
            #步骤1:计算误差Ei
            fXi = float(
                np.multiply(alphas, labelMat).T *
                (dataMatrix * dataMatrix[i, :].T)) + b
            Ei = fXi - float(labelMat[i])
            #优化alpha,更设定一定的容错率。
            if ((labelMat[i] * Ei < -toler) and
                (alphas[i] < C)) or ((labelMat[i] * Ei > toler) and
                                     (alphas[i] > 0)):
                #随机选择另一个与alpha_i成对优化的alpha_j
                j = sm.selectJrand(i, m)
                #步骤1:计算误差Ej
                fXj = float(
                    np.multiply(alphas, labelMat).T *
                    (dataMatrix * dataMatrix[j, :].T)) + b
                Ej = fXj - float(labelMat[j])
                #保存更新前的aplpha值,使用深拷贝
                alphaIold = alphas[i].copy()
                alphaJold = alphas[j].copy()
                #步骤2:计算上下界L和H
                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:
                    print("L==H")
                    continue
                #步骤3:计算eta
                eta = 2.0 * dataMatrix[i, :] * dataMatrix[j, :].T - dataMatrix[
                    i, :] * dataMatrix[i, :].T - dataMatrix[j, :] * dataMatrix[
                        j, :].T
                if eta >= 0:
                    print("eta>=0")
                    continue
                #步骤4:更新alpha_j
                alphas[j] -= labelMat[j] * (Ei - Ej) / eta
                #步骤5:修剪alpha_j
                alphas[j] = sm.clipAlpha(alphas[j], H, L)
                if (abs(alphas[j] - alphaJold) < 0.00001):
                    print("alpha_j变化太小")
                    continue
                #步骤6:更新alpha_i
                alphas[i] += labelMat[j] * labelMat[i] * (alphaJold -
                                                          alphas[j])
                #步骤7:更新b_1和b_2
                b1 = b - Ei - labelMat[i] * (
                    alphas[i] - alphaIold
                ) * dataMatrix[i, :] * dataMatrix[i, :].T - labelMat[j] * (
                    alphas[j] -
                    alphaJold) * dataMatrix[i, :] * dataMatrix[j, :].T
                b2 = b - Ej - labelMat[i] * (
                    alphas[i] - alphaIold
                ) * dataMatrix[i, :] * dataMatrix[j, :].T - labelMat[j] * (
                    alphas[j] -
                    alphaJold) * dataMatrix[j, :] * dataMatrix[j, :].T
                #步骤8:根据b_1和b_2更新b
                if (0 < alphas[i]) and (C > alphas[i]): b = b1
                elif (0 < alphas[j]) and (C > alphas[j]): b = b2
                else: b = (b1 + b2) / 2.0
                #统计优化次数
                alphaPairsChanged += 1
                #打印统计信息
                print("第%d次迭代 样本:%d, alpha优化次数:%d" %
                      (iter_num, i, alphaPairsChanged))
        #更新迭代次数
        if (alphaPairsChanged == 0): iter_num += 1
        else: iter_num = 0
        print("迭代次数: %d" % iter_num)
    return b, alphas