如何在Python中绘制超平面SVM?
这是我第一个问题,请多多包涵 :)
我在用Shogun工具箱在Python中处理支持向量机(SVM)。我只是先做一些实验,以便更好地理解SVM。我写了一些Python代码,使用一些数据点来进行线性分割。我使用的是LibSVM()
。
X = np.array([[2.0, 2.0, 1.0, 1.0],
[1.0, -1.0, 1.0, -1.0]])
Y = np.array([[4.0, 5.0, 5.0, 4.0],
[1.0, 1.0, -1.0, -1.0]])
在用给定的数据训练完SVM后,我可以获取它的偏置(get_bias()
)、支持向量(get_support_vectors()
)和其他属性。不过,我还不知道怎么画出那条线或者超平面。我知道超平面的方程是y=wx + b
,但我不知道该怎么写或者怎么画出来,以便在我的图中看到它。
2 个回答
0
在编程中,有时候你会遇到一些问题,可能是因为代码写得不够好,或者是因为你对某些概念理解得不够透彻。这种情况下,向其他人请教是个不错的选择。StackOverflow就是一个这样的地方,大家可以在这里提问,分享经验,互相帮助。
当你在StackOverflow上提问时,记得描述清楚你的问题,提供相关的代码片段,这样其他人才能更好地理解你的困扰,并给出有效的建议。这样一来,你就能更快地找到解决方案,提升自己的编程技能。
总之,遇到问题不要害怕,勇敢地去请教别人,利用好像StackOverflow这样的资源,你会学到很多有用的知识。
from pylab import *
def __intersect(rect, line):
l = []
xmin,xmax,ymin,ymax = rect
a,b,c = line
assert a!=0 or b!=0
if a == 0:
y = -c/b
if y<=ymax and y>=ymin:
l.append((xmin, y))
l.append((xmax, y))
return l
if b == 0:
x = -c/a
if x<=xmax and x>=xmin:
l.append((x, ymin))
l.append((x, ymax))
return l
k = -a/b
m = -c/b
for x in (xmin, xmax):
y = k*x+m
if y<=ymax and y>= ymin:
l.append((x,y))
k = -b/a
m = -c/a
for y in (ymin, ymax):
x = k*y+m
if x<=xmax and y>= xmin and len(l) < 2:
l.append((x,y))
return l
def plotLine(coef, *args, **kwargs):
'''plot line: y=a*x+b or a*x+b*y+c=0'''
coef = float64(coef[:])
assert len(coef)==2 or len(coef)==3
if len(coef) == 2:
a, b, c = coef[0], -1., coef[1]
elif len(coef) == 3:
a, b, c = coef
ax = gca()
limits = ax.axis()
print limits
points = __intersect(limits, (a,b,c))
print points
if len(points) == 2:
pts = array(points)
ax.plot(pts[:,0], pts[:,1], *args, **kwargs)
ax.axis(limits)
1
这是一个完整的示例
import numpy as np
import matplotlib.pyplot as plt
def __intersect(rect, line):
l = []
xmin,xmax,ymin,ymax = rect
a,b,c = line
assert a!=0 or b!=0
if a == 0:
y = -c/b
if y<=ymax and y>=ymin:
l.append((xmin, y))
l.append((xmax, y))
return l
if b == 0:
x = -c/a
if x<=xmax and x>=xmin:
l.append((x, ymin))
l.append((x, ymax))
return l
k = -a/b
m = -c/b
for x in (xmin, xmax):
y = k*x+m
if y<=ymax and y>= ymin:
l.append((x,y))
k = -b/a
m = -c/a
for y in (ymin, ymax):
x = k*y+m
if x<xmax and x> xmin:
l.append((x,y))
return l
def plotline(coef, *args, **kwargs):
'''plot line: y=a*x+b or a*x+b*y+c=0'''
coef = np.float64(coef[:])
assert len(coef)==2 or len(coef)==3
if len(coef) == 2:
a, b, c = coef[0], -1., coef[1]
elif len(coef) == 3:
a, b, c = coef
ax = plt.gca()
limits = ax.axis()
points = __intersect(limits, (a,b,c))
if len(points) == 2:
pts = np.array(points)
ax.plot(pts[:,0], pts[:,1], *args, **kwargs)
ax.axis(limits)
def circle_out(x, y, s=20, *args, **kwargs):
'''Circle out points with size 's' and edgecolors'''
ax = plt.gca()
if 'edgecolors' not in kwargs:
kwargs['edgecolors'] = 'g'
ax.scatter(x, y, s, facecolors='none', *args, **kwargs)
def plotSVM(coef, support_vectors=None):
coef1 = coef[:]
coef2 = coef[:]
coef1[2] += 1
coef2[2] -= 1
plotline(coef, 'b', lw=2)
plotline(coef1, 'b', ls='dashed')
plotline(coef2, 'b', ls='dashed')
if support_vectors != None:
circle_out(support_vectors[:,0], support_vectors[:,1], s=100)
from pylab import *
X = array([[2.0, 2.0, 1.0, 1.0],
[1.0, -1.0, 1.0, -1.0]])
Y = array([[4.0, 5.0, 5.0, 4.0],
[1.0, 1.0, -1.0, -1.0]])
data = hstack((X,Y)).T
label = hstack((zeros(X.shape[1]), ones(Y.shape[1])))
from sklearn.svm import SVC
clf = SVC(kernel='linear')
clf.fit(data, label)
coef = [clf.coef_[0,0], clf.coef_[0,1], clf.intercept_[0]]
scatter(data[:,0], data[:,1], c=label)
plotSVM(coef, clf.support_vectors_)
show()