当前位置: 首页 > news >正文

石家庄做手机网站建设凉州区住房城乡建设局网站

石家庄做手机网站建设,凉州区住房城乡建设局网站,为企业打造赚钱系统,网站的主题是什么一引言#xff1a;支持向量机这部分确实很多#xff0c;想要真正的去理解它#xff0c;不仅仅知道理论#xff0c;还要进行相关的代码编写和测试#xff0c;二者想和结合#xff0c;才能更好的帮助我们理解SVM这一非常优秀的分类算法支持向量机是一种二类分类算法#x…一引言支持向量机这部分确实很多想要真正的去理解它不仅仅知道理论还要进行相关的代码编写和测试二者想和结合才能更好的帮助我们理解SVM这一非常优秀的分类算法支持向量机是一种二类分类算法假设一个平面可以将所有的样本分为两类位于正侧的样本为一类值为1而位于负一侧的样本为另外一类值为-1。我们说分类不仅仅是将不同的类别样本分隔开还要以比较大的置信度来分隔这些样本这样才能使绝大部分样本被分开。比如我们想通过一个平面将两个类别的样本分开如果这些样本是线性可分或者近视线性可分那么这样的平面有很多但是如果我们加上要以最大的置信度来将这些样本分开那么这样的平面只有一条。那么怎么才能找到这样的平面呢这里不得不提到几个概念 1 几何间隔几何间隔的概念简单理解就是样本点到分隔平面的距离 2 间隔最大化想要间隔最大化我们必须找到距离分隔平面最近的点并且使得距离平面最近的点尽可能的距离平面最远这样每一个样本就都能够以比较大的置信度被分隔开 算法的分类预测能力也就越好显然SVM算法的关键所在就是找到使得间隔最大化的分隔超平面如果特征是高维度的情况我们称这样的平面为超平面这里关于SVM学习推荐两本书统计学习方法李航和机器学习实战二者结合可以帮助我们理解svm算法 2 支持向量机关于支持向量机的推导无论是书上还是很多很优秀的博客都写的非常清楚大家有兴趣可以看上面推荐的统计与学习方法书写的浅显易懂或者看这几篇博客 http://blog.csdn.net/app_12062011/article/details/50536369 机器学习算法支持向量机系列博客 http://blog.csdn.net/zouxy09/article/details/16955347 http://blog.csdn.net/zouxy09/article/details/17291543 http://blog.csdn.net/zouxy09/article/details/17291805 http://blog.csdn.net/zouxy09/article/details/17292011这两位博主都重点讲解了SVM的推导过程。这里我就本着站在巨人的肩膀上的思想不再赘述我的侧重点在于实际的代码编写上比较理论总归要回到实践上这也是每个算法的归宿所在。好了下面我就简要写出简要介绍一下线性支持向量机近似线性支持向量机以及非线性支持向量机核函数 1 线性支持向量机求解线性支持向量机的过程是凸二次规划问题所谓凸二次规划问题就是目标函数是凸的二次可微函数约束函数为仿射函数满足f(x)a*xb,a,x均为n为向量。而我们说求解凸二次规划问题可以利用对偶算法--即引入拉格朗日算子利用拉格朗日对偶性将原始问题的最优解问题转化为拉格朗日对偶问题这样就将求w*b的原始问题的极小问题转化为求alpha*alpha0的对偶问题的极大问题即求出alpha*在通过KKT条件求出对应的参数w*b从而找到这样的间隔最大化超平面进而利用该平面完成样本分类 2 近似线性支持向量机当数据集并不是严格线性可分时即满足绝不部分样本点是线性可分存在极少部分异常点这里也就是说存在部分样本不能满足约束条件此时我们可以引入松弛因子这样这些样本点到超平面的函数距离加上松弛因子就能保证被超平面分隔开来当然添加了松弛因子sigma我们也会添加对应的代价项使得alpha满足0alphaC 3 非线性支持向量机显然当数据集不是线性可分的即我们不能通过前面的线性模型来对数据集进行分类。此时我们必须想办法将这些样本特征符合线性模型才能通过线性模型对这些样本进行分类。这就要用到核函数核函数的功能就是将低维的特征空间映射到高维的特征空间而在高维的特征空间中这些样本进过转化后变成了线性可分的情况这样在高维空间中我们就能够利用线性模型来解决数据集分类问题好了我们就只讲这么写大致的概念如果想要透彻理解SVM建议还是要看看上面的书和博客文章篇幅有限我这里的中心在于凸二次规划的优化算法--SMO(序列最小最优化算法) 3 SMO算法SMO是一种用于训练SVM的强大算法它将大的优化问题分解为多个小的优化问题来进行求解。而这些小优化问题往往很容易求解并且对它们进行顺序求解和对整体求解结果是一致的。在结果一致的情况下显然SMO算法的求解时间要短很多这样当数据集容量很大时SMO就是一致十分高效的算法SMO算法的目标是找到一系列alpha和b而求出这些alpha我们就能求出权重w这样就能得到分隔超平面从而完成分类任务SMO算法的工作原理是每次循环中选择两个alpha进行优化处理。一旦找到一对合适的alpha那么就增大其中一个而减少另外一个。这里的合适,意味着在选择alpha对时必须满足一定的条件条件之一是这两个alpha不满足最优化问题的kkt条件另外一个条件是这两个alpha还没有进行区间化处理对于SMO算法编写我们采用由简单到复杂的方法层层递进完成最终的SMO算法实现最后通过实际的用例对SVM模型进行训练并验证准确性 1 简化版SMO算法简化版SMO算法省略了确定要优化的最佳alpha对的步骤而是首先在数据集上进行遍历每一个alpha再在剩余的数据集中找到另外一个alpha构成要优化的alpha对同时对其进行优化这里的同时是要确保公式Σαi*label(i)0。所以改变一个alpha显然会导致等式失效所以这里需要同时改变两个alpha。接下来看实际的代码简易版SMO算法的辅助函数 #SMO算法相关辅助中的辅助函数 #1 解析文本数据函数提取每个样本的特征组成向量添加到数据矩阵 #添加样本标签到标签向量 def loadDataSet(filename):dataMat[];labelMat[]fropen(filename)for line in fr.readlines():lineArrline.strip().split(\t)dataMat.append([float(lineArr[0]),float(lineArr[1])])labelMat.append((float()lineArr[2]))return dataMat,labelMat#2 在样本集中采取随机选择的方法选取第二个不等于第一个alphai的 #优化向量alphaj def selectJrand(i,m):jiwhile(ji):jint(random.uniform(0,m))return j#3 约束范围LalphajH内的更新后的alphaj值 def clipAlpha(aj,H,L):if ajH:ajHif LajajLreturn aj上面是简易版SMO算法需要用到的一些功能我们将其包装成函数需要时调用即可接下来看算法的伪代码 #SMO算法的伪代码 #创建一个alpha向量并将其初始化为0向量 #当迭代次数小于最大迭代次数时(w外循环)#对数据集中每个数据向量(内循环):#如果该数据向量可以被优化#随机选择另外一个数据向量#同时优化这两个向量#如果两个向量都不能被优化退出内循环#如果所有向量都没有被优化增加迭代次数继续下一次循环实际代码如下 #dataMat 数据列表 #classLabels标签列表 #C 权衡因子增加松弛因子而在目标优化函数中引入了惩罚项 #toler 容错率 #maxIter 最大迭代次数 def smoSimple(dataMat,classLabels,C,toler,maxIter):#将列表形式转为矩阵或向量形式dataMatrixmat(dataMatIn);labelMatmat(classLabels).transpose()#初始化b0获取矩阵行列b0;m,nshape(dataMatrix)#新建一个m行1列的向量alphasmat(zeros((m,1)))#迭代次数为0iter0while(itermaxIter):#改变的alpha对数alphaPairsChanged0#遍历样本集中样本for i in range(m):#计算支持向量机算法的预测值fXifloat(multiply(alphas,labelMat).T*\(dataMatrix*dataMatrix[i,:].T))b#计算预测值与实际值的误差EifXi-float(labelMat[i])#如果不满足KKT条件即labelMat[i]*fXi1(labelMat[i]*fXi-1-toler)#and alphaC 或者labelMat[i]*fXi1(labelMat[i]*fXi-1toler)and alpha0if((labelMat[i]*Ei-toler)and(alphaC))or\((labelMat[i]*Eitoler)and(alpha[i]0))):#随机选择第二个变量alphajjselectJrand(i,m)#计算第二个变量对应数据的预测值fXjfloat(multiply(alphas,labelMat).T*\(dataMatrix*dataMatrix[j,:]).T)b#计算与测试与实际值的差值EjfXj-float(label[j])#记录alphai和alphaj的原始值便于后续的比较alphaIoldalphas[i].copy()alphaJoldalphas[j].copy()#如何两个alpha对应样本的标签不相同if(labelMat[i]!labelMat[j]):#求出相应的上下边界Lmax(0,alphas[j]-alphas[i])Hmin(C,Calphas[j]-alphas[i])else:Lmax(0,alphas[j]alphas[i]-C)Hmin(C,alphas[j]alphas[i])if LH:print(LH);continue#根据公式计算未经剪辑的alphaj#------------------------------------------eta2.0*dataMatrix[i,:]*dataMatrix[j,:].T-\dataMatrix[i,:]*dataMatrix[i,:].T-\dataMatrix[j,:]*dataMatrix[j,:].T#如果eta0,跳出本次循环if eta0:print(eta0):continuealphas[j]-labelMat[j]*(Ei-Ej)/etaalphas[j]clipAlpha(alphas[j],H,L)#------------------------------------------ #如果改变后的alphaj值变化不大跳出本次循环 if(abs(alphas[j]-alphaJold)0.00001):print(j not moving\enough);continue#否则计算相应的alphai值alphas[i]labelMat[j]*labelMat[i]*(alphaJold-alphas[j])#再分别计算两个alpha情况下对于的b值b1b-Ei-labelMat[i]*(alphas[i]-alphaIold)*\dataMatrix[i,:]*dataMat[i,:].T-\labelMat[j]*(alphas[j]-alphaJold)*\dataMatrix[i,:]*dataMatrix[j,:].Tb2b-Ej-labelMat[i]*(alphas[i]-alphaIold)*\dataMatrix[i,:]*dataMatrix[j,:].T-\labelMat[j]*(alphas[j]-alphaJold)*\dataMatrix[j,:]*dataMatrix[j,:].T#如果0alphaiC,那么bb1if(0alphas[i]) and (Calphas[i]):bb1#否则如果0alphaiC,那么bb1elif (0alphas[j]) and (Calphas[j]):bb2#否则alphaialphaj0或Celse:b(b1b2)/2.0#如果走到此步表面改变了一对alpha值alphaPairsChanged1print(iter: d i:%d,paird changed %d,%(iter,i,alphaPairsChanged))#最后判断是否有改变的alpha对没有就进行下一次迭代if(alphaPairsChanged0):iter1#否则迭代次数置0继续循环else:iter0print(iteration number: %d %iter)#返回最后的b值和alpha向量return b,alphas上面的代码量看起来很多但事实上只要理解了SVM算法的理论知识就很容易理解其只不过是将理论转化为机器可以运行的语言而已。上面代码在一台性能一般的笔记本上对100个样本的数据集上运行收敛时间14.5秒取得了令人满意的分类效果当然上面的代码通过对整个数据集进行两次遍历的方法来寻找alpha对的方法显然存在一定的不足如果数据集规模较小的情况下或许还可以满足要求。但是对于大规模的数据集而言上面的代码显然收敛速度非常慢所以接下来我们在此基础上对选取合适的alpha对方法进行改进采用启发式的方法来选取合适的alpha对从而提升运算效率。 2 启发式选取alpha变量的SMO算法启发式的SMO算法一个外循环来选择第一个alpha值并且其选择过程会在下面两种方法之间进行交替 1在所有数据集上进行单遍扫描 2另一种方法是在间隔边界上样本点进行单遍扫描所谓间隔边界上的点即为支持向量点。显然对于整个数据集遍历比较容易而对于那些处于间隔边界上的点我们还需要事先将这些点对应的alpha值找出来存放在一个列表中然后对列表进行遍历此外在选择第一个alpha值后算法会通过一个内循环来选择第二个值在优化的过程中依据alpha的更新公式αnew,uncaoldlabel*(Ei-Ej)/η(ηdataMat[i,:]*dataMat[i,:].TdataMat[j,:]*dataMat[j,:].T-2*dataMat[i,:]*dataMat[j,:].T),可知alpha值的变化程度更Ei-Ej的差值成正比所以为了使alpha有足够大的变化选择使Ei-Ej最大的alpha值作为另外一个alpha。所以我们还可以建立一个全局的缓存用于保存误差值便于我们选择合适的alpha值下面是创建的一个数据结构类便于我们存取算法中需要用到的重要数据 #启发式SMO算法的支持函数 #新建一个类的收据结构保存当前重要的值 class optStruct:def __init__(self,dataMatIn,classLabels,C,toler):self.XdataMatInself.labelMatclassLabelsself.CCself.toltolerself.mshape(dataMatIn)[0]self.alphasmat(zeros((self.m,1)))self.b0self.eCachemat(zeros((self.m,2))) #格式化计算误差的函数方便多次调用 def calcEk(oS,k):fXkfloat(multiply(oS.alphas,oS.labelMat).T*\(oS.X*oS.X[k,:].T))oS.bEkfXk-float(oS.labelMat[k])return Ek #修改选择第二个变量alphaj的方法 def selectJ(i,oS,Ei):maxK-1;maxDeltaE-;Ej0#将误差矩阵每一行第一列置1以此确定出误差不为0#的样本oS.eCache[i][1,Ei]#获取缓存中Ei不为0的样本对应的alpha列表validEcacheListnonzero(oS.Cache[:,0].A)[0]#在误差不为0的列表中找出使abs(Ei-Ej)最大的alphajif(len(validEcacheList)0):for k in validEcacheList:if k i:continueEkcalcEk(oS,k)deltaEabs(Ei-Ek)if(deltaEmaxDeltaE):maxKk;maxDeltaEdeltaE;EjEkreturn maxK,Ejelse:#否则就从样本集中随机选取alphajjselectJrand(i,oS.m)EjcalcEk(oS,j)return j,Ej #更新误差矩阵 def updateEk(oS,k):EkcalcEk(oS,k)oS.eCache[k][1,Ek]好了有了这些辅助性的函数我们就可以很容易的实现启发式的SMO算法的具体代码 #SMO外循环代码 def smoP(dataMatIn,classLabels,C,toler,maxIter,kTup(lin,0))#保存关键数据oSoptStruct(mat(dataMatIn),mat(classLabels).transpose(),C,toler)iter0enrireSetTrue;alphaPairsChanged0#选取第一个变量alpha的三种情况从间隔边界上选取或者整个数据集while(itermaxIter)and((alphaPairsChanged0)or(entireSet)):alphaPairsChanged0#没有alpha更新对if entireSet:for i in range(oS.m):alphaPairsChangedinnerL(i,oS)print(fullSet,iter: %d i:%d,pairs changed %d,%\(iter,i,alphaPairsChanged))else:#统计alphas向量中满足0alphaC的alpha列表nonBoundIsnonzero((oS.alphas.A)0)*(oS.alphas.AC))[0]for i in nonBoundIs:alphaPairsChangedinnerL(i,oS)print(non-bound,iter: %d i:%d,pairs changed %d,%\(iter,i,alphaPairsChanged))iter1if entireSet:entireSetFalse#如果本次循环没有改变的alpha对将entireSet置为true#下个循环仍遍历数据集elif (alphaPairsChanged0):entireSetTrueprint(iteration number: %d,%iter)return oS.b,oS.alphas#内循环寻找alphaj def innerL(i,oS):#计算误差EicalcEk(oS,i)#违背kkt条件if(((oS.labelMat[i]*Ei-oS.tol)and(oS.alphas[i]oS.C))or\ ((oS.labelMat[i]*EioS.tol)and(oS.alphas[i]0))):j,EjselectJ(i,oS,Ei)alphaIoldalphas[i].copy();alphaJoldalphas[j].copy()#计算上下界if(oS.labelMat[i]!oS.labelMat[j]):Lmax(0,oS.alphas[j]-oS.alphas[i])Hmin(oS.C,oS.CoS.alphas[j]-oS.alphas[i])else:Lmax(0,oS.alphas[j]oS.alphas[i]-oS.C)Hmin(oS.C,oS.alphas[j]oS.alphas[i])if LH:print(LH);return 0#计算两个alpha值eta2.0*oS.X[i,:]*oS.X[j,:].T-oS.X[i,:]*oS.X[i,:].T-\oS.X[j,:]*oS.X[j,:].Tif eta0:print(eta0);return 0oS.alphas[j]-oS.labelMat[j]*(Ei-Ej)/etaoS.alphas[j]clipAlpha(oS.alphas[j],H,L)updateEk(oS,j)if(abs(oS.alphas[j]-alphaJold)0.00001):print(j not moving enough);return 0oS.alphas[i]oS.labelMat[j]*oS.labelMat[i]*\(alphaJold-oS.alphas[j])updateEk(oS,i)#在这两个alpha值情况下计算对应的b值#注非线性可分情况将所有内积项替换为核函数K[i,j]b1oS.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,:].Tb2oS.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,:].Tif(0oS.alphas[i])and (oS.CoS.alphas[i]):oS.bb1elif(0oS.alphas[j])and (oS.CoS.alphas[j]):oS.bb2else:oS.b(b1b2)/2.0#如果有alpha对更新return 1#否则返回0else return 0显然上面的SMO完整代码是分为内外两个循环函数来编写的采取这样的结构可以更方便我们去理解选取两个alpha的过程既然我们已经计算出了alpha值和b值那么显然我们可以利用公式w*Σαi*label[i]*dataMat[i,:]计算出相应的权值参数然后就可以得到间隔超平面的公式w*xb*来完成样本的分类了由于SVM算法是一种二类分类算法正值为1负值为-1即分类的决策函数为跳跃函数signw*xb* 然后我们可以编写一小段测试代码来利用SMO算法得到的alpha值和b值计算分类决策函数从而实现具体的预测分类了 #求出了alpha值和对应的b值就可以求出对应的w值以及分类函数值 def predict(alphas,dataArr,classLabels):Xmat(dataArr);labelMatmat(classLabels)m,nshape(X)wzeros((n,1))for i in range(m):wmultiply(alphas[i]*labelMat[i],X[i,:].T)resultdataArr[0]*mat(ws)breturn sign(result)看一下分类效果3 核函数核函数的目的主要是为了解决非线性分类问题通过核技巧将低维的非线性特征转化为高维的线性特征从而可以通过线性模型来解决非线性的分类问题。 如下图当数据集不是线性可分时即数据集分布是下面的圆形该怎么办呢显然此时数据集线性不可分我们无法用一个超平面来将两种样本分隔开那么我们就希望将这些数据进行转化转化之后的数据就能够通过一个线性超平面将不同类别的样本分开这就需要核函数核函数的目的主要是为了解决非线性分类问题通过核技巧将低维的非线性特征转化为高维的线性特征从而可以通过线性模型来解决非线性的分类问题。而径向基核函数是SVM中常用的一个核函数。径向基核函数是一个采用向量作为自变量的函数能够基于向量距离运算输出一个标量。径向基核函数的高斯版本公式为k(xy)exp(-||x-y||2/2σ2),其中σ为到达率决定了函数值跌落至0的速度下面通过代码编写高斯核函数 #径向基核函数是svm常用的核函数 #核转换函数 def kernelTrans(X,A,kTup):m,nshape(X)Kmat(zeros((m,1)))#如果核函数类型为linif kTup[0]lin:KX*A.T#如果核函数类型为rbf:径向基核函数#将每个样本向量利用核函数转为高维空间elif kTup[0]rbffor j in range(m):deltaRowX[j,:]-AK[j]deltaRow*deltaRow.TKexp(K/(-1*kTup[1]**2))elseraise NameError(Houston we Have a Problem -- \That Kernel is not recognised)return K#对核函数处理的样本特征存入到optStruct中 class optStructdef __init__(self,dataMatIn,classLabels,C,toler,kTup):self.XdataMatInself.labelMatclassLabelsself.CCself.toltolerself.mshape(dataMatIn)[0]self.alphasmat(zeros((self.m,1)))self.b0self.eCachemat(zeros((self.m,2)))self.Kmat(zeros((self.m,self.m)))for i in range(self.m):self.K[:,i]kernelTrans(self.X,self.X[i,:],kTup)需要说明的是这里引入了一个变量kTup,kTup是一个包含核信息的元组它提供了选取的核函数的类型比如线性lin或者径向基核函数rbf;以及用户提供的到达率σ有了高斯核函数之后我们只要将上面的SMO算法中所有的内积项替换为核函数即可比如讲dataMat[i,:]*dataMat[j,:].T替换为k[i,j]即可替换效果如下 def innerL(i,oS):#计算误差EicalcEk(oS,i)#违背kkt条件if(((oS.labelMat[i]*Ei-oS.tol)and(oS.alphas[i]oS.C))or\ ((oS.labelMat[i]*EioS.tol)and(oS.alphas[i]0))):j,EjselectJ(i,oS,Ei)alphaIoldalphas[i].copy();alphaJoldalphas[j].copy()#计算上下界if(oS.labelMat[i]!oS.labelMat[j]):Lmax(0,oS.alphas[j]-oS.alphas[i])Hmin(oS.C,oS.CoS.alphas[j]-oS.alphas[i])else:Lmax(0,oS.alphas[j]oS.alphas[i]-oS.C)Hmin(oS.C,oS.alphas[j]oS.alphas[i])if LH:print(LH);return 0#计算两个alpha值eta2.0*oS.K[i,j]-oS.K[i,i]-oS.K[j,j]if eta0:print(eta0);return 0oS.alphas[j]-oS.labelMat[j]*(Ei-Ej)/etaoS.alphas[j]clipAlpha(oS.alphas[j],H,L)updateEk(oS,j)if(abs(oS.alphas[j]-alphaJold)0.00001):print(j not moving enough);return 0oS.alphas[i]oS.labelMat[j]*oS.labelMat[i]*\(alphaJold-oS.alphas[j])updateEk(oS,i)#在这两个alpha值情况下计算对应的b值#注非线性可分情况将所有内积项替换为核函数K[i,j]b1oS.b-Ei-oS.labelMat[i]*(oS.alphas[i]-alphaIold)*\oS.K[i,i]-\oS.labelMat[j]*(oS.alphas[j]-alphaJold)*\oS.k[i,j]b2oS.b-Ej-oS.labelMat[i]*(oS.alphas[i]-alphaIold)*\oS.k[i,j]-\oS.labelMat[j]*(oS.alphas[j]-alphaJold)*\oS.k[i,j]if(0oS.alphas[i])and (oS.CoS.alphas[i]):oS.bb1elif(0oS.alphas[j])and (oS.CoS.alphas[j]):oS.bb2else:oS.b(b1b2)/2.0#如果有alpha对更新return 1#否则返回0else return 0有了核函数我们就能对非线性的数据集进行分类预测了接下来就是编写代码利用核函数进行测试需要说明的是在优化的过程中我们仅仅需要找到支持向量和其对应的alpha值而对于其他的样本值可以不用管甚至可以舍弃因为这些样本将不会对分类预测函数造成任何影响。这也就是SVM相比KNN算法的优秀的地方所在 #测试核函数 #用户指定到达率 def testRbf(k11.3):#第一个测试集dataArr,labelArrloadDataSet(testSetRBF.txt)b,alphassmoP(dataArr,labelArr,200,0.0001,10000,(rbf,k1))dataMatmat(dataArr);labelMatmat(labelArr).transpose()svIndnonzero(alphas.A0)[0]sVsdataMat[svInd]labelSVlabelMat[svInd]print(there are %d Support Vectors,%shape(sVs)[0])m,nshape(dataMat)errorCount0for i in range(m):kernelEvalkernelTrans(sVs,dataMat[i,:],(rbf,k1))predictkernelEval.T*multiply(labelSV,alphas[svInd])bif sign(predict)!sign(labelArr[i]):errorCount1print(the training error rate is: %f,%(float(errorCount)/m))#第二个测试集dataArr,labelArrloadDataSet(testSetRBF2.txt)dataMatmat(dataArr);labelMatmat(labelArr).transpose()errorCount0m,nshape(dataMat)for i in range(m):kernelEvalkernelTrans(sVs,dataMat[i,:],(rbf,k1))predictkernelEval.T*multiply(labelSV,alphas[svInd])bif sign(predict)!sign(labelArr[i]):errorCount1print(the training error rate is: %f,%(float(errorCount)/m))当用户输入σ1.3时的实验结果为当σ0.1时实验结果为通过输入不同的σ值当然迭代次数也会有一定的影响我们只讨论σ值我们发现测试错误率训练误差率支持向量个数都会发生变化在一定的范围内支持向量数目的下降会使得训练错误率和测试错误率都下降但是当抵达某处的最优值时再次通过增大σ值的方法减少支持向量此时训练错误率下降而测试误差上升简言之对于固定的数据集支持向量的数目存在一个最优值如果支持向量太少会得到一个很差的决策边界而支持向量太多也相当于利用整个数据集进行分类就类似于KNN算法显然运算速度不高。 三SVM实例手写识别问题相较于第二张的KNN算法尽管KNN也能取得不错的效果但是从节省内存的角度出发显然SVM算法更胜一筹因为其不需要保存真个数据集而只需要其作用的支持向量点而取得不错的分类效果。 #实例手写识别问题 #支持向量机由于只需要保存支持向量所以相对于KNN保存整个数据集占用更少内存 #且取得可比的效果#基于svm的手写数字识别 def loadImages(dirName):from os import listdirhwLabels[]trainingFileListlistdir(dirName)mlen(trainingFileList)trainingMatzeros((m,1024))for i in range(m):fileNameStrtrainingFileList[i]fileStrfileNameStr.split(.)[0]classNumStrint(fileStr.split(_)[0])if classNumStr9:hwLabels.append(-1)else:hwLabels.append(1)trainingMat[i,:]img2vector(%s/%s,%(dirName,fileNameStr))return hwLabels,trainingMat#将图像转为向量 def img2vector(fileaddir):featVeczeros((1,1024))fropen(filename)for i in range(32):lineStrfr.readline()for j in range(32):featVec[0,32*ij]int(lineStr[j])return featVec#利用svm测试数字 def testDigits(kTup(rbf,10)):#训练集dataArr,labelArrloadDataSet(trainingDigits)b,alphassmoP(dataArr,labelArr,200,0.0001,10000,kTup)dataMatmat(dataArr);labelMatmat(labelArr).transpose()svIndnonzero(alphas.A0)[0]sVsdataMat[svInd]labelSVlabelMat[svInd]print(there are %d Support Vectors,%shape(sVs)[0])m,nshape(dataMat)errorCount0for i in range(m):kernelEvalkernelTrans(sVs,dataMat[i,:],kTup)predictkernelEval.T*multiply(labelSV,alphas[svInd])bif sign(predict)!sign(labelArr[i]):errorCount1print(the training error rate is: %f,%(float(errorCount)/m))#测试集dataArr,labelArrloadDataSet(testDigits.txt)dataMatmat(dataArr);labelMatmat(labelArr).transpose()errorCount0m,nshape(dataMat)for i in range(m):kernelEvalkernelTrans(sVs,dataMat[i,:],(rbf,k1))predictkernelEval.T*multiply(labelSV,alphas[svInd])bif sign(predict)!sign(labelArr[i]):errorCount1print(the training error rate is: %f,%(float(errorCount)/m))下面来看一下在kTup(rbf,20)情况下的测试误差率和支持向量个数情况并且通过尝试不同的σ值以及尝试了线性核函数可以得到关于不同σ值的书写数字识别性能 内核模式设置训练错误率(%)测试错误率(%)支持向量数rbf,0.1052402rbf,503.2402rbf,1000.599rbf,500.22.241rbf,1004.54.326Linear2.72.238由上图可以看出σ值在取10时取得了最好的分类效果这也印证了我们上面的叙述。即对于固定的数据集存在最优的支持向量个数使得分类错误率最低。支持向量的个数会随着σ值的增大而逐渐减少但是分类错误率确实一个先降低后升高的过程。即最小的分类错误率并不意味着最少的支持向量个数。 4 总结支持向量机是一种通过求解凸二次规划问题来解决分类问题的算法具有较低的泛化错误率。而SMO算法可以通过每次只优化两个alpha值来加快SVM的训练速度。核技巧是将数据由低维空间映射到高维空间可以将一个低维空间中的非线性问题转换为高维空间下的线性问题来求解。而径向基核函数是一个常用的度量两个向量距离的核函数。最后支持向量机的优缺点优点泛化错误率低计算开销不大缺点对参数调节和核函数的选择敏感且仅适用于二类分类
http://wiki.neutronadmin.com/news/370573/

