支持向量机从原理到算法的实现
思想:寻找能够成功分开两类样本并且具有最大分类间隔的最优超平面。
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>