SVM算法
来源:互联网 发布:阿里云测试培训 编辑:程序博客网 时间:2024/06/07 22:22
1 基本介绍
支持向量机算法是一个有效的分类算法,可用于分类、回归等任务,在传统的机器学习任务中,通过人工构造、选择特征,然后使用支持向量机作为训练器,可以得到一个效果很好的base-line训练器。
支持向量机具有如下的优缺点,
优点:
- 高维空间有效;
- 维度大于样本数量的情况下,依然有效;
- 预测时使用训练样本的子集(也即支持向量),节省内存;
- 可以使用不同的核函数用于决策;
缺点:
- 如果特征的数目远远大于样本的数目,性能将会降低;
- 不能直接提供概率估计,需要通过5-fold 交叉验证来获得;
2 理论推导
2.1 间隔与支持向量
划分超平面,
样本空间中任意一个样本
假设超平面能将样本正确分类,即对样本
若
若
令,
距离超平面最近的几个训练样本点,使上式的等号成立,则它们称为支持向量;
两个异类支持向量到超平面的距离之和为
欲找到最大间隔的划分超平面,也就是找到
等价于,
希望求解式(6),来得到最大间隔划分超平面所对应的模型,
2.2 对偶问题
对上述公式使用拉格朗日乘子法,可得其对偶问题,具体就是对上述公式的每个约束添加拉格朗日乘子
其中,
将式(9)带入(8)中,可将
解出
式(11)中解出的
对于训练样本
若
若
2.3 核函数
如果训练样本不能线性可分,可将样本从原始空间映射到更高维的特征空间,使得样本在这个特征空间内线性可分;
令
其中,
对偶问题为,
由于样本
则式(16)可重写为,
求解即可得到模型,
其中,
常见的核函数有,
线性核,
多项式核,
高斯核,
拉普拉斯核,
Sigmoid核,
2.4 软间隔
前面介绍的支持向量机形式要求所有样本满足约束条件(3),即所有样本都必须划分正确,也即“硬划分”,而软间隔则是允许某些样本不满足约束
在最大化间隔的同时,不满足约束的样本应该尽可能少,于是,优化目标可写为,
其中C > 0,
如果C为无穷大,则式(21)迫使所有样本均满足约束(20),于是式(21)等价与式(6);
如果C取有限值,式(21)允许一些样本不满足约束(20);
由于
若采用hinge-loss函数,则式(21)变为,
引入松弛变量
与式(8)类似,通过拉格朗日乘子法可得式(24)的拉格朗日函数。
其中,
令
将式(26)-(28)代入式(25)中,可得式(24)的对偶问题,
对比式(29)与式(11),唯一的差别就是在于对偶变量的约束不同,前者是
类似于式(13),对软间隔支持向量机,KKT条件要求。
对任意训练样本
(1) 若
(2) 若
(2.1) 若
(2.2) 若
(2.2.1) 若
(2.2.2) 若
2.5 多分类
SVM算法最初是为二分类问题设计,当处理多分类问题时,需要构造合适的多类分类器。
1.one-versus-rest(一对多法):
训练时,依次把某个类别的样本归为一类,其他剩余的样本归为另一类,有k个类别的样本就构造出k个SVM;预测时,将未知样本分类为具有最大分类函数值的那类。
缺陷:会存在数据倾斜;分类结果出现重叠(属于多个分类器)或者不可分类(不属于任何一个分类器)。
2.one-versus-one(一对一法):
训练时,选择一个类的样本作为正样本,负样本则只选择一个类,又k个类别的样本,就构造出
3.DAG SVM:
类似于"one-versus-one"方法,只是在对一个样本进行分类之前,先按照下图的结构组织分类器(这是一个有向无环图,因此被称作DAG SVM),
在预测时,可以先问分类器"1 vs 5",如果回答是5,就往左走;再问分类器"2 vs 5",如果还回答5,就继续往左走,一直问下去,就可以得到分类结果,如果有k个类别,那么只调用k-1个,分类速度快,且没有分类重叠和不可分类现象。
缺陷:如果一开始分类器回答错误,那么后面的分类器是无法纠正的。
3 工程应用
使用Python机器学习开源库scikit-learn中提供的SVM算法来进行实验。scikit-learn中提供的SVM模型既可以支持稠密数据(numpy.ndarray),也支持稀疏数据(scipy.sparse)。如果要使用SVM模型来对稀疏数据进行预测,它必须符合这些数据类型,例如,为了获得最优的性能,在使用C-ordered numpy.ndarray(稠密)或者scipy.sparse.csr_matrix(稀疏)这些数组时,指定数据类型dtype=float64。
example 1,画出不同SVM分类器在iris数据集上的分界线;
import numpy as npimport matplotlib.pyplot as pltfrom sklearn import svm,datasetsiris = datasets.load_iris()X = iris.data[:,:2]y = iris.targeth = 0.02C = 1.0svc = svm.SVC(kernel = 'linear',C=C).fit(X,y)rbf_svc = svm.SVC(kernel = 'rbf',gamma = 0.7, C=C).fit(X,y)poly_svc = svm.SVC(kernel = 'poly',degree = 3,C=C).fit(X,y)lin_svc = svm.LinearSVC(C=C).fit(X,y)x_min,x_max = X[:,0].min() - 1,X[:,0].max() + 1y_min,y_max = X[:,1].min() - 1,X[:,1].max() + 1xx,yy = np.meshgrid(np.arange(x_min,x_max,h), np.arange(y_min,y_max,h))titles = ['SVC with linear kernel', 'LinearSVC (linear kernel)', 'SVC with RBF kernel', 'SVC with polynomial (degree 3) kernel']for i ,clf in enumerate((svc,lin_svc,rbf_svc,poly_svc)): plt.subplot(2,2,i+1) plt.subplots_adjust(wspace = 0.4,hspace = 0.4) Z = clf.predict(np.c_[xx.ravel(),yy.ravel()]) Z = Z.reshape(xx.shape) plt.contourf(xx, yy, Z, cmap=plt.cm.Paired, alpha=0.8) plt.scatter(X[:, 0], X[:, 1], c=y, cmap=plt.cm.Paired) plt.xlabel('Sepal length') plt.ylabel('Sepal width') plt.xlim(xx.min(), xx.max()) plt.ylim(yy.min(), yy.max()) plt.xticks(()) plt.yticks(()) plt.title(titles[i])plt.show()
各个分类器的分界面如下所示,
example 2,画出最大分割超平面;
import numpy as npimport matplotlib.pyplot as pltfrom sklearn import svm# we create 40 separable pointsnp.random.seed(0)X = np.r_[np.random.randn(20, 2) - [2, 2], np.random.randn(20, 2) + [2, 2]]Y = [0] * 20 + [1] * 20# fit the modelclf = svm.SVC(kernel='linear')clf.fit(X, Y)# get the separating hyperplanew = 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 vectorsb = clf.support_vectors_[0]yy_down = a * xx + (b[1] - a * b[0])b = clf.support_vectors_[-1]yy_up = a * xx + (b[1] - a * b[0])# plot the line, the points, and the nearest vectors to the planeplt.plot(xx, yy, 'k-')plt.plot(xx, yy_down, 'k--')plt.plot(xx, yy_up, 'k-.')plt.scatter(clf.support_vectors_[:, 0], clf.support_vectors_[:, 1], s=80, facecolors='none')plt.scatter(X[:, 0], X[:, 1], c=Y, cmap=plt.cm.Paired)plt.axis('tight')plt.show()
最大分割超平面如下所示,
example 3,针对异或类型数据,研究SVM(高斯核)中参数对分类的影响。
import numpy as npimport matplotlib.pyplot as pltfrom sklearn import svmxx, yy = np.meshgrid(np.linspace(-3, 3, 500), np.linspace(-3, 3, 500))np.random.seed(0)X = np.random.randn(300, 2)Y = np.logical_xor(X[:, 0] > 0, X[:, 1] > 0)CArray = [0.1,1.0,10.0,100.0]gammaArray = [0.1,1.0,10.0,100.0]clfList = []for C in CArray: clf = svm.SVC(kernel = 'rbf',gamma = gammaArray[1], C=C).fit(X,Y) clfList.append(clf)for gamma in gammaArray: clf = svm.SVC(kernel = 'rbf',gamma = gamma, C=CArray[1]).fit(X,Y) clfList.append(clf)titles = ['C = 0.1,gamma = 1.0', 'C = 1.0,gamma = 1.0', 'C = 10.0,gamma = 1.0', 'C = 100.0,gamma = 1.0', 'C = 1.0,gamma = 0.1', 'C = 1.0,gamma = 1.0', 'C = 1.0,gamma = 10.0', 'C = 1.0,gamma = 100.0', ]# fit the modelfor i,clf in enumerate(clfList): print "i = ",i plt.subplot(2, 4, i + 1) plt.subplots_adjust(wspace=0.4, hspace=0.4) # plot the decision function for each datapoint on the grid Z = clf.decision_function(np.c_[xx.ravel(), yy.ravel()]) Z = Z.reshape(xx.shape) plt.imshow(Z, interpolation='nearest', extent=(xx.min(), xx.max(), yy.min(), yy.max()), aspect='auto', origin='lower', cmap=plt.cm.PuOr_r) contours = plt.contour(xx, yy, Z, levels=[0], linewidths=2, linetypes='--') plt.scatter(X[:, 0], X[:, 1], s=30, c=Y, cmap=plt.cm.Paired) plt.xticks(()) plt.yticks(()) plt.axis([-3, 3, -3, 3]) plt.title(titles[i])plt.show()
分类对比图,如下所示,
上面四个图是固定
下面四个图是固定C,选取不同的
- SVM算法
- SVM算法
- SVM算法
- Svm算法
- svm算法
- SVM算法
- SVM算法
- SVM算法
- SVM算法
- SVM算法
- SVM算法
- SVM算法
- SVM算法
- SVM算法
- SVM算法
- SVM算法
- SVM算法
- SVM算法
- Mosquitto pub/sub服务实现代码浅析-主体框架
- 欢迎使用CSDN-markdown编辑器
- 编程随记:有整型数组a[],中间有连续递增的子数组,现在要求把原来数组中每个递增部分组成一个新的数组
- Cookie前后台使用乱码问题
- Hadoop、spark的一些基本使用笔记
- SVM算法
- mySql的连接useSSL=false
- android 应用重启实现
- pandas.DataFrame.append
- 员工部门mysql面试题
- 单片机与数字电路抗干扰措施
- java1.8 lambda表达式 函数式编程 闭包
- Canvas基础知识
- C++中的Compare()函数用法