支持向量机(Support Vector Machine,SVM),监督学习,二元分类的广义线性分类。
他的基本模型是在特征空间中寻找间隔最大化的分离超平面的线性分类器。
概括
SVM 是一种二分类模型,她的基本思想是在特征空间中寻找间隔最大的分类超平面使得数据得到高效的二分类。
学习策略
间隔最大化,可形式化一个求解凸二次函数规划的问题,也等价于正则化的合页损失函数的最小化问题,支持向量机的学习算法是求解凸二次规划的最优化问题。
分类
- 线性可分支持向量机,又称硬间隔支持向量机(当训练数据线性可分的时候,通过硬间隔最大化 hard margin maximization学习线性的分类器)
- 线性支持向量机,又称软间隔支持向量机(当训练数据近似线性可分的时候,引入松弛变量,通过软间隔最大化 soft margin maximization学习线性的分类器)
- 非线性支持向量机(当训练数据线性不可分时,通过使用核技巧及软间隔最大化,学习非线性支持向量机)
基本知识
- 感知机和线性可分支持向量机的区别
感知机利用误分类最小的策略,求的分离超平面,此时解有无穷多个。线性可分支持向量机利用间隔最大化求最优超平面,解是唯一的。 - 拉格朗日乘子
参考机器学习基础 - 函数间隔和几何间隔
在支持向量机中,一个点距离分离超平面的远近可以表示分类预测的确信程度。在超平面确定的情况下,可以使用函数间隔来表示分类的正确性和确信度。
对于给定的训练数据集T和超平面(w,b),定义超平面(w,b)关于样本点(x_i,y_i)的函数间隔为:
γ ^ i = y i ( w T x i + b ) \hat{\gamma}_{i}=y_{i}\left(w^{T} x_{i}+b\right) γ^i=yi(wTxi+b)
定义超平面(w,b)关于训练数据集T的函数间隔为超平面(w,b)关于T中所有样本点(x_i,y_i)的函数间隔之最小值,即:
γ ^ = min i = 1 , ⋯ , N γ ^ i \hat{\gamma}=\min _{i=1, \cdots, N} \hat{\gamma}_{i} γ^=i=1,⋯,Nminγ^i
对于给定的训练数据集T和超平面(w,b),定义超平面(w,b)关于样本点 的几何间隔为:
γ
i
=
y
i
(
w
T
∥
w
∥
⋅
x
i
+
b
∥
w
∥
)
\gamma_{i}=y_{i}\left(\frac{w^{T}}{\|w\|} \cdot x_{i}+\frac{b}{\|w\|}\right)
γi=yi(∥w∥wT⋅xi+∥w∥b)
定义超平面(w,b)关于训练数据集T的几何间隔为超平面(w,b)关于T中所有样本点 的几何间隔之最小值,即:
γ
=
min
i
=
1
,
⋯
,
N
γ
i
\gamma=\min _{i=1, \cdots, N} \gamma_{i}
γ=i=1,⋯,Nminγi
关系:如果||w||=1,那么函数间隔和几何间隔相等,如果超平面参数w和b成比例的改变(超平面没有改变),函数间隔也按此比例改变,几何间隔不变
间隔最大化
SVM学习的基本思想是求解能够正确划分训练数据集并且几何间隔最大的分离超平面。
假设超平面
(
w
,
b
)
(w, b)
(w,b)能将训练样本正确分类,即对于
(
x
i
,
y
i
)
∈
D
\left(x_{i}, y_{i}\right) \in D
(xi,yi)∈D,若
y
i
y_{i}
yi=1,则有
w
T
x
i
+
b
>
0
w^{T} x_{i}+b>0
wTxi+b>0,若
y
i
y_{i}
yi=-1,则有
w
T
x
i
+
b
<
0
w^{T} x_{i}+b<0
wTxi+b<0,令
{
w
T
x
i
+
b
⩾
+
1
,
y
i
=
+
1
w
T
x
i
+
b
⩽
−
1
,
y
i
=
−
1
\left\{\begin{array}{ll}{w^{\mathrm{T}} x_{i}+b \geqslant+1,} & {y_{i}=+1} \\ {w^{\mathrm{T}} x_{i}+b \leqslant-1,} & {y_{i}=-1}\end{array}\right.
{wTxi+b⩾+1,wTxi+b⩽−1,yi=+1yi=−1
如下图所示,距离超平面最近的这几个训练样本点使上式等号成立,他们被称为“支持向量”,两个异类支持向量到超平面的距离只和为
γ
=
2
∥
w
∥
\gamma=\frac{2}{\|w\|}
γ=∥w∥2
它被称为间隔。
欲找到“最大间隔”的分离超平面,也就是要找到上式中约束参数w,b,使得
γ
\gamma
γ最大
max
w
,
b
2
∥
w
∥
s.t.
y
i
(
w
T
x
i
+
b
)
⩾
1
,
i
=
1
,
2
,
…
,
m
\begin{array}{l}{\max _{w, b} \frac{2}{\|w\|}} \\ {\text { s.t. } y_{i}\left(w^{T} x_{i}+b\right) \geqslant 1, \quad i=1,2, \ldots, m}\end{array}
maxw,b∥w∥2 s.t. yi(wTxi+b)⩾1,i=1,2,…,m
即
min
w
,
b
∥
w
∥
2
s.t.
y
i
(
w
T
x
i
+
b
)
⩾
1
,
i
=
1
,
2
,
…
,
m
\begin{array}{l}{\min _{w, b} {\|w\|^2}}\\ {\text { s.t. } y_{i}\left(w^{T} x_{i}+b\right) \geqslant 1, \quad i=1,2, \ldots, m}\end{array}
minw,b∥w∥2 s.t. yi(wTxi+b)⩾1,i=1,2,…,m
这就是支持向量机的基本型。
对偶问题
拉格朗日函数
L
(
w
,
b
,
α
)
=
1
2
∥
w
∥
2
+
∑
i
=
1
m
α
i
(
1
−
y
i
(
w
T
x
i
+
b
)
)
L(\boldsymbol{w}, b, \boldsymbol{\alpha})=\frac{1}{2}\|\boldsymbol{w}\|^{2}+\sum_{i=1}^{m} \alpha_{i}\left(1-y_{i}\left(\boldsymbol{w}^{\mathrm{T}} \boldsymbol{x}_{i}+b\right)\right)
L(w,b,α)=21∥w∥2+i=1∑mαi(1−yi(wTxi+b))
其中
α
i
\alpha_{i}
αi 为拉格朗日乘子,并且
α
i
>
0
\alpha_{i}>0
αi>0
对
L
(
w
,
b
,
α
)
L(\boldsymbol{w}, b, \boldsymbol{\alpha})
L(w,b,α)对w和b的偏导数为零可得
w
=
∑
i
=
1
m
α
i
y
i
x
i
0
=
∑
i
=
1
m
α
i
y
i
\begin{aligned} \boldsymbol{w} &=\sum_{i=1}^{m} \alpha_{i} y_{i} \boldsymbol{x}_{i} \\ 0 &=\sum_{i=1}^{m} \alpha_{i} y_{i} \end{aligned}
w0=i=1∑mαiyixi=i=1∑mαiyi
最终求的对偶形式:
max
α
∑
i
=
1
m
α
i
−
1
2
∑
i
=
1
m
∑
j
=
1
m
α
i
α
j
y
i
y
j
x
i
T
x
j
\max _{\alpha} \sum_{i=1}^{m} \alpha_{i}-\frac{1}{2} \sum_{i=1}^{m} \sum_{j=1}^{m} \alpha_{i} \alpha_{j} y_{i} y_{j} x_{i}^{T} x_{j}
αmaxi=1∑mαi−21i=1∑mj=1∑mαiαjyiyjxiTxj
s.t.
∑
i
=
1
m
α
i
y
i
=
0
α
i
⩾
0
,
i
=
1
,
2
,
…
,
m
\begin{array}{ll}{\text { s.t. }} & {\sum_{i=1}^{m} \alpha_{i} y_{i}=0} \\ {} & {\alpha_{i} \geqslant 0, \quad i=1,2, \ldots, m}\end{array}
s.t. ∑i=1mαiyi=0αi⩾0,i=1,2,…,m
解出
α
\alpha
α,求出
w
w
w和
b
b
b即可得到模型
f
(
x
)
=
w
T
x
+
b
=
∑
i
=
1
m
α
i
y
i
x
i
T
x
+
b
\begin{aligned} f(x) &=w^{\mathrm{T}} x+b \\ &=\sum_{i=1}^{m} \alpha_{i} y_{i} x_{i}^{\mathrm{T}} x+b \end{aligned}
f(x)=wTx+b=i=1∑mαiyixiTx+b
软间隔
到这里都是基于训练集数据线性可分的假设下进行的,但是实际情况下几乎不存在完全线性可分的数据,为了解决这个问题,引入了“软间隔”的概念,即允许某些点不满足约束
(现实任务中往往很难确定合适的核函数使训练样本在线性空间中线性可分,退一步说即使恰好找到了某个核函数使训练集在特征空间上线性可分,也很难确定这个貌似线性可分的结果是不是有过拟合造成的
缓解该问题的一个办法是允许支持向量机在一些样本上出错。为此引入软间隔。
软间隔允许某些样本不满足约束条件。
)
y
j
(
w
⋅
x
j
+
b
)
≥
1
y_{j}\left(\boldsymbol{w} \cdot \boldsymbol{x}_{j}+b\right) \geq 1
yj(w⋅xj+b)≥1
采用hinge损失,讲愿优化问题改写为
min
w
,
b
,
ξ
i
1
2
∥
w
∥
2
+
C
∑
i
=
1
m
ξ
i
s.t.
y
i
(
w
⋅
x
i
+
b
)
≥
1
−
ξ
i
ξ
i
≥
0
,
i
=
1
,
2
,
…
,
N
\begin{array}{c}{\min _{w, b, \xi_{i}} \frac{1}{2}\|\boldsymbol{w}\|^{2}+C \sum_{i=1}^{m} \xi_{i}} \\ {\text {s.t.} \quad y_{i}\left(\boldsymbol{w} \cdot \boldsymbol{x}_{i}+b\right) \geq 1-\xi_{i}} \\ {\xi_{i} \geq 0, i=1,2, \ldots, N}\end{array}
minw,b,ξi21∥w∥2+C∑i=1mξis.t.yi(w⋅xi+b)≥1−ξiξi≥0,i=1,2,…,N
其中
ξ
i
\xi_{i}
ξi 为“松弛变量”,
ξ
i
=
max
(
0
,
1
−
y
i
(
w
⋅
x
i
+
b
)
)
\xi_{i}=\max \left(0,1-y_{i}\left(\boldsymbol{w} \cdot \boldsymbol{x}_{i}+b\right)\right)
ξi=max(0,1−yi(w⋅xi+b)),即一个hinge损失函数。每一个样本都有一个对应的松弛变量,表征该样本不满足约束的程度。C>0 称为惩罚参数, C值越大,对分类的惩罚越大。跟线性可分求解的思路一致,同样这里先用拉格朗日乘子法得到拉格朗日函数,再求其对偶问题。
非线性SVM算法原理
-
核函数
核函数表示将输入空间映射到特征空间得到的特征向量直接的内积。通过核函数可以学习非线性支持向量积,等价于隐式的在高维特征空间中学习线性支持向量机。这种方法称为核技巧。 -
正定核
-
常用核函数
- 线性核
- 多项式核
- 高斯核
- 拉普拉斯核
- sigmoid 核
序列最小优化算法(SMO)
SVM 优点
- 在高维空间中非常有效
- SVM是一个凸优化问题,求得的解一定是全局最优。
- 不仅适用于线性问题还适用于非线性问题
- 拥有高维样本空间的数据也可以使用SVM,这是因为数据的复杂度只取决于支持向量而不是数据的维度
- 理论上比较完善
缺点
- 二次规划问题设计M阶矩阵的计算(m为样本的个数),因此SVM不适用于超大数据集。(SMO算法可以解决这个问题)
- 只适用于二分类问题。(SVM的推广SVR也适用于回归问题,可以通过多个SVM的组合来解决多酚类问题)
实例
- sklearn 库
from sklearn import svm
__all__ = ['LinearSVC',
'LinearSVR',
'NuSVC',
'NuSVR',
'OneClassSVM',
'SVC',
'SVR',
'l1_min_c']
SVC,NuSVC 和LinearSVC能在数据集中实现多分类
"""
SVC LinerSVC NuSVC
"""
from sklearn import svm
import numpy as np
import matplotlib.pyplot as plt
from sklearn import datasets
iris=datasets.load_iris()
print(dir(iris))
# print(iris.DESCR)
print(iris.feature_names)
print(iris.target_names)
print(iris.filename)
"""
['DESCR', 'data', 'feature_names', 'filename', 'target', 'target_names']
['sepal length (cm)', 'sepal width (cm)', 'petal length (cm)', 'petal width (cm)']
['setosa' 'versicolor' 'virginica']
"""
def make_meshgrid(x, y, h=.02):
x_min, x_max = x.min() - 1, x.max() + 1
y_min, y_max = y.min() - 1, y.max() + 1
xx, yy = np.meshgrid(np.arange(x_min, x_max, h),
np.arange(y_min, y_max, h))
return xx, yy
def plot_contours(ax, clf, xx, yy, **params):
Z = clf.predict(np.c_[xx.ravel(), yy.ravel()])
Z = Z.reshape(xx.shape)
out = ax.contourf(xx, yy, Z, **params)
return out
X=iris.data[:,:2]
y=iris.target
C=1.0
models=(svm.SVC(kernel='linear',C=C),
svm.LinearSVC(C=C,max_iter=10000),
svm.SVC(kernel='rbf',gamma=0.7,C=C),
svm.SVC(kernel='poly',degree=3,gamma='auto',C=C)
)
models=(clf.fit(X,y) for clf in models)
titles = ('SVC with linear kernel',
'LinearSVC (linear kernel)',
'SVC with RBF kernel',
'SVC with polynomial (degree 3) kernel')
# Set-up 2x2 grid for plotting.
fig, sub = plt.subplots(2, 2)
plt.subplots_adjust(wspace=0.4, hspace=0.4)
X0, X1 = X[:, 0], X[:, 1]
xx, yy = make_meshgrid(X0, X1)
for clf, title, ax in zip(models, titles, sub.flatten()):
plot_contours(ax, clf, xx, yy,
cmap=plt.cm.coolwarm, alpha=0.8)
ax.scatter(X0, X1, c=y, cmap=plt.cm.coolwarm, s=20, edgecolors='k')
ax.set_xlim(xx.min(), xx.max())
ax.set_ylim(yy.min(), yy.max())
ax.set_xlabel('Sepal length')
ax.set_ylabel('Sepal width')
ax.set_xticks(())
ax.set_yticks(())
ax.set_title(title)
plt.show()
sklearn svm.svc 参数
_impl = 'c_svc'
def __init__(self, C=1.0, kernel='rbf', degree=3, gamma='scale',
coef0=0.0, shrinking=True, probability=False,
tol=1e-3, cache_size=200, class_weight=None,
verbose=False, max_iter=-1, decision_function_shape='ovr',
break_ties=False,
random_state=None):
- C 错误项的惩罚系数。C越大,对分错样本的惩罚程度越大,因此在训练样本中准确率越高,但是泛化能力降低,也就是对测试数据的分类准确率降低。
- kernel: 默认为 rbf
可选参数为
linear
poly
sigmoid
precomputed - gamma
只对rbf poly sigmoid 有效 ,核函数系数 - degree
这个参数只对多项式核函数管用,值多项式核函数的阶数 - coef0
核函数的独立项,只对poly sigmoid 核函数有用 - probability
bool 参数,默认false
是否启用概率估计。这必须在调用fit之前启用,并且fit方法会变慢 - shrinking
默认为false
是否采用启发式收缩方式 - tol
svm停止训练的误差精度 - cache_size
指定训练做需要的内存,一MB为单位指定200 - verbose
默认为false
是否启用详细输出 - max_iter
最大迭代次数
-1 表示不限制 - random_state
伪随机数发生器的种子 - 属性
svc.n_support_: 各类有多少个支持向量
svc.support_:各类的支持向量在训练样本中的索引
svc.support_vectors_:各类所有的支持向量