支持向量机(Support Vector Machine,简称SVM)是Cortes和Vapnik于1995年首先提出的,它在解决小样本、非线性及高维模式识别中表现出许多特有的优势,并能够推广应用到函数拟合等其他机器学习问题中。SVM是我们常用的一种机器学习的分类器,其中的数据设涉及拉格朗日方程,等式优化,梳数理统计等很多问题,但是我这里并不想多说数学的问题,只是想理解其后的原理。
SVM(support vector machine)简单的说是一个分类器,并且是二类分类器。
- Vector:通俗说就是点,或是数据。
- Machine:也就是classifier,也就是分类器。
实际上((support vector)支持向量是在SVM中关键的概念,概念上说决定决策边界的数据叫做支持向量,实际上我们使用SVM就是找到一个超平面,将不同类别的数据分割开来,而那个超平面就是所谓的支持向量。下面的两个图就是例子。
在寻找这个超平面的时候,当然遵循的规则是最大分类间隔,对于一个包含 n 个点的数据集,就像例子中所示的,我们可以很自然地找到很多可以分割如下点的线但是我们肯定很容易知道不同线的分类效果是不一样的,比如红线靠近下半段,而蓝线几乎是在中间的,如果一个新的数据点来了之后根据红线的判断它是属于差类别的,而从蓝线看来他是属于圈类别的,这就出现了如何优化得到最佳分界面的问题。
SVM中,如果存在两类数据,我们举例最简单的二维数据,那么我们就可以把数据画在一个二维平面上,此时我想找到一个决策面(决策边界)去将这两类数据分开。如下图所示:
我们可以发现存在多个决策面可以划分两类数据,但是其中必然存在一个面使得对两类数据的距离最远也就我们所说的分类效果最佳,这对我们以后的预测工作使用积极作用的。实际的计算中,分类器通过不断的调整直线的参数,而后通过计算直线到点距离不断比较当前直线对分类的影响,最终找到符合要求的最佳的直线。
最大分类间隔
那么这里的最佳要求是什么,什么样的直线才是符合要求的,那就是
SVM 通过使用最大分类间隙Maximum Margin Classifier 来设计决策最优分类超平面,而为何是最大间隔,却不是最小间隔呢?因为最大间隔能获得最大稳定性与区分的确信度,从而得到良好的推广能力(超平面之间的距离越大,分离器的推广能力越好,也就是预测精度越高,不过对于训练数据的误差不一定是最小。
我们可以看到分界面的直线是有一定斜率的,我们寻找距离该直线最近的两个类别中的点,也就是粉色和蓝色线所标记出来的点,在这种情况下分界面到两侧最近的距离是等长度的,也是多种情况中距离最大的,可以最清晰的将二者进行分类。
支持向量
前面也说过支持向量,实际上从名字上就能听出来,支持向量的意思就是支撑我们分界面的向量, 可以看到两个支撑着中间红线的蓝线和粉线,它们到中间的红线的距离相等,即我们所能得到的最大的分类间隔 。即可以明白,在分类中一定会有这样的数据点,根据他们来找到符合我们要求的超平面,它们用来计算距离并“支撑”我们得到的哪个超平面,而这些“支撑”的点便叫做支持向量Support Vector。
线性分类器
实际上就是上边举的例子。支持向量机算法如何实现最大分类间隔的任务呢?我们可以先从线性分类器开始理解它,支持向量在没有引入核函数的时候就是一个线性的分类器。而实际的通俗的来说,一个二维平面的分割距离的计算依靠两个东西:
1.将数据尽量的分割在平面的两侧,如果难以分割那么也要尽量减少分割错误的数据点。
2. 存在多个平面时,需要使用一个就算距离的算法来衡量平面的好坏。
线性不可分
线性不可分,则可以理解为自变量和因变量之间的关系不是线性的。实际上,线性可不分的情况更多,我们可以通过将原始空间映射到一个高维空间,如果高维空间中数据集是线性可分的,那么问题就可以解决了。
可以看出来它们实际山就是计算距离的式子。
实际上举个简单的例子就是下面这个图,在平面上看来确实很难分辨,但是映射到高维空间之后我们可以看到数据点变为稍微可以分割的了
matlab中的libsvm
关于来历不想多说,在matlab下这是一个非常好用的svm工具,不过安装的时候可能需要编译一下才能使用,使用的方法十分简单,在以前做东西的使用用过一段时间,并且现在涉及svm的也都是用的MATLAB的这个工具。
具体的安装可以参考下:
https://blog.csdn.net/forever__1234/article/details/78148108
libsvm参数意义
在最初使用的时候最不能理解的就是模型训练出来之后有一堆的参数,以前也没有在意,后来有一段时间觉得了解一下还是有必要的,所以当时就整理了一下。
model =
Parameters: [5x1 double]
nr_class: 2
totalSV: 259
rho: 0.0514
Label: [2x1 double]
ProbA: []
ProbB: []
nSV: [2x1 double]
sv_coef: [259x1 double]
SVs: [259x13 double]
>> model.Parameters
ans =
0
2.0000
3.0000
2.8000
0
model.Parameters参数意义从上到下依次为:
- -s svm类型:SVM设置类型(默认0)
- -t 核函数类型:核函数设置类型(默认2)
- -d degree:核函数中的degree设置(针对多项式核函数)(默认3)
- -g r(gama):核函数中的gamma函数设置(针对多项式/rbf/sigmoid核函数) (默认类别数目的倒数)
- -r coef0:核函数中的coef0设置(针对多项式/sigmoid核函数)((默认0)
即在本例中通过model.Parameters我们可以得知 –s 参数为0;-t 参数为 2;-d 参数为3;-g 参数为2.8(这也是我们自己的输入);-r 参数为0。
nr_class 总分类类别 Label 表示标签
>> model.Label
ans =
1
-1
>> model.nr_class
ans =
2
model.totalSV model.nSV
>> model.totalSV
ans =
259
>> model.nSV
ans =
118
141
重要知识点:
model.totalSV代表总共的支持向量的数目,这里共有259个支持向量;
model.nSV表示每类样本的支持向量的数目,这里表示标签为1的样本的支持向量有118个,标签为-1的样本的支持向量为141。
model.ProbA model.ProbB
关于这两个参数这里不做介绍,使用-b参数时才能用到,用于概率估计。
最后我想截取一下一位师傅的描述 真的是很有意思
武功大侠接受别人的挑战,要求是用一张木板将不同颜色的求分开。可是一看这根本不可能啊现在怎么办呢?当然像所有武侠片中一样大侠桌子一拍,球飞到空中。然后,凭借大侠的轻功,大侠抓起木板,插到了两种球的中间。
现在,从空中的魔鬼的角度看这些球,这些球看起来像是被一条曲线分开了。现实一般的数据是线性不可分的,这个时候,我们就需要像大侠一样,将小球拍起,用木板将小球进行分类。想要让数据飞起,我们需要的东西就是核函数(kernel),用于切分小球的木板,就是超平面。
http://blog.sina.com.cn/s/blog_6646924501018fqc.html
https://blog.csdn.net/hx14301009/article/details/79762666
https://blog.csdn.net/u014433413/article/details/78427574
https://www.cnblogs.com/spoorer/p/6551220.html
https://blog.csdn.net/chaipp0607/article/details/73662441
https://blog.csdn.net/chaipp0607/article/details/73716226
https://www.zhihu.com/question/21094489/answer/86273196、
https://www.cnblogs.com/berkeleysong/articles/3251245.html