赞
踩
原创不易,转载前请注明博主的链接地址:Blessy_Zhu https://blog.csdn.net/weixin_42555080
本次代码的环境:
运行平台: Windows
Python版本: Python3.x
IDE: PyCharm
经常听到这样一句话:“SVM有三宝:间隔、对偶、核技巧”。支持向量机(SVM:Support Vector Machine),主要用于解决模式识别领域中的数据分类问题,属于有监督学习算法的一种。SVM的分类主要有:硬间隔(hard-margin SVM)、软间隔(soft-margin SVM)、kernel SVM。SVM可以用一个经典的二分类问题来描述要解决的问题。如下图所示:
可以找到一条直线,将绿色和蓝色的二维数据点分开的。然而将两类数据点分开的直线显然不止一条。如下图:
图A和图B分别给出了A、B两种不同的分类方案:其中“决策面”如黑色实线所示。这样每个决策面对应了一个线性分类器。显然这两个分类器都能达到将数据分类的目的,而且误分率为零。那到底这两个分类器哪个相对来说更好一些呢?支持向量机算法认为分类器A在性能上优于分类器B,其依据是A的分类间隔比B要大为什么呢?因为分类器B的鲁棒性较差,也就是对噪声比较敏感,当它稍微出现一点移动就会越过覆盖边界点,所以他的泛化误差没有分类器A的好,也就是说,它对未知数据的预测能力较差。所以这样就引出SVM的一个核心思想就是:找到一个超平面,是得其到所有点的距离是最大的。
接下里开始一步一步的去学习SVM吧!!!!!!!!!!!!!
这里的数据集D,以及y的取值如下:
在这里,这个超平面可以用函数
当f(x) 等于0的时候,x便是位于超平面上的点,而f(x) 大于0的点对应 y=1 的数据点,也就是+1类的数据点;f(x)小于0的点对应y=-1的点,也就是-1类的数据。(注意:这里y 为了描述方便取值为{-1,+1}),通过上面的定义,我们知道,所谓的支持向量,就是使得上式等号成立,即y=1和y=-1,在两条虚边界线的向量。那么,不难理解当wTx+b的值大于+1,或小于-1的时候,就更加支持“样本的分类”了,所以可以令:
我们可以计算得到空间中任意样本点x到超平面的距离为:
因为yi∈{−1,1} 两个异类支持向量到超平面的距离之和(也称为“间隔”)可表示为:
接下来就是要找到一个超平面来分开两类数据 这个超平面离两类样本都足够远,也就是使得“间隔”最大。即最终确定的参数w和b 使得r最大。即满足条件:
将||w||用矩阵表示后,等价于:
这样就得到了SVM的基本型。可以看到,上面的基本型目标函数是二次的,约束条件是线性的,这是一个凸二次规划问题(convex optimization)。
详细可能可以见一下推导过程:
解决凸优化问题可以采用“凸二次规划”,这里采用对偶化更简单。通过使用拉格朗日乘子法可以将凸优化问题转换为“对偶问题”。
对原问题这样一个有限制的问题:
对(1)式每一个约束(共有m个约束,yi(wTxi+b)≥1,添加拉格朗日乘子 αi≥0 ,则整个问题的拉格朗日函数可写为:
这样通过该添加拉格朗日乘子,将具有约束条件的目标函数,变成没有约束条件的问题来解决:
从有约束到无约束,看看这二者是否是等价的:
令:
假设,将(w,b)的数据集分为两部分:
一部分是Δ>0,一部分是Δ<0;对于(xi,yi)数据样本来说:
这样就验证了,二者是的等价的。所以优化1/2∥w∥ 2等价于优化L(w,b,α) 且约束条件αi≥0 。
于是,我们的目标函数可以表示为:
满足一定条件下,等价于(注意,这个满足一定条件,是指满足KKT条件),上式,后者把最小和最大的位置交换,这样使得运算方便起来。
其中,这里面使用到的对偶是强对偶:
即使上式相等的时候。
紧接着对上式继续求解。先令L(w,b,α) 对w,b 求偏导为0,可得:
将此两个式子带入式L(w,b,α)消去w,b ,便得到了原问题的对偶问题。
详细过程可参看一下步骤:
这样,可以总结一下以上求的一个过程,如下图所示:
由带约束的原问题,通过拉格朗日乘子变为不带约束的问题,再根据强对偶关系将不带约束的问题转化为更好求的强对偶问题。通过对w,b求min,得到求得最大的λ值时的表达式:
原问题的对偶问题具有强对偶关系 等价于 满足KKT条件
于是,上面的过程,需要满足的KKT条件是:
对于任意样本,总有αi=0或者 yi(wTxi+b)=1 若αi=0 则由
知w=0, 则此αi对应的向量不会对 f(x)的确定有任何影响对应的向量不会对 f(x) 的确定有任何影响。当ai>0时,必有
这就是,松弛互补条件(slackness complementary),此时αi 对应的向量在最大间隔的边缘上(一开始示意图的虚线上),即是支持向量。这也说明,最终模型的确定,只与支持向量有关。
详细过程如下:
这样就求得了所有的变量:
在Hard-margin SVM中认为数据时立项可分的,但实际情况下,数据时不可分,或者说数据可分但其本书含有噪声的。所以这里引入了soft-Margin。它的思想是允许有一点点错误,这一点错误用loss函数来表达。关于loss函数,可以采用的思想有:
这个代码例子使用Hard-Margin SVM,同时数据时线性可分的
import numpy as np import pylab as pl #画图用 from sklearn import svm #随机生成两组二位数据 np.random.seed(0)#使每次产生随机数不变 X = np.r_[np.random.randn(20,2)-[2,2],np.random.randn(20,2)+[2,2]]#注意这里np.r_[],而不是np.r_()我都打错了,会报错TypeError: 'RClass' object is not callable #np.r_是按列连接两个矩阵,就是把两矩阵上下相加,要求列数相等,np.c_是按行连接两个矩阵,就是把两矩阵左右相加,要求行数相等 Y = [0] * 20+[1] * 20#Python原来可以这么简单的创建重复的列表呀 clf=svm.SVC(kernel='linear') clf.fit(X,Y) w=clf.coef_[0] a=-w[0]/w[1] xx=np.linspace(-5,5)#产生-5到5的线性连续值,间隔为1 yy=a*xx-(clf.intercept_[0])/w[1] #clf.intercept_[0]是w3.即为公式a1*x1+a2*x2+w3中的w3。(clf.intercept_[0])/w[1]即为直线的截距 #得出支持向量的方程 b=clf.support_vectors_[0] yy_down=a*xx+(b[1]-a*b[0])#(b[1]-a*b[0])就是简单的算截距 b=clf.support_vectors_[-1] yy_up=a*xx+(b[1]-a*b[0]) print("w:",w) #打印出权重系数 print("a:",a) #打印出斜率 print("suport_vectors_:",clf.support_vectors_)#打印出支持向量 print("clf.coef_:",clf.coef_) #打印出权重系数,还是w #这个就是画出来而已。很简单,也不太常用,都用matplotlib去了。不多说了 pl.plot(xx,yy,'k-') pl.plot(xx,yy_down,'k--') pl.plot(xx,yy_up,'k--') pl.scatter(clf.support_vectors_[:,0],clf.support_vectors_[:,0],s=80,facecolors='none') pl.scatter(X[:,0],X[:,1],c=Y,cmap=pl.cm.Paired) pl.axis('tight') pl.show()
以下结果的数据量级(单类数据量级):20,200,500,1000结果为:
本篇内容主要介绍了SVM支持向量机,分别介绍了Hard-Margin SVM中的凸优化、KKT约束、对偶化问题,而且还介绍了Soft-margin SVM的思想,并对SVM的Hard-Margin模型进行验证。这篇文章就到这里了,欢迎大佬们多批评指正,也欢迎大家积极评论多多交流。
1 支持向量机(SVM)从入门到放弃再到掌握
2 支持向量机通俗导论(理解SVM的三层境界)
3 机器学习中的损失函数 (着重比较:hinge loss vs softmax loss)
4 机器学习技法–Soft-Margin SVM
5 SVM原理介绍
6 SVM如何用于回归分析
7 菜鸟之路——机器学习之SVM分类器学习理解以及Python实现
8 理论:SVM理论解析及python实现 :SMO方法的核心功能实现
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。