1 支持向量机介绍
支持向量机(Support Vector Machine,SVM)常用于数据分类,也可以用于数据的回归预测中。
对于一个二分类,我们得到了以下两种分类器的决策边界(黑线和蓝线):
如果此时新加入一个属于红色数据点的新数据,黑色的线会把这个新的数据集分错,而蓝色的线不会。
以上的例子较为主观,客观地评判分类器的健壮性,我们需要引入一个概念:最大间隔。
最大间隔刻画着当前分类器与数据集的边界,以这两个分类器为例:
可以看到, 蓝色的线最大间隔是大于黑色的线的,所以我们会选择蓝色的线作为我们的分类器。
那么怎么知道那么,有没有更好的分类器,它具有更大的间隔?我们可以用SVM找到最优分类器。
我们将距离当前分类器最近的点,称之为支持向量(即上图圈出来的点)。
支持向量机为我们提供了在众多可能的分类器之间进行选择的原则,从而确保对未知数据集具有更高的泛化性。
1.1 软间隔
假设我们拿到的数据是这样子的:
这种情况并不容易找到最大间隔。
于是就引入了软间隔,相比于硬间隔而言,软间隔允许个别数据出现在间隔带中。
但是,如果没有一个原则进行约束,满足软间隔的分类器也会出现很多条。所以需要对分错的数据进行惩罚,SVC 函数中,有一个参数 C 就是惩罚参数。惩罚参数越小,容忍性就越大。
如C=1时:
C=0.2时:
可以看出惩罚参数 C=0.2 时,SVM 会更具包容性,从而兼容更多的错分样本。
1.2 超平面
有时数据可能没有办法利用线性分类器进行分类:
如果将二维(低维)空间的数据映射到三维(高维)空间中,便可以通过一个超平面对数据进行划分。
所以,我们映射的目的在于使用 SVM 在高维空间找到超平面的能力。
在 SVC 中,我们可以用高斯核函数来实现这以功能:kernel=‘rbf’
此时便完成了非线性分类。
2 SVM理论知识
2.1 SVM最优化问题
上一节我们知道SVM要使分类器的超平面与样本点的间隔最大化,对于任意超平面,可以使用线性方程描述:
在二维空间中,点(x,y)到直线Ax+By+C=0的距离公式为:
如果扩展到n维空间,点 x = (x
1
,x
2
… x
n
)到直线w
T
x + b = 0的距离为:
其中
上一节我们知道支持向量是距离超平面最近的样本点,将这个距离设为d,那么其他点到超平面的距离都会大于d,所以有公式:
不等式左右两边同时除以d,得到:
这里||w||d肯定是一个正数,为了方便推导和优化,可以令其等于1,因为一个常数对目标函数的优化(我们只关注符号变化)并不会有影响,因此有:
将两个方程合并,可简写为:
至此我们就可以得到最大间隔超平面的上下两个超平面:
每个支持向量到超平面的距离为:
由
可得
因此距离d又可以写成:
我们的目标就是最大化这个距离:
这里乘上 2 倍也是为了后面推导,对目标函数没有影响。
通过之前的合并方程,可以得到支持向量:
所以最大距离改写为:
转换为:
之前的公式知道||w||有一个根号,为了方便计算,可得:
所以我们最后需要最优化的问题为:
2.2 对偶问题
2.2.1 拉格朗日乘数法
高等数学中的拉格朗日乘数法是一个等式约束优化问题:
令:
函数L(x,λ)就称为拉格朗日函数,参数λ称为拉格朗日乘子。
问题需要我们利用必要条件找到可能的极值点:
当然具体是否为极值点需根据问题本身的具体情况检验。这个方程组称为等式约束的极值必要条件。
等式约束下的 Lagrange 乘数法引入了l个 Lagrange 乘子,我们将 x
i
和λ
k
一起看作优化变量,共有(n+l)个优化变量。
不等式优化问题,其主要思想是将不等式约束条件转变为等式约束条件,引入松弛变量,将松弛变量也是为优化变量。
以我们的最优化问题为例:
这里引入a
i
2
,得到:
这里加平方主要为了不再引入新的约束条件,如果只引入 a
i
那我们必须要保证a
i
>0才能保证这里的h=0。
由此我们将不等式约束转化为了等式约束,并得到 Lagrange 函数:
通过等式约束的极值必要条件(即上述求极值点的方程组)对其求解,联立方程:
这里λ
i
≥0需要通过几何性质进行证明,这里不展开(因为我不懂)
针对λ
i
a
i
=0有两种讨论情况:
情况一:λ
i
=0,a
i
≠0
此时约束条件g
i
(w)不起作用,且g
i
(w)<0
情况二:λ
i
≠0,a
i
=0
此时约束条件g
i
(w)=0,且λ
i
>0,可以理解为约束条件起作用了
综合可得:λ
i
g
i
(w)=0,且在约束条件起作用时λ
i
>0,g
i
(w)=0;约束不起作用时 λ
i
=0,g
i
(w),<0
由此方程组转换为:
以上便是不等式约束优化优化问题的 KKT(Karush-Kuhn-Tucker) 条件, λ
i
称为 KKT 乘子。
直观来讲就是,支持向量g
i
(w)=0,所以 λ
i
>0即可。而其他向量 g
i
(w)<0,λ
i
=0。
原问题要求:
即
由于
问题可转换为求以下函数最小值:
假设目标函数最小值为p,即:
根据λ
i
≥0,g
i
(w)≤0,可知:
因此L(w,λ)≤p,我们需要找到最优的参数 λ ,使得 L(w,λ) 接近 p,故问题转换为:
故我们的最优化问题转换为:
2.2.2 强对偶性
对偶问题其实就是将:
变成:
将目标函数设为f,有:
即最大的里面挑出来的最小的也要比最小的里面挑出来的最大的要大。这就是弱对偶关系,而强对偶关系是当等号成立时,即:
如果 f是凸优化问题,强对偶性成立。而我们之前求的 KKT 条件是强对偶性的充要条件。(当然,为什么是充要条件我也不知道)
2.2.3 SVM优化
SVM 优化的主问题是:
求解线性可分的 SVM 的步骤为:
第一步:构造拉格朗日函数:
第二步:利用强对偶性转化为:
对参数 w 和 b 求偏导数:
得:
代入原函数中,得:
即:
第三步:由第二步 得:
这是一个二次规划问题(目标函数为二次函数,约束均用线性形式给出的非线性规划问题)(其实也不懂),问题规模正比于训练样本数,常用 SMO(Sequential Minimal Optimization) ,序列最小优化算法求解。
核心思想:每次只优化一个参数,其他参数先固定住,仅求当前这个优化参数的极值。
但是我们的优化目标有约束条件:
没法一次只变动一个参数。可以使用一个参数表示令一个参数的方式解决。具体步骤为:
1.选择两个需要更新的参数λ·
i
和 λ
j
,固定其他参数。于是我们有以下约束:
其中
由此可得
即用λ
i
的表达式代替 λ
j
,这样就相当于把目标问题转化成了仅有一个约束条件的最优化问题,仅有的约束是 λ
i
≥0。
2.对于仅有一个约束条件的最优化问题,可以在 λ
i
上对优化目标求偏导,令导数为零,从而求出变量值 λ
inew
,然后根据 λ
inew
求出 λ
jnew
。
3.多次迭代直至收敛。
第四步:求偏导数时得到:
对于:
两边同乘y
s
:
y
s
2
=1,可得:
为了更具鲁棒性,我们可以求得支持向量的均值:
第五步:w 和 b 都求出来了,我们就能构造出最大分割超平面:
分类决策函数:
其中sign()为阶跃函数:
将新样本点导入到决策函数中既可得到样本的分类。
2.3 软间隔
之前说过软间隔允许个别样本点出现在间隔带里面,即允许部分样本点不满足约束条件:
为了度量这个间隔软到何种程度,我们为每个样本引入一个松弛变量ξ
i
≥0,且:
对应下图:
2.4 优化目标及求解
增加软间隔后我们的优化目标变成了:
C 是一个大于 0 的常数,也就是我们一开始讲到的惩罚项。
针对新的优化目标求解最优化问题:
第一步:
构造拉格朗日函数:
λ和μ是拉格朗日乘子,,w,b和ξ是主问题参数。
根据强对偶性,将对偶问题转换为:
第二步:
分别对主问题参数求偏导数,并令偏导数为 0,得:
代入拉格朗日函数中,得:
最小化结果只有λ而没有μ ,所以只需要最大化λ就好:
和之前不设置软间隔的比较,只是多了个约束条件。
第三步:
求出w和b后就能得到超平面w
T
x+b=0了。
2.5 核函数
2.5.1 线性不可分
我们知道对于线性不可分的样本点需要映射到高维空间,用 x 表示原来的样本点,用 φ(x)表示 x 映射到特征新的特征空间后到新向量。那么分割超平面可以表示为:
对于非线性 SVM 的对偶问题就变成了:
其实就是之前的(x
i
·x
j
),变成了(φ(x
i
)·φ(x
j
))
2.5.2 核函数的作用
低维空间映射到高维空间后维度可能会很大,如果将全部样本的点乘全部计算好,这样的计算量太大了。
但如果我们有这样的一核函数 :
x
i
与x
j
在特征空间的内积等于它们在原始样本空间中通过函数 k(x,y) 计算的结果,就不需要计算高维甚至无穷维空间的内积了。
假设一个多项式核函数:
代入样本点:
其中展开项为:
如果没有核函数,我们则需要把向量映射成:
然后再进行内积计算,才能与多项式核函数达到相同的效果。
可见核函数的引入一方面减少了我们计算量,另一方面也减少了我们存储数据的内存使用量。
2.5.3 常见核函数
线性核函数
多项式核函数
高斯核函数
其中只有高斯核函数是需要调参的。
特征维数高选择线性核
样本数量可观、特征少选择高斯核(非线性核)
样本数量非常多选择线性核(避免造成庞大的计算量)
3 SVM实例
我们调用sklearn的svm,首先导入需要的包:
## 基础函数库
import numpy as np
## 导入画图库
import matplotlib.pyplot as plt
import seaborn as sns
## 导入SVM模型函数
from sklearn import svm
## 生成散点图
from sklearn.datasets.samples_generator import make_blobs
%matplotlib inline
生成一些散点图:
# 画散点图
X, y = make_blobs(n_samples=60, centers=2, random_state=0, cluster_std=0.9)
plt.scatter(X[:, 0], X[:, 1], c=y, s=50, cmap=plt.cm.Paired)
60个样本点,分为两类
调用svm模型进行训练,核函数选择线性函数
from sklearn.svm import SVC
# 惩罚参数:C=1
clf = SVC(C=1, kernel='linear')
clf.fit(X, y)
模型预测
clf.predict(X)
绘制决策边界需要先找出最佳函数,超平面方程一般形式为w1y+w0x+b=0,即y=-w0/w1 * x – b/w1,可以得到斜率为-w0/w1,常数项为-b/w1
# 最佳函数
x_fit = np.linspace(-3,3)#范围
w = clf.coef_[0]
a = -w[0] / w[1]
y_3 = a*x_fit - (clf.intercept_[0]) / w[1]
还可以通过绘制边距查看最大间隔
# 最大边距 下界
b_down = clf.support_vectors_[0]
y_down = a* x_fit + b_down[1] - a * b_down[0]
# 最大边距 上界
b_up = clf.support_vectors_[-1]
y_up = a* x_fit + b_up[1] - a * b_up[0]
首先通过支持向量找到上下界的点,然后通过移动函数截距的方式找到边界函数
最后将其可视化
# 画函数
plt.plot(x_fit, y_3, '-c')
# 画边距
plt.fill_between(x_fit, y_down, y_up, edgecolor='none', color='#AAAAAA', alpha=0.4)
# 画支持向量
plt.scatter(clf.support_vectors_[:, 0], clf.support_vectors_[:, 1], edgecolor='b',
s=80, facecolors='none')
尝试使用SVM对鸢尾花数据集进行分类
##我们利用sklearn中自带的iris数据作为数据载入,并利用Pandas转化为DataFrame格式
import pandas as pd
from sklearn.datasets import load_iris
from sklearn import metrics
from sklearn.model_selection import train_test_split
data = load_iris() #得到数据特征
iris_target = data.target #得到数据对应的标签
iris_features = pd.DataFrame(data=data.data, columns=data.feature_names) #利用Pandas转化为DataFrame格式
##测试集大小为20%,80%/20%分
x_train,x_test,y_train,y_test=train_test_split(iris_features,iris_target,test_size=0.2,random_state=2020)
##训练
clf = SVC(C=1, kernel='linear')
clf.fit(x_train,y_train)
##预测
train_predict=clf.predict(x_train)
test_predict=clf.predict(x_test)
##利用accuracy(准确度)【预测正确的样本数目占总预测样本数目的比例】评估模型效果
print('The accuracy of the train is:',metrics.accuracy_score(y_train,train_predict))
print('The accuracy of the test is:',metrics.accuracy_score(y_test,test_predict))
对于小样本,准确率还是挺高的
总结
SVM有严格的数学理论支持,可解释性强,能找出对任务至关重要的关键样本(即支持向量),不过,虽然决策函数计算的复杂性只取决于支持向量的数目,不在意样本空间维度的大小,但是在训练时,如果采用 SMO 算法,由于每次都需要挑选一对参数,因此时间复杂度为O(N
2
),其中N为训练样本的数量;当采用核技巧时,如果需要存储核矩阵,则空间复杂度为 O(N
2
),因此支持向量机目前只适合小批量样本的任务,无法适应百万甚至上亿样本的任务。
问题
1.什么是支持向量
距离超平面最近的向量
2.支持向量机的推导
见2.1
3.SVM的损失函数
s
yii
表示真实类别的得分,s
j
表示其他类别的得分。Δ 表示为边界值,L
i
表示某输入图像的损失值
4.SVM的核函数有哪些,核函数的作用是什么
见2.5
5.硬间隔和软间隔
是否容许误分类样本
6.SVM可以做多分类吗,怎么做
(1)直接法,直接在目标函数上进行修改,将多个分类面的参数求解合并到一个最优化问题中,通过求解该最优化问题“一次性”实现多类分类。这种方法看似简单,但其计算复杂度比较高,实现起来比较困难,只适合用于小型问题中;
(2)间接法,主要是通过组合多个二分类器来实现多分类器的构造,常见的方法有:
· one-against-one,练时依次把某个类别的样本归为一类,其他剩余的样本归为另一类,这样k个类别的样本就构造出了k个SVM。分类时将未知样本分类为具有最大分类函数值的那类。
· one-against-all,在任意两类样本之间设计一个SVM,因此k个类别的样本就需要设计k(k-1)/2个SVM。当对一个未知样本进行分类时,最后得票最多的类别即为该未知样本的类别。SVC(C-Support Vector Classification)实现基于libsvm,Libsvm中的多类分类就是根据这个方法实现的。
7.SVM可以做回归吗,怎么做
改变约束条件,回归模型的目标是让训练集中的每个样本点尽量拟合到一个线性模型。对于一般的回归模型,我们是用均方误差作为损失函数的,但SVM不是,定义参数ε,SVM回归模型损失函数为:
这里红色的线为损失大小,而在蓝色带里的点都是没有损失的。
以此修改目标函数为:
然后一样进行优化、对偶、超平面计算。(具体比较复杂,还不是很懂)
8.SVM的对偶问题,为什么要把原问题转化为对偶问题
第一:对偶问题将原始问题中的不等式约束转为了对偶问题中的等式约束
第二:方便核函数的引入
第三:改变了问题的复杂度。由求特征向量w转化为求比例系数a,在原始问题下,求解的复杂度与样本的维度有关,即w的维度。在对偶问题下,只与样本数量有关
9.KKT限制条件有哪些
(1)无约束条件
这是最简单的情况,解决方法通常是函数对变量求导,令求导函数等于0的点可能是极值点。将结果带回原函数进行验证即可。
(2)等式约束条件
设目标函数为f(x),约束条件为hk(x),形如
s.t. 表示subject to ,“受限于”的意思,l表示有l个约束条件
(3)不等式约束条件
设目标函数f(x),不等式约束为g(x),有的教程还会添加上等式约束条件h(x)。此时的约束优化问题描述如下: