学*了SVM分类器的简单原理,并调用sklearn库,对40个线性可分点进行训练,并绘制出图形画界面。
一、问题引入
如下图所示,在x,y坐标轴上,我们绘制3个点A(1,1),B(2,0),C(2,3),其中A和B属于一类,C属于一类。
我们希望找到一条直线,将两个类分开来,且保持实线和两条虚线的距离最大,我们就能将两个类最大化分割开来。当然,我们还有很多其他直线的可以将两个点分割开来,但是这样分割效果最好。
当一个新的点进行预测时,根据点在直线的位置,判断所属分类。例如D(4,3)点在实线上方,判定为和C是一类。
源码:
# 导入基本库 from sklearn import svm import pylab as pl import numpy as np # 初始化坐标点 x = np.zeros((3,2)) x[0] = [2,0] x[1] = [1,1] x[2] = [2,3] y = [0,0,1] # 建立一个SVM分类器,并进行预测 clf = svm.SVC(kernel='linear') clf.fit(x,y) # 打印出所有的支持向量点 print(clf.support_vectors_) # 根据方程w_0*x + w_1*y + w_3 = 0--> y = -w_0/w_1*x - w_3/w_1 = kx + b # 根据w_0,w_1,w_3求得k和b w = clf.coef_[0] k = -w[0]/w[1] b = -clf.intercept_[0]/w[1] # 调用函数,初始化x点坐标范围 xx = np.linspace(start=0, stop = 5) # 计算直线方程 yy = k*xx + b # 获取第一个支持向量点,计算直线方程 b = clf.support_vectors_[0] yy_down = k*xx + (b[1] - k*b[0]) # 获取最后一个支持向量点,计算直线方程 b = clf.support_vectors_[-1] yy_up = k*xx + (b[1] - k*b[0]) # 绘制点和直线 pl.scatter(x[:,0],x[:,1]) pl.plot(xx,yy,'k-') pl.plot(xx,yy_down,'k--') pl.plot(xx,yy_up,'k--') pl.scatter(x[:,0],x[:,1],c=y,cmap=pl.cm.Paired) pl.scatter(4,3,c=y,cmap=pl.cm.Paired) pl.show()