前言
本文转自 sealyao 的博客,原文链接「CSDN - SVM中的数学和算法」,是我在学习 SVM 的过程中找到的一篇讲解比较透彻的文章,这里转载过来分享给大家,并优化一下原文的排版。
SVM 中的数学和算法
支持向量机(Support Vector Machine)是 Cortes 和 Vapnik 于 1995 年首先提出的,它在解决小样本、非线性及高维模式识别中表现出许多特有的优势,并能够推广应用到函数拟合等其他机器学习问题中。
1 数学部分
1.1 二维空间
支持向量机的典型应用是分类,用于解决这样的问题:有一些事物是可以被分类的,但是具体怎么分类的我们又说不清楚,比如说下图中三角的就是 C1 类,圆圈的就是 C2 类,这都是已知的,好,又来了一个方块,这个方块是属于 C1 呢还是属于 C2 呢,说不清楚。SVM 算法就是试着帮您把这件事情说清楚的。
在二维空间里(这时候样本有两个参照属性),SVM 就是在 C1 和 C2 中间划一条线
g(x)=0
,线儿上边的属于 C1 类,线儿下边的属于 C2 类,这时候方块再来,咱就有章程了。
关于
g(x)=0
得再啰嗦几句,
g(x)
里边的
x
不是横坐标,而是一个向量,
ω
也不是解析几何里边的斜率,也是向量。
ωx
是一个向量积。
对 C1 类中的点:
g(x)>0
;对于 C2 类中的点:
g(x)<0
;
如果我们用
y
来表示类型,+1 代表 C1 类,-1 代表 C2 类。
那么对于所有训练样本而言,都有:
yig(xi)>0
,那么
g(x)=0
就能够正确分割所有训练样本的那条线,只要把
g(x)=0
这条线给找出来就能凑合用了。
这也就只能凑合用,因为满足这个条件的
g(x)=0
太多了,追求完美的我们要的是最优的那条线。怎么才是最优的呢?直觉告诉我们
g(x)=0
这条线不偏向 C1 那边,也不偏向 C2 那边,就应该是最优的了吧。对,学名叫分类间隔,下图红线的长度就是分类间隔。
扫描二维码关注公众号,回复:
3387796 查看本文章
在二维空间中,求分类间隔,可以转化为求点到线的距离,点到线的距离可以表示为
|g(x)||ω|
(向量表示)。为简单计,把整个二维空间归一化(等比放大或缩小),使得对于所有的样本,都有
|g(x)|>=1
,也就是让 C1 和 C2 类中离
g(x)=0
最近的训练样本的
|g(x)|=1
,这时分类间隔就是
2|ω|
,这个间隔越大越好,那么
|ω|
越小越好。
1.2 多维空间
现在我们已经在二维空间中抽象出一个数学问题,求满足如下条件的
g(x)=0
:
min(12|ω|2)st.yig(xi)−1≥0
即在满足
yig(xi)−1≥0
条件下能使
12|ω|2
取最小值的那个
ω
。在二维空间中,
ω
可以近似的理解为斜率,在样本确定,斜率确定的情况下,
g(x)=ωx+b
中的那个b也是可以确定的,整个
g(x)=0
也就确定了。
现在我们讨论的只是二维空间,但是我们惊喜的发现,在二维空间中的结论可以很容易的推广到多维空间。比如说:
我们仍然可以把多维空间中的分割面(超平面)表示为
g(x)=ωx+b=0
。
多维空间中点到面的距离仍然可以表示为
|g(x)||ω|
。如下图,平面表示为
g(x)=ωx+b=0
,
x
是
xp
在面上的投影,
r
是
x
到面的距离,简单推导如下:
ω
向量垂直于平面
g(x)=ωx+b=0
,有:
x=xp+rω|ω|
,
把上式带入
g(x)=ωx+b=0
中,得到
ω(x−rω|w|)+b=0
,
化简得到
ωx+b−r|ω|=0
,所以
g(x)=r|ω|
,向量
x
到平面
g(x)=ωx+b=0
的距离
r=g(x)|ω|
,这和二维空间中结论也是一致的。
现在我们把 SVM 从二维空间推广到多维空间,即求满足如下条件的
g(x)=0
:
min(12|ω|2)st.yi(ωxi+b)−1≥0
1.3 拉格朗日因子
这是一个典型的带约束条件的求极值问题,目标函数是
ω
的二次函数,约束函数是
ω
的线性函数:二次规划问题。求解二次规划问题的一般性方法就是添加拉格朗日乘子,构造拉格朗日函数(理论上这儿应该还有一些额外的数学条件,拉格朗日法才是可用,就略过了)。
具体求解步骤如下:
1.3.1 构造拉格朗日函数
L(ω,b)=12|ω|2−Σiαi(yi(ωxi+b)−1)
其中
ω
和
b
是未知量。
1.3.2 对
ω
和
b
求偏导数,令偏导数为 0
∂(ω)=|ω|−Σiαiyixi=0,即|ω|=Σiαiyixi
∂(b)=Σiαiyi=0,αi≥0
1.3.3 把上式带回拉格朗日函数,得到拉格朗日对偶问题,把问题转化为求解
αi
(12|ω|2−Σiαi(yi(ωxi+b)−1))
=(12|ω|2−Σiαiyixiω−Σiαiyib+Σiαi)
=(Σiαi−12|ω|2)
=(Σiαi−12ΣiΣjαiαjyiyjxixj),αi≥0
1.3.4 最后把问题转化为求解满足下列等式的
αi
min(12ΣiΣjαiαjyiyjxixj−Σiαi),αi≥0
1.4 线性化
好,现在我们再来梳理一下 SVM 的分类逻辑,在空间中找一个分割面(线)把样本点分开,分割面(线)的最优条件就是分类间隔最大化,分类间隔是基于点到平面(直线)的距离来计算的。问题是所有的分割面都是平面,所有的分割线都是直线吗?显然不是。
比如特征是房子的面积
x
,这里的
x
是实数,结果
y
是房子的价格。假设我们从样本点的分布中看到
x
和
y
符合三次曲线,那么我们希望使用
x
的三次多项式来逼近这些样本点。
在二维空间中这是非线性的,这样我们前面的推理都没法用了——点到曲线的距离?不知道怎么算。但是如果把
x
映射到三维空间
Φ(x)=(x,x2,x3)T
,那么对于
Φ(x)
来说,
y=ωΦ(x)+b
就是线性的,也就是说,对于低维空间中非线性的线(面),在映射到高维空间中时,就能变成线性的。于是我们还需要把问题做一个小小的修正,我们面临的问题是求解:
min(12ΣiΣjαiαjyiyjxixj−Σiαi),αi≥0
这里面引入了一个 Kernel,核函数,用于样本空间的线性化。
1.5 松弛变量
上面就是一个比较完整的推导过程,但是经验表明把上述条件丢给计算机进行求解,基本上是无解的,因为条件太苛刻了。实际上,最经常出现的情况如下图红色部分,在分类过程中会出现噪声,如果对噪声零容忍那么很有可能导致分类无解。
为了解决这个问题又引入了松弛变量。把原始问题修正为:
max(12|ω|2)+CΣiγi s t. yi(ωxi+b)≥1−γ, γ≥0
按照拉格朗日法引入拉格朗日因子:
L(ω,b,γ)=(12|ω|2)+CΣiγi−Σiαi(yi(ωxi+b)−1+γi)−Σiμiγi
对上式分别求
ω,b,γ
的导数得到:
∂(ω)=|ω|−Σi,即 |ω|=Σiαiyixi
∂(b)=Σiαiyi=0, ai≥0
∂(γi)=C−αi−μi, αi≥0, μi≥0
带回
L(ω,b,γ)
得到拉格朗日的对偶问题:
min(12ΣiΣjαiαjyiyjKernel(xi,xj)−Σiαi), C≥αi≥0
另外当目标函数取极值时,约束条件一定是位于约束边界(KKT条件),也就是说:
αi(yi(ωxi+b)−1+γi)=0
μiγi=(C−αi)γi=0
分析上面式子可以得出以下结论:
αi=C
时:
γi
可以不为零,就是说该点到分割面的距离小于
1|ω|
,是误分类点。
αi=0
时:
γi
为零,
(yi(ωxi+b)−1+γi)>0
,表示该点到分割面的距离大于
1|ω|
,是正确分类点。
0<αi<C
时:
γi
为零,
(yi(ωxi+b)−1+γi)=0
,该点就是支持向量。
再用数学语言提炼一下:
令
Lω=12ΣiΣjαiαjyiyjKernel(xi,xj)−Σiαi
,其对
αi
的偏导数为:
∂(αi)=yiΣjαjyjKernel(xi,xj)−1
KKT 条件可以表示为:
yi(ωxi+b)=yiΣjαjyjKernel(xi,xj)+b=⎧⎩⎨⎪⎪≥1, αi=01, 0<αi<C≤1, αi=C
用
∂(αi)
表示该 KKT 条件就是:
{−yi∂(αi)≤b, (yi=1,αi<C)or(yi=−1,αi>0)−yi∂(αi)≥b, (yi=1,αi>0)or(yi=−1,αi<C)
若
g(αi)=−yi∂(αi)
,则
所有的
g(αi),(yi=1,αi>0)或者(yi=−1,αi<C)
大于所有的
g(αi),(yi=1,αi<C)或者(yi=−1,αi>0)
。这里
b
作为中间数被忽略了,因为
b
是可以由
αi
推导得到的。
2 算法部分
对于样本数量比较多的时候(几千个),SVM所需要的内存是计算机所不能承受的。目前,对于这个问题的解决方法主要有两种:块算法和分解算法。这里,libSVM采用的是分解算法中的SMO(串行最小化)方法,其每次训练都只选择两个样本。基本流程如下:
这里有两个重要的算法,一个是
α
的选择,另一个是
α
的更新。
2.1
α
的选择算法
选择两个和KKT条件违背的最严重的两个
αi
,包含两层循环:
外层循环:优先选择遍历非边界样本,因为非边界样本更有可能需要调整,而边界样本常常不能得到进一步调整而留在边界上。在遍历过程中找出
(yi=1,αi<C)或者(yi=−1,αi>0)
的所有样本中
−yi∂(αi)
值最大的那个(这个样本是最有可能不满足
−yi∂(αi)≤b
条件的样本。
内层循环:对于外层循环中选定的那个样本
αi
,找到这样的样本
αj
,使得:
⎧⎩⎨⎪⎪⎪⎪(∂(αi)+∂(αj))2(Kernel(i,i)+Kernel(j,j)−2Kernel(i,j)), y1y2=−1(∂(αi)+∂(αj))2(Kernel(i,i)+Kernel(j,j)+2Kernel(i,j)), y1y2=+1
最大,上式是更新
α
中的一个算式,表示的是在选定
αi
,
αj
为更新算子的情况下,
δ(αj)
最大。
如果选择
α
的过程中发现 KKT 条件已经满足了,那么算法结束。
2.2 \alpha 的更新算法
由于SMO每次都只选择2个样本,那么等式约束可以转化为直线约束:
α1+y1y2α2=d(常数)
转化为图形表示为:
那么
α2
的取值范围是:
{L=max(0,α1−α2),H=min(C2,C1+α2−α1),y1y2=−1L=max(0,α2+α1−C1),H=min(C2,α2+α1),y1y2=+1
把
α1+y1y2α2=d
代入
12ΣiΣjαiαjyiyjKernel(xi,xj)−Σiαi
中,得到一个一元二次方程,求极值得到:
⎧⎩⎨⎪⎪αnew∗2=α2+−∂(α1)−∂(α2)K(1,1)+K(2,2)+2K(1,2), y1y2=−1αnew∗2=α2+−∂(α1)−∂(α2)K(1,1)+K(2,2)−2K(1,2), y1y2=+1
最终:
αnew2=⎧⎩⎨⎪⎪H, αnew∗2≥Hαnew∗2, 0<αnew∗2<HL,αnew∗2≥L
2.3 其他
上面说到 SVM 用到的内存巨大,另一个缺陷就是计算速度,因为数据大了,计算量也就大,很显然计算速度就会下降。因此,一个好的方式就是在计算过程中逐步去掉不参与计算的数据。因为,实践证明,在训练过程中,
αi
一旦达到边界(
αi=0
或者
αi=C
),
αi
的值就不会变,随着训练的进行,参与运算的样本会越来越少。
LibSVM 采用的策略是在计算过程中,检测 active_size 中的
αi
值,如果
αi
到了边界,那么就应该把相应的样本去掉(变成 inactived ),并放到栈的尾部,从而逐步缩小 active_size 的大小。
b的计算 ,基本计算公式为:
b=yi−ΣjαjyjKernel(xi,xj)
理论上,
b
的值是不定的。当程序达到最优后,只要用任意一个标准支持向量机(
0<αi<C
)的样本带入上式,得到的
b
值都是可以的。目前,求
b
的方法也有很多种。在 libSVM 中,分别对
y=+1
和
y=−1
的两类所有支持向量求
b
,然后取平均值。