支持向量机属于上一节中说的硬输出的方法,是从几何角度出发考虑的。
在介绍SVM之前,先解释一下几个基本概念。
函数间隔与几何间隔
一般的,一个点距离分离超平面的远近可以表示分类预测的确信程度。当超平面确定后,的大小能够相对的表示远近,而的符号与类别是否一致则可以表示是否分类正确。因此令
定义函数间隔
但是很明显的会发现这个间隔与的量纲是有关系的,与之前超平面是一样的,但是间隔却差了k倍。因此需要几何间隔
间隔最大化
有了前面关于间隔的定义,或者是关于分类距离的定义,就有了目标。SVM的目标就是: 求解能够将数据集正确划分并且几何间隔最大的分离超平面。
注:对于线性可分的数据,超平面有无数个(等价于感知机),但是间隔最大的只有一个。间隔最大其实是两个要求:
- 能尽可能的将正负例区分开
- 对于难分的点(距离平面较近的点)也有很好的置信把握,即泛化能力会好一些
SVM对应的三种问题类型
根据分类问题,可分为以下三种
- 线性可分与硬间隔最大化
- 线性支持向量机与软间隔最大化
- 非线性支持向量机与核函数
这些会在后面部分中进行详细介绍
支持向量
这个需要看完下面关于三部分的介绍之后,再来了解这个概念。
- 在线性可分的情况下,样本中与超平面距离最近的样本点称为支持向量. 支持向量是满足的点。
- 分隔边界最终只是由支持向量的点决定的,其他距离比较远的点并没有影响。
1.线性可分与硬间隔最大化
先讨论一种最简单的情况,当数据集本身可以线性可分时候(实际数据中可能并没有这么好的性质),我们只要找到对应的超平面即可。从前面的集合图形上我们的目标:希望每个点到超平面的间隔的最小值达到最大,即
数学模型:
因为几何间隔,所以原问题等价于
注意到
- 函数间隔的取值并不影响最优解的求解。(如果w,b是最优解,则也是,函数距离就是和)。所以这里可以取。
- 与是等价的
因此最终优化的问题等价于如下的凸二次规划问题:
解法:关于这个优化问题的解法,在后面会详细给出。可以证明这个解是存在且唯一的。
几何角度
- 过两个类的边界的点的平行线(),有点类似于楚河汉界
- 将两条平行线进行旋转,保证同类划分不变。两者距离就会改变
- 落在两个平行线上的异类点就是支持向量
2.线性支持向量机与软间隔最大化
上一节说的是对线性可分数据的,如果数据本身不可分该怎么办呢,此时线性分割必然存在误分类的点。对于线性不可分我们不可能要求其严格满足上面说的不等式约束。这时我们只能退而求其次:
思路:使得之前的几何间隔尽量大,同时使误分类的个数尽可能少
数学表示:对于每个样本,类似运筹学中的方法我们可以引入一个松弛变量,满足 之前是要求一定要大于等于1,现在因为并不完全可分,所以不一定要大于等于1。
数学模型:
这时候其实可以发现线性可分的相当于是这里的一种特殊情况,即
求解:
该优化问题的拉格朗日函数是
因此原问题等价于
(1)首先求L对的极小
可得
(2) 再对求最大,即有
最后一个条件其实等价于
对于线性可分问题其max函数是一样的,只是约束条件是
【定理】若是上述优化问题的一个解,若存在一个分量,则原始问题的解可按如下形式求得
从中可以发现b的解并不唯一。
最终的分离超平面是
分类的决策函数是
几何角度
- 如果在分解边界上,则,距离是1
- 如果是在两个分界边界中间,
- 越过分界边界,到了另外一边, 这个时候是小于0的,属于误分类,在优化的时候会考虑
合页损失函数:与原优化问题等价的一种损失函数形式
3.非线性支持向量机与核函数
当数据的分布呈现的是一种非线性的时候,用之前的线性分割的方法肯定就会出现问题。比如数据是在一个椭圆内外分布,这个时候就需要先对原始数据做一个映射,然后变成线性可分的。而这里主要用到了核技巧。
【核函数】如果存在一个映射,使得对于所有,函数满足
则为核函数,为映射函数。
核函数的想法是:在学习中只定义核函数,而不显示的定义映射函数,通常映射函数不太好找且不唯一。
在支持向量机中的应用:
如前所述,在支持向量机的对偶问题中,只涉及样本之间的内积运算。
因此可以用核函数代替
常用的核函数
- 多项式核函数
- 高斯核函数
- 字符串核函数
优化算法SMO
前面介绍了SVM中的三类问题,最终都是通过一个凸二次规划进行求解。当样本量较大的时候,SMO是一种相对求解较快的方法。简言之,是采用了启发式算法,每次只更新两个。原始论文可见《Sequential Minimal Optimization A Fast Algorithm for Training Support Vector Machines》
https://www.cnblogs.com/nolonely/p/6541527.html
python实现
sklearn.svc
模块 http://scikit-learn.org/stable/modules/svm.html#svm
主要包含
- SVC 标准的,参数
kernel
可以选择不同的核函数,选择线性时候即是线性SVM
from sklearn import svm
X = [[0, 0], [1, 1]]
y = [0, 1]
clf = svm.SVC()
clf.fit(X, y)
以iris数据为例
### iris数据
from sklearn import datasets, svm
import matplotlib.pyplot as plt
import numpy as np
iris = datasets.load_iris()
X = iris.data[:, :2]
y = iris.target
# model
C = 1.0
model = svm.SVC(kernel='linear', C=C)
model.fit(X, y)
## 绘制可视化图
x1 = X[:,0]
x2 = X[:,1]
h=0.1
x_min, x_max = x1.min()-1, x1.max()+1
y_min, y_max = x2.min()-1, x2.max()+1
xx,yy = np.meshgrid(np.arange(x_min, x_max, h),
np.arange(y_min, y_max, h)) #生成对应的坐标矩阵
Z = model.predict(np.c_[xx.ravel(), yy.ravel()]) # 在新的坐标点上预测分类
Z = Z.reshape(xx.shape)
plt.contourf(xx, yy, Z, cmap=plt.cm.coolwarm, alpha=0.8)
plt.scatter(x1, x2, c=y, cmap=plt.cm.coolwarm, s=20, edgecolors='k')
plt.xlabel('Sepal length')
plt.ylabel('Sepal width')
- NuSVC 与SVC的优化目标函数略微不同
- LinearSVC: 只针对linear kernel
此外,在进行多分类的时候SVC中参数decision_function_shape
可以选择是ovo
还是ovr
。LinearSVC是通过参数multi_class
进行选择,