相关文章:

  • 住房和城乡建设部是国家认定网站吗网站模板使用
  • 精品网站建设比较好做坏事网站
  • 进一步推进网站建设百度推广开户代理商
  • 梅州专业网站建设教程简单手机网站
  • 深圳电商网络网站网站建设 猴王网络有实力
  • php做的网站怎么入侵青海西宁今天刚刚紧急通知
  • 沈阳h5建站温州鹿城网站制作报价
  • 桐乡城市建设局网站asp网站开发视频教程
  • 做任务可以给钱的网站江苏省建筑工程网
  • 台州品牌网站建设网站建设私活中能找
  • 着陆页制作网站深圳建设厅官网
  • 做音乐网站赚钱吗wap文字游戏搭建教程
  • 网站安全认证去哪做河南企业建设网站
  • 培训机构网站建设高端旅游网站建设
  • 有没有外包活的网站上饶市建设局官方网站
  • 可视化网站建设拟定一个农产品电商网站的建设需求
  • 国外域名的网站中企动力做的网站经常打不开
  • 一键生成logo免费在线网页网站优化seo教程
  • 视频类网站建设的成果新企业在哪里做网站好
  • 企业网站设计wordpresswordpress插件seo
  • 洛阳做网站公司在哪wordpress 文字折叠
  • 珠海网站建设最新报价移动云盘免费空间
  • 云南省网站开发软件土豆网网站开发源代码
  • 微擎微网站开发自适用网站的建设
  • 陕西建设官方网站帮客户做插边球网站
  • 北京网站建设价格天西部数码如何建设自己的网站
  • 返利系统网站开发建站之星模板怎么设置
  • 长沙seo网站排名优化公司有什么网站可以做ppt
  • 企业网站怎么扣费的网络系统分类
  • 公司网站维护怎么维护wordpress侧边栏自定义