分享

机器学习理论与实战(六)支持向量机

 瓜子的成长 2015-03-16
         上节基本完成了SVM的理论推倒,寻找最大化间隔的目标最终转换成求解拉格朗日乘子变量alpha的求解问题,求出了alpha即可求解出SVM的权重W,有了权重也就有了最大间隔距离,但是其实上节我们有个假设:就是训练集是线性可分的,这样求出的alpha在[0,infinite]。但是如果数据不是线性可分的呢?此时我们就要允许部分的样本可以越过分类器,这样优化的目标函数就可以不变,只要引入松弛变量即可,它表示错分类样本点的代价,分类正确时它等于0,当分类错误时,其中Tn表示样本的真实标签-1或者1,回顾上节中,我们把支持向量到分类器的距离固定为1,因此两类的支持向量间的距离肯定大于1的,当分类错误时肯定也大于1,如(图五)所示(这里公式和图标序号都接上一节)。


(图五)

       这样有了错分类的代价,我们把上节(公式四)的目标函数上添加上这一项错分类代价,得到如(公式八)的形式:

(公式八)

        重复上节的拉格朗日乘子法步骤,得到(公式九):

(公式九)

         多了一个Un乘子,当然我们的工作就是继续求解此目标函数,继续重复上节的步骤,求导得到(公式十):


(公式十)

         又因为alpha大于0,而且Un大于0,所以0<alpha<C,为了解释的清晰一些,我们把(公式九)的KKT条件也发出来(上节中的第三类优化问题),注意Un是大于等于0

       推导到现在,优化函数的形式基本没变,只是多了一项错分类的价值,但是多了一个条件,0<alpha<C,C是一个常数,它的作用就是在允许有错误分类的情况下,控制最大化间距,它太大了会导致过拟合,太小了会导致欠拟合。接下来的步骤貌似大家都应该知道了,多了一个C常量的限制条件,然后继续用SMO算法优化求解二次规划,但是我想继续把核函数也一次说了,如果样本线性不可分,引入核函数后,把样本映射到高维空间就可以线性可分,如(图六)所示的线性不可分的样本:

(图六)

         在(图六)中,现有的样本是很明显线性不可分,但是加入我们利用现有的样本X之间作些不同的运算,如(图六)右边所示的样子,而让f作为新的样本(或者说新的特征)是不是更好些?现在把X已经投射到高维度上去了,但是f我们不知道,此时核函数就该上场了,以高斯核函数为例,在(图七)中选几个样本点作为基准点,来利用核函数计算f,如(图七)所示:

(图七)

       这样就有了f,而核函数此时相当于对样本的X和基准点一个度量,做权重衰减,形成依赖于x的新的特征f,把f放在上面说的SVM中继续求解alpha,然后得出权重就行了,原理很简单吧,为了显得有点学术味道,把核函数也做个样子加入目标函数中去吧,如(公式十一)所示:


