SVM
1 由来
利用一根直线或者一个超平面把数据按照某种规则区分开来
2 最大间隔分类器
上面我们推导出了间隔的表达式,自然的,我们想让数据点离超平面越远越好:
3 核函数
在前面的讨论中,我们假设数据集是线性可分的。但是现实任务中,可能并不存在一个超平面将数据集完美得分开。
这种情况下,我们可以通过将原始空间映射到一个高维空间,如果高维空间中数据集是线性可分的,那么问题就可以解决了。
这样,超平面变为:
可见,需要计算 ϕ(xi)Tϕ(xj)ϕ(xi)Tϕ(xj) ,但很多时候,我们并不知道高维空间是什么样子,也就是我们根本连 ϕ(x)ϕ(x) 是什么样子都不知道,更不要说如果高维空间维数很大, ϕ(xi)Tϕ(xj)ϕ(xi)Tϕ(xj) 计算十分困难。 其实 ϕ(xi)Tϕ(xj)ϕ(xi)Tϕ(xj) 只是一个实数,如果将它们看成一个整体,它也是关于 xi,xjxi,xj 的一个函数,所以,如果存在那么一个神奇的函数 κ(xi,xj)=ϕ(xi)Tϕ(xj)κ(xi,xj)=ϕ(xi)Tϕ(xj) ,我们就可以在低维空间计算出高维空间的点积结果。这个函数κ(xi,xj)κ(xi,xj) 就叫做核函数。 常用的核函数有:
4 松弛变量
现实任务中,可能用上核函数还是不能线性可分。或者即使找到线性可分的超平面,也不能判断是不是过拟合。因此,我们将标准放宽一些,允许SVM模型在某些数据点上“出错”,为此,要引入“软间隔”:
5程序代码:
import numpy as np
import pylab as pl
from sklearn import svm
#we create 40 separable points
X = np.r_[np.random.randn(20, 2) - [2, 2], np.random.randn(20, 2) + [2, 2]]
Y = [0]20 +[1]20
#选择模型,并且训练出模型参数
#fit the model
clf = svm.SVC(kernel='linear')
clf.fit(X, Y)
#得到分离超平面
#get the separating hyperplane
w = clf.coef_[0]
a = -w[0]/w[1]
xx = np.linspace(-5, 5)
yy = a*xx - (clf.intercept_[0])/w[1]
#plot the parallels to the separating hyperplane that pass through the support vectors
b = clf.supportvectors[0]
yy_down = axx + (b[1] - ab[0])
b = clf.supportvectors[-1]
yy_up = axx + (b[1] - ab[0])
print("w: ", w)
print("a: ", a)
#print "xx: ", xx
#print "yy: ", yy
print("supportvectors: ", clf.supportvectors)
print("clf.coef: ", clf.coef)
#switching to the generic n-dimensional parameterization of the hyperplan to the 2D-specific equation
#of a line y=a.x +b: the generic w_0x + w_1y +w_3=0 can be rewritten y = -(w_0/w_1) x + (w_3/w_1)
#plot the line, the points, and the nearest vectors to the plane
pl.plot(xx, yy, 'k-')
pl.plot(xx, yy_down, 'k--')
pl.plot(xx, yy_up, 'k--')
pl.scatter(clf.supportvectors[:, 0], clf.supportvectors[:, 1],
s=80, facecolors='none')
pl.scatter(X[:, 0], X[:, 1], c=Y, cmap=pl.cm.Paired)
pl.axis('tight')
pl.show()
部分代码参考:https://blog.csdn.net/u014433413/article/details/78427574
转载于:https://blog.51cto.com/13831593/2173882