思想:寻找能够成功分开两类样本并且具有最大分类间隔的最优超平面。
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>