思想:寻找能够成功分开两类样本并且具有最大分类间隔的最优超平面。
1.原理解析
空间中任何一个平面的方程都可以表示为wx+b =0,如上图,设最优超平面方程H为wx+b=0,支持向量x-到H的距离为,要使分类间隔最大,即该距离最大,而该距离只与|w|有关,分子为一个常数,为了简单优美,设分子常数为-1,则H1平面方程为wx+b = -1,同理H2平面方程为wx+b = 1。
则H1H2间的距离为( - ) . =
间隔最大等价于最小化,故目标函数为J(w)=
这个编辑器很难用,不想打公式了,直接上草稿 :
2.实例
- #1、读入数据
- import numpy as np
- dataList = []
- labelList = []
- def loadData(fileName):
- f = open(fileName)
- for line in f.readlines():
- lineStr = line.split('\t')
- dataList.append([float(lineArr[0]),float(lineArr[1])])
- labelList.append(float(lineArr[2]))
- return dataList,labelList
-
- dataList,labelList = loadData('testSet.txt')
- #2、训练支持向量机
- from sklearn import svm
- #基于libsvm工具箱,SVC非线性支持向量分类,可通过核定义其核函数,如‘linear’为线性,‘rbf’为径向基核函数
- clf = svm.SVC(kernel='linear')
- clf.fit(dataList,labelList)#训练
- #3、预测
- clf.predict([[7.5,-1.5]])#预测类别
- clf.decision_function([[7.5,-1.5]])#该SVC方法decision_function为每个样本提供每个类别的分数相当于回归
-
- #支持向量
- clf.support_vectors_#获得支持向量
- clf.support_#获得支持向量索引
- clf.n_support_#获得支持向量属于不同类别的个数
- #4、绘制决策边界和支持向量
- labelArr = np.array(labelList)
- x_min, x_max = dataArr[:, 0].min() - 1, dataArr[:, 0].max() + 1
- y_min, y_max = dataArr[:, 1].min() - 1, dataArr[:, 1].max() + 1
- xx, yy = np.meshgrid(np.arange(x_min, x_max, 0.02),np.arange(y_min, y_max, 0.02))#meshgrid在空间上取点
- Z = clf.predict(np.c_[xx.ravel(), yy.ravel()])#ravel平铺,相当于np.hstack(xx)
- row = len(np.arange(y_min,y_max,0.02))
- col = len(np.arange(x_min,x_max,0.02))
- Z = Z.reshape([row,col])
-
- #plt.cm中cm全称表示colormap,paired表示两个两个相近色彩输出,比如浅蓝、深蓝;浅红、深红;浅绿,深绿这种
- plt.contourf(xx, yy, Z, cmap=plt.cm.Paired)
- plt.scatter(dataArr[:, 0], dataArr[:, 1], c=labelList)#画出数据点
- plt.scatter(dataArr[clf.support_,0],dataArr[clf.support_,1],c = 'red',s = 100,marker='o')#画出支持向量
<script>(function(){function setArticleH(btnReadmore,posi){var winH = $(window).height();var articleBox = $("div.article_content");var artH = articleBox.height();if(artH > winH*posi){articleBox.css({'height':winH*posi+'px','overflow':'hidden'})btnReadmore.click(function(){articleBox.removeAttr("style");$(this).parent().remove();})}else{btnReadmore.parent().remove();}}var btnReadmore = $("#btn-readmore");if(btnReadmore.length>0){if(currentUserName){setArticleH(btnReadmore,3);}else{setArticleH(btnReadmore,1.2);}}})()</script></article>