(公式十一)


        其中K(Xn,Xm)是核函数,和上面目标函数比没有多大的变化,用SMO优化求解就行了,代码如下:

  1. def smoPK(dataMatIn, classLabels, C, toler, maxIter):    #full Platt SMO  
  2.     oS = optStruct(mat(dataMatIn),mat(classLabels).transpose(),C,toler)  
  3.     iter = 0  
  4.     entireSet = True; alphaPairsChanged = 0  
  5.     while (iter < maxIter) and ((alphaPairsChanged > 0) or (entireSet)):  
  6.         alphaPairsChanged = 0  
  7.         if entireSet:   #go over all  
  8.             for i in range(oS.m):          
  9.                 alphaPairsChanged += innerL(i,oS)  
  10.                 print "fullSet, iter: %d i:%d, pairs changed %d" % (iter,i,alphaPairsChanged)  
  11.             iter += 1  
  12.         else:#go over non-bound (railed) alphas  
  13.             nonBoundIs = nonzero((oS.alphas.A > 0) * (oS.alphas.A < C))[0]  
  14.             for i in nonBoundIs:  
  15.                 alphaPairsChanged += innerL(i,oS)  
  16.                 print "non-bound, iter: %d i:%d, pairs changed %d" % (iter,i,alphaPairsChanged)  
  17.             iter += 1  
  18.         if entireSet: entireSet = False #toggle entire set loop  
  19.         elif (alphaPairsChanged == 0): entireSet = True    
  20.         print "iteration number: %d" % iter  
  21.     return oS.b,oS.alphas  

       下面演示一个小例子,手写识别。

      (1)收集数据:提供文本文件

      (2)准备数据:基于二值图像构造向量

      (3)分析数据:对图像向量进行目测

      (4)训练算法:采用两种不同的核函数,并对径向基函数采用不同的设置来运行SMO算法。

       (5)测试算法:编写一个函数来测试不同的核函数,并计算错误率

       (6)使用算法:一个图像识别的完整应用还需要一些图像处理的只是,此demo略。

      完整代码如下:

  1. from numpy import *  
  2. from time import sleep  
  3.   
  4. def loadDataSet(fileName):  
  5.     dataMat = []; labelMat = []  
  6.     fr = open(fileName)  
  7.     for line in fr.readlines():  
  8.         lineArr = line.strip().split('\t')  
  9.         dataMat.append([float(lineArr[0]), float(lineArr[1])])  
  10.         labelMat.append(float(lineArr[2]))  
  11.     return dataMat,labelMat  
  12.   
  13. def selectJrand(i,m):  
  14.     j=i #we want to select any J not equal to i  
  15.     while (j==i):  
  16.         j = int(random.uniform(0,m))  
  17.     return j  
  18.   
  19. def clipAlpha(aj,H,L):  
  20.     if aj > H:   
  21.         aj = H  
  22.     if L > aj:  
  23.         aj = L  
  24.     return aj  
  25.   
  26. def smoSimple(dataMatIn, classLabels, C, toler, maxIter):  
  27.     dataMatrix = mat(dataMatIn); labelMat = mat(classLabels).transpose()  
  28.     b = 0; m,n = shape(dataMatrix)  
  29.     alphas = mat(zeros((m,1)))  
  30.     iter = 0  
  31.     while (iter < maxIter):  
  32.         alphaPairsChanged = 0  
  33.         for i in range(m):  
  34.             fXi = float(multiply(alphas,labelMat).T*(dataMatrix*dataMatrix[i,:].T)) + b  
  35.             Ei = fXi - float(labelMat[i])#if checks if an example violates KKT conditions  
  36.             if ((labelMat[i]*Ei < -toler) and (alphas[i] < C)) or ((labelMat[i]*Ei > toler) and (alphas[i] > 0)):  
  37.                 j = selectJrand(i,m)  
  38.                 fXj = float(multiply(alphas,labelMat).T*(dataMatrix*dataMatrix[j,:].T)) + b  
  39.                 Ej = fXj - float(labelMat[j])  
  40.                 alphaIold = alphas[i].copy(); alphaJold = alphas[j].copy();  
  41.                 if (labelMat[i] != labelMat[j]):  
  42.                     L = max(0, alphas[j] - alphas[i])  
  43.                     H = min(C, C + alphas[j] - alphas[i])  
  44.                 else:  
  45.                     L = max(0, alphas[j] + alphas[i] - C)  
  46.                     H = min(C, alphas[j] + alphas[i])  
  47.                 if L==H: print "L==H"; continue  
  48.                 eta = 2.0 * dataMatrix[i,:]*dataMatrix[j,:].T - dataMatrix[i,:]*dataMatrix[i,:].T - dataMatrix[j,:]*dataMatrix[j,:].T  
  49.                 if eta >= 0: print "eta>=0"; continue  
  50.                 alphas[j] -= labelMat[j]*(Ei - Ej)/eta  
  51.                 alphas[j] = clipAlpha(alphas[j],H,L)  
  52.                 if (abs(alphas[j] - alphaJold) < 0.00001): print "j not moving enough"; continue  
  53.                 alphas[i] += labelMat[j]*labelMat[i]*(alphaJold - alphas[j])#update i by the same amount as j  
  54.                                                                         #the update is in the oppostie direction  
  55.                 b1 = b - Ei- labelMat[i]*(alphas[i]-alphaIold)*dataMatrix[i,:]*dataMatrix[i,:].T - labelMat[j]*(alphas[j]-alphaJold)*dataMatrix[i,:]*dataMatrix[j,:].T  
  56.                 b2 = b - Ej- labelMat[i]*(alphas[i]-alphaIold)*dataMatrix[i,:]*dataMatrix[j,:].T - labelMat[j]*(alphas[j]-alphaJold)*dataMatrix[j,:]*dataMatrix[j,:].T  
  57.                 if (0 < alphas[i]) and (C > alphas[i]): b = b1  
  58.                 elif (0 < alphas[j]) and (C > alphas[j]): b = b2  
  59.                 else: b = (b1 + b2)/2.0  
  60.                 alphaPairsChanged += 1  
  61.                 print "iter: %d i:%d, pairs changed %d" % (iter,i,alphaPairsChanged)  
  62.         if (alphaPairsChanged == 0): iter += 1  
  63.         else: iter = 0  
  64.         print "iteration number: %d" % iter  
  65.     return b,alphas  
  66.   
  67. def kernelTrans(X, A, kTup): #calc the kernel or transform data to a higher dimensional space  
  68.     m,n = shape(X)  
  69.     K = mat(zeros((m,1)))  
  70.     if kTup[0]=='lin': K = X * A.T   #linear kernel  
  71.     elif kTup[0]=='rbf':  
  72.         for j in range(m):  
  73.             deltaRow = X[j,:] - A  
  74.             K[j] = deltaRow*deltaRow.T  
  75.         K = exp(K/(-1*kTup[1]**2)) #divide in NumPy is element-wise not matrix like Matlab  
  76.     else: raise NameError('Houston We Have a Problem -- \  
  77.     That Kernel is not recognized')  
  78.     return K  
  79.   
  80. class optStruct:  
  81.     def __init__(self,dataMatIn, classLabels, C, toler, kTup):  # Initialize the structure with the parameters   
  82.         self.X = dataMatIn  
  83.         self.labelMat = classLabels  
  84.         self.C = C  
  85.         self.tol = toler  
  86.         self.m = shape(dataMatIn)[0]  
  87.         self.alphas = mat(zeros((self.m,1)))  
  88.         self.b = 0  
  89.         self.eCache = mat(zeros((self.m,2))) #first column is valid flag  
  90.         self.K = mat(zeros((self.m,self.m)))  
  91.         for i in range(self.m):  
  92.             self.K[:,i] = kernelTrans(self.X, self.X[i,:], kTup)  
  93.           
  94. def calcEk(oS, k):  
  95.     fXk = float(multiply(oS.alphas,oS.labelMat).T*oS.K[:,k] + oS.b)  
  96.     Ek = fXk - float(oS.labelMat[k])  
  97.     return Ek  
  98.           
  99. def selectJ(i, oS, Ei):         #this is the second choice -heurstic, and calcs Ej  
  100.     maxK = -1; maxDeltaE = 0; Ej = 0  
  101.     oS.eCache[i] = [1,Ei]  #set valid #choose the alpha that gives the maximum delta E  
  102.     validEcacheList = nonzero(oS.eCache[:,0].A)[0]  
  103.     if (len(validEcacheList)) > 1:  
  104.         for k in validEcacheList:   #loop through valid Ecache values and find the one that maximizes delta E  
  105.             if k == i: continue #don't calc for i, waste of time  
  106.             Ek = calcEk(oS, k)  
  107.             deltaE = abs(Ei - Ek)  
  108.             if (deltaE > maxDeltaE):  
  109.                 maxK = k; maxDeltaE = deltaE; Ej = Ek  
  110.         return maxK, Ej  
  111.     else:   #in this case (first time around) we don't have any valid eCache values  
  112.         j = selectJrand(i, oS.m)  
  113.         Ej = calcEk(oS, j)  
  114.     return j, Ej  
  115.   
  116. def updateEk(oS, k):#after any alpha has changed update the new value in the cache  
  117.     Ek = calcEk(oS, k)  
  118.     oS.eCache[k] = [1,Ek]  
  119.           
  120. def innerL(i, oS):  
  121.     Ei = calcEk(oS, i)  
  122.     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)):  
  123.         j,Ej = selectJ(i, oS, Ei) #this has been changed from selectJrand  
  124.         alphaIold = oS.alphas[i].copy(); alphaJold = oS.alphas[j].copy();  
  125.         if (oS.labelMat[i] != oS.labelMat[j]):  
  126.             L = max(0, oS.alphas[j] - oS.alphas[i])  
  127.             H = min(oS.C, oS.C + oS.alphas[j] - oS.alphas[i])  
  128.         else:  
  129.             L = max(0, oS.alphas[j] + oS.alphas[i] - oS.C)  
  130.             H = min(oS.C, oS.alphas[j] + oS.alphas[i])  
  131.         if L==H: print "L==H"; return 0  
  132.         eta = 2.0 * oS.K[i,j] - oS.K[i,i] - oS.K[j,j] #changed for kernel  
  133.         if eta >= 0: print "eta>=0"; return 0  
  134.         oS.alphas[j] -= oS.labelMat[j]*(Ei - Ej)/eta  
  135.         oS.alphas[j] = clipAlpha(oS.alphas[j],H,L)  
  136.         updateEk(oS, j) #added this for the Ecache  
  137.         if (abs(oS.alphas[j] - alphaJold) < 0.00001): print "j not moving enough"; return 0  
  138.         oS.alphas[i] += oS.labelMat[j]*oS.labelMat[i]*(alphaJold - oS.alphas[j])#update i by the same amount as j  
  139.         updateEk(oS, i) #added this for the Ecache                    #the update is in the oppostie direction  
  140.         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]  
  141.         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]  
  142.         if (0 < oS.alphas[i]) and (oS.C > oS.alphas[i]): oS.b = b1  
  143.         elif (0 < oS.alphas[j]) and (oS.C > oS.alphas[j]): oS.b = b2  
  144.         else: oS.b = (b1 + b2)/2.0  
  145.         return 1  
  146.     else: return 0  
  147.   
  148. def smoP(dataMatIn, classLabels, C, toler, maxIter,kTup=('lin', 0)):    #full Platt SMO  
  149.     oS = optStruct(mat(dataMatIn),mat(classLabels).transpose(),C,toler, kTup)  
  150.     iter = 0  
  151.     entireSet = True; alphaPairsChanged = 0  
  152.     while (iter < maxIter) and ((alphaPairsChanged > 0) or (entireSet)):  
  153.         alphaPairsChanged = 0  
  154.         if entireSet:   #go over all  
  155.             for i in range(oS.m):          
  156.                 alphaPairsChanged += innerL(i,oS)  
  157.                 print "fullSet, iter: %d i:%d, pairs changed %d" % (iter,i,alphaPairsChanged)  
  158.             iter += 1  
  159.         else:#go over non-bound (railed) alphas  
  160.             nonBoundIs = nonzero((oS.alphas.A > 0) * (oS.alphas.A < C))[0]  
  161.             for i in nonBoundIs:  
  162.                 alphaPairsChanged += innerL(i,oS)  
  163.                 print "non-bound, iter: %d i:%d, pairs changed %d" % (iter,i,alphaPairsChanged)  
  164.             iter += 1  
  165.         if entireSet: entireSet = False #toggle entire set loop  
  166.         elif (alphaPairsChanged == 0): entireSet = True    
  167.         print "iteration number: %d" % iter  
  168.     return oS.b,oS.alphas  
  169.   
  170. def calcWs(alphas,dataArr,classLabels):  
  171.     X = mat(dataArr); labelMat = mat(classLabels).transpose()  
  172.     m,n = shape(X)  
  173.     w = zeros((n,1))  
  174.     for i in range(m):  
  175.         w += multiply(alphas[i]*labelMat[i],X[i,:].T)  
  176.     return w  
  177.   
  178. def testRbf(k1=1.3):  
  179.     dataArr,labelArr = loadDataSet('testSetRBF.txt')  
  180.     b,alphas = smoP(dataArr, labelArr, 200, 0.0001, 10000, ('rbf', k1)) #C=200 important  
  181.     datMat=mat(dataArr); labelMat = mat(labelArr).transpose()  
  182.     svInd=nonzero(alphas.A>0)[0]  
  183.     sVs=datMat[svInd] #get matrix of only support vectors  
  184.     labelSV = labelMat[svInd];  
  185.     print "there are %d Support Vectors" % shape(sVs)[0]  
  186.     m,n = shape(datMat)  
  187.     errorCount = 0  
  188.     for i in range(m):  
  189.         kernelEval = kernelTrans(sVs,datMat[i,:],('rbf', k1))  
  190.         predict=kernelEval.T * multiply(labelSV,alphas[svInd]) + b  
  191.         if sign(predict)!=sign(labelArr[i]): errorCount += 1  
  192.     print "the training error rate is: %f" % (float(errorCount)/m)  
  193.     dataArr,labelArr = loadDataSet('testSetRBF2.txt')  
  194.     errorCount = 0  
  195.     datMat=mat(dataArr); labelMat = mat(labelArr).transpose()  
  196.     m,n = shape(datMat)  
  197.     for i in range(m):  
  198.         kernelEval = kernelTrans(sVs,datMat[i,:],('rbf', k1))  
  199.         predict=kernelEval.T * multiply(labelSV,alphas[svInd]) + b  
  200.         if sign(predict)!=sign(labelArr[i]): errorCount += 1      
  201.     print "the test error rate is: %f" % (float(errorCount)/m)      
  202.       
  203. def img2vector(filename):  
  204.     returnVect = zeros((1,1024))  
  205.     fr = open(filename)  
  206.     for i in range(32):  
  207.         lineStr = fr.readline()  
  208.         for j in range(32):  
  209.             returnVect[0,32*i+j] = int(lineStr[j])  
  210.     return returnVect  
  211.   
  212. def loadImages(dirName):  
  213.     from os import listdir  
  214.     hwLabels = []  
  215.     trainingFileList = listdir(dirName)           #load the training set  
  216.     m = len(trainingFileList)  
  217.     trainingMat = zeros((m,1024))  
  218.     for i in range(m):  
  219.         fileNameStr = trainingFileList[i]  
  220.         fileStr = fileNameStr.split('.')[0]     #take off .txt  
  221.         classNumStr = int(fileStr.split('_')[0])  
  222.         if classNumStr == 9: hwLabels.append(-1)  
  223.         else: hwLabels.append(1)  
  224.         trainingMat[i,:] = img2vector('%s/%s' % (dirName, fileNameStr))  
  225.     return trainingMat, hwLabels      
  226.   
  227. def testDigits(kTup=('rbf', 10)):  
  228.     dataArr,labelArr = loadImages('trainingDigits')  
  229.     b,alphas = smoP(dataArr, labelArr, 200, 0.0001, 10000, kTup)  
  230.     datMat=mat(dataArr); labelMat = mat(labelArr).transpose()  
  231.     svInd=nonzero(alphas.A>0)[0]  
  232.     sVs=datMat[svInd]   
  233.     labelSV = labelMat[svInd];  
  234.     print "there are %d Support Vectors" % shape(sVs)[0]  
  235.     m,n = shape(datMat)  
  236.     errorCount = 0  
  237.     for i in range(m):  
  238.         kernelEval = kernelTrans(sVs,datMat[i,:],kTup)  
  239.         predict=kernelEval.T * multiply(labelSV,alphas[svInd]) + b  
  240.         if sign(predict)!=sign(labelArr[i]): errorCount += 1  
  241.     print "the training error rate is: %f" % (float(errorCount)/m)  
  242.     dataArr,labelArr = loadImages('testDigits')  
  243.     errorCount = 0  
  244.     datMat=mat(dataArr); labelMat = mat(labelArr).transpose()  
  245.     m,n = shape(datMat)  
  246.     for i in range(m):  
  247.         kernelEval = kernelTrans(sVs,datMat[i,:],kTup)  
  248.         predict=kernelEval.T * multiply(labelSV,alphas[svInd]) + b  
  249.         if sign(predict)!=sign(labelArr[i]): errorCount += 1      
  250.     print "the test error rate is: %f" % (float(errorCount)/m)   
  251.   
  252.   
  253. '''''#######******************************** 
  254. Non-Kernel VErsions below 
  255. '''#######********************************  
  256.   
  257. class optStructK:  
  258.     def __init__(self,dataMatIn, classLabels, C, toler):  # Initialize the structure with the parameters   
  259.         self.X = dataMatIn  
  260.         self.labelMat = classLabels  
  261.         self.C = C  
  262.         self.tol = toler  
  263.         self.m = shape(dataMatIn)[0]  
  264.         self.alphas = mat(zeros((self.m,1)))  
  265.         self.b = 0  
  266.         self.eCache = mat(zeros((self.m,2))) #first column is valid flag  
  267.           
  268. def calcEkK(oS, k):  
  269.     fXk = float(multiply(oS.alphas,oS.labelMat).T*(oS.X*oS.X[k,:].T)) + oS.b  
  270.     Ek = fXk - float(oS.labelMat[k])  
  271.     return Ek  
  272.           
  273. def selectJK(i, oS, Ei):         #this is the second choice -heurstic, and calcs Ej  
  274.     maxK = -1; maxDeltaE = 0; Ej = 0  
  275.     oS.eCache[i] = [1,Ei]  #set valid #choose the alpha that gives the maximum delta E  
  276.     validEcacheList = nonzero(oS.eCache[:,0].A)[0]  
  277.     if (len(validEcacheList)) > 1:  
  278.         for k in validEcacheList:   #loop through valid Ecache values and find the one that maximizes delta E  
  279.             if k == i: continue #don't calc for i, waste of time  
  280.             Ek = calcEk(oS, k)  
  281.             deltaE = abs(Ei - Ek)  
  282.             if (deltaE > maxDeltaE):  
  283.                 maxK = k; maxDeltaE = deltaE; Ej = Ek  
  284.         return maxK, Ej  
  285.     else:   #in this case (first time around) we don't have any valid eCache values  
  286.         j = selectJrand(i, oS.m)  
  287.         Ej = calcEk(oS, j)  
  288.     return j, Ej  
  289.   
  290. def updateEkK(oS, k):#after any alpha has changed update the new value in the cache  
  291.     Ek = calcEk(oS, k)  
  292.     oS.eCache[k] = [1,Ek]  
  293.           
  294. def innerLK(i, oS):  
  295.     Ei = calcEk(oS, i)  
  296.     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)):  
  297.         j,Ej = selectJ(i, oS, Ei) #this has been changed from selectJrand  
  298.         alphaIold = oS.alphas[i].copy(); alphaJold = oS.alphas[j].copy();  
  299.         if (oS.labelMat[i] != oS.labelMat[j]):  
  300.             L = max(0, oS.alphas[j] - oS.alphas[i])  
  301.             H = min(oS.C, oS.C + oS.alphas[j] - oS.alphas[i])  
  302.         else:  
  303.             L = max(0, oS.alphas[j] + oS.alphas[i] - oS.C)  
  304.             H = min(oS.C, oS.alphas[j] + oS.alphas[i])  
  305.         if L==H: print "L==H"; return 0  
  306.         eta = 2.0 * oS.X[i,:]*oS.X[j,:].T - oS.X[i,:]*oS.X[i,:].T - oS.X[j,:]*oS.X[j,:].T  
  307.         if eta >= 0: print "eta>=0"; return 0  
  308.         oS.alphas[j] -= oS.labelMat[j]*(Ei - Ej)/eta  
  309.         oS.alphas[j] = clipAlpha(oS.alphas[j],H,L)  
  310.         updateEk(oS, j) #added this for the Ecache  
  311.         if (abs(oS.alphas[j] - alphaJold) < 0.00001): print "j not moving enough"; return 0  
  312.         oS.alphas[i] += oS.labelMat[j]*oS.labelMat[i]*(alphaJold - oS.alphas[j])#update i by the same amount as j  
  313.         updateEk(oS, i) #added this for the Ecache                    #the update is in the oppostie direction  
  314.         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  
  315.         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  
  316.         if (0 < oS.alphas[i]) and (oS.C > oS.alphas[i]): oS.b = b1  
  317.         elif (0 < oS.alphas[j]) and (oS.C > oS.alphas[j]): oS.b = b2  
  318.         else: oS.b = (b1 + b2)/2.0  
  319.         return 1  
  320.     else: return 0  
  321.   
  322. def smoPK(dataMatIn, classLabels, C, toler, maxIter):    #full Platt SMO  
  323.     oS = optStruct(mat(dataMatIn),mat(classLabels).transpose(),C,toler)  
  324.     iter = 0  
  325.     entireSet = True; alphaPairsChanged = 0  
  326.     while (iter < maxIter) and ((alphaPairsChanged > 0) or (entireSet)):  
  327.         alphaPairsChanged = 0  
  328.         if entireSet:   #go over all  
  329.             for i in range(oS.m):          
  330.                 alphaPairsChanged += innerL(i,oS)  
  331.                 print "fullSet, iter: %d i:%d, pairs changed %d" % (iter,i,alphaPairsChanged)  
  332.             iter += 1  
  333.         else:#go over non-bound (railed) alphas  
  334.             nonBoundIs = nonzero((oS.alphas.A > 0) * (oS.alphas.A < C))[0]  
  335.             for i in nonBoundIs:  
  336.                 alphaPairsChanged += innerL(i,oS)  
  337.                 print "non-bound, iter: %d i:%d, pairs changed %d" % (iter,i,alphaPairsChanged)  
  338.             iter += 1  
  339.         if entireSet: entireSet = False #toggle entire set loop  
  340.         elif (alphaPairsChanged == 0): entireSet = True    
  341.         print "iteration number: %d" % iter  
  342.     return oS.b,oS.alphas  

运行结果如(图八)所示:


(图八)

上面代码有兴趣的可以读读,用的话,建议使用libsvm。

参考文献:

    [1]machine learning in action. PeterHarrington

    [2] pattern recognition and machinelearning. Christopher M. Bishop

    [3]machine learning.Andrew Ng


转载请注明来源:http://blog.csdn.net/cuoqu/article/details/9305497


    本站是提供个人知识管理的网络存储空间,所有内容均由用户发布,不代表本站观点。请注意甄别内容中的联系方式、诱导购买等信息,谨防诈骗。如发现有害或侵权内容,请点击一键举报。
    转藏 分享 献花(0

    0条评论

    发表

    请遵守用户 评论公约

    类似文章 更多