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
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
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
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
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
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
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
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