SVM 中的数学和算法

前言

本文转自 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 类。

那么对于所有训练样本而言,都有: y i g ( x i ) > 0 ,那么 g ( x ) = 0 就能够正确分割所有训练样本的那条线,只要把 g ( x ) = 0 这条线给找出来就能凑合用了。

这也就只能凑合用,因为满足这个条件的 g ( x ) = 0 太多了,追求完美的我们要的是最优的那条线。怎么才是最优的呢?直觉告诉我们 g ( x ) = 0 这条线不偏向 C1 那边,也不偏向 C2 那边,就应该是最优的了吧。对,学名叫分类间隔,下图红线的长度就是分类间隔。

在二维空间中,求分类间隔,可以转化为求点到线的距离,点到线的距离可以表示为 | g ( x ) | | ω | (向量表示)。为简单计,把整个二维空间归一化(等比放大或缩小),使得对于所有的样本,都有 | g ( x ) | >= 1 ,也就是让 C1 和 C2 类中离 g ( x ) = 0 最近的训练样本的 | g ( x ) | = 1 ,这时分类间隔就是 2 | ω | ,这个间隔越大越好,那么 | ω | 越小越好。

1.2 多维空间

现在我们已经在二维空间中抽象出一个数学问题,求满足如下条件的 g ( x ) = 0

m i n ( 1 2 | ω | 2 ) s t . y i g ( x i ) 1 0

即在满足 y i g ( x i ) 1 0 条件下能使 1 2 | ω | 2 取最小值的那个 ω 。在二维空间中, ω 可以近似的理解为斜率,在样本确定,斜率确定的情况下, g ( x ) = ω x + b 中的那个b也是可以确定的,整个 g ( x ) = 0 也就确定了。

现在我们讨论的只是二维空间,但是我们惊喜的发现,在二维空间中的结论可以很容易的推广到多维空间。比如说:

我们仍然可以把多维空间中的分割面(超平面)表示为 g ( x ) = ω x + b = 0

多维空间中点到面的距离仍然可以表示为 | g ( x ) | | ω | 。如下图,平面表示为 g ( x ) = ω x + b = 0 x x p 在面上的投影, r x 到面的距离,简单推导如下:

ω 向量垂直于平面 g ( x ) = ω x + b = 0 ,有: x = x p + 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

m i n ( 1 2 | ω | 2 ) s t . y i ( ω x i + b ) 1 0

1.3 拉格朗日因子

这是一个典型的带约束条件的求极值问题,目标函数是 ω 的二次函数,约束函数是 ω 的线性函数:二次规划问题。求解二次规划问题的一般性方法就是添加拉格朗日乘子,构造拉格朗日函数(理论上这儿应该还有一些额外的数学条件,拉格朗日法才是可用,就略过了)。

具体求解步骤如下:

1.3.1 构造拉格朗日函数

L ( ω , b ) = 1 2 | ω | 2 Σ i α i ( y i ( ω x i + b ) 1 )

其中 ω b 是未知量。

1.3.2 对 ω b 求偏导数,令偏导数为 0

( ω ) = | ω | Σ i α i y i x i = 0 | ω | = Σ i α i y i x i

( b ) = Σ i α i y i = 0 , α i 0

1.3.3 把上式带回拉格朗日函数,得到拉格朗日对偶问题,把问题转化为求解 α i

    ( 1 2 | ω | 2 Σ i α i ( y i ( ω x i + b ) 1 ) )

= ( 1 2 | ω | 2 Σ i α i y i x i ω Σ i α i y i b + Σ i α i )

= ( Σ i α i 1 2 | ω | 2 )

= ( Σ i α i 1 2 Σ i Σ j α i α j y i y j x i x j ) , α i 0

1.3.4 最后把问题转化为求解满足下列等式的 α i

m i n ( 1 2 Σ i Σ j α i α j y i y j x i x j Σ i α i ) , α i 0

1.4 线性化

好,现在我们再来梳理一下 SVM 的分类逻辑,在空间中找一个分割面(线)把样本点分开,分割面(线)的最优条件就是分类间隔最大化,分类间隔是基于点到平面(直线)的距离来计算的。问题是所有的分割面都是平面,所有的分割线都是直线吗?显然不是。

比如特征是房子的面积 x ,这里的 x 是实数,结果 y 是房子的价格。假设我们从样本点的分布中看到 x y 符合三次曲线,那么我们希望使用 x 的三次多项式来逼近这些样本点。

在二维空间中这是非线性的,这样我们前面的推理都没法用了——点到曲线的距离?不知道怎么算。但是如果把 x 映射到三维空间 Φ ( x ) = ( x , x 2 , x 3 ) T ,那么对于 Φ ( x ) 来说, y = ω Φ ( x ) + b 就是线性的,也就是说,对于低维空间中非线性的线(面),在映射到高维空间中时,就能变成线性的。于是我们还需要把问题做一个小小的修正,我们面临的问题是求解:

m i n ( 1 2 Σ i Σ j α i α j y i y j x i x j Σ i α i ) , α i 0

这里面引入了一个 Kernel,核函数,用于样本空间的线性化。

1.5 松弛变量

上面就是一个比较完整的推导过程,但是经验表明把上述条件丢给计算机进行求解,基本上是无解的,因为条件太苛刻了。实际上,最经常出现的情况如下图红色部分,在分类过程中会出现噪声,如果对噪声零容忍那么很有可能导致分类无解。

为了解决这个问题又引入了松弛变量。把原始问题修正为:

m a x ( 1 2 | ω | 2 ) + C Σ i γ i     s   t .     y i ( ω x i + b ) 1 γ ,   γ 0

按照拉格朗日法引入拉格朗日因子:

L ( ω , b , γ ) = ( 1 2 | ω | 2 ) + C Σ i γ i Σ i α i ( y i ( ω x i + b ) 1 + γ i ) Σ i μ i γ i

对上式分别求 ω , b , γ 的导数得到:

( ω ) = | ω | Σ i   | ω | = Σ i α i y i x i

( b ) = Σ i α i y i = 0 ,   a i 0

( γ i ) = C α i μ i ,   α i 0 ,   μ i 0

带回 L ( ω , b , γ ) 得到拉格朗日的对偶问题:

m i n ( 1 2 Σ i Σ j α i α j y i y j K e r n e l ( x i , x j ) Σ i α i ) ,   C α i 0

另外当目标函数取极值时,约束条件一定是位于约束边界(KKT条件),也就是说:

α i ( y i ( ω x i + b ) 1 + γ i ) = 0

μ i γ i = ( C α i ) γ i = 0

分析上面式子可以得出以下结论:

α i = C 时:
γ i 可以不为零,就是说该点到分割面的距离小于 1 | ω | ,是误分类点。

α i = 0 时:
γ i 为零, ( y i ( ω x i + b ) 1 + γ i ) > 0 ,表示该点到分割面的距离大于 1 | ω | ,是正确分类点。

0 < α i < C 时:
γ i 为零, ( y i ( ω x i + b ) 1 + γ i ) = 0 ,该点就是支持向量。

再用数学语言提炼一下:

L ω = 1 2 Σ i Σ j α i α j y i y j K e r n e l ( x i , x j ) Σ i α i ,其对 α i 的偏导数为:

( α i ) = y i Σ j α j y j K e r n e l ( x i , x j ) 1

KKT 条件可以表示为:

y i ( ω x i + b ) = y i Σ j α j y j K e r n e l ( x i , x j ) + b = { 1 ,       α i = 0 1 ,   0 < α i < C 1 ,         α i = C

( α i ) 表示该 KKT 条件就是:

{ y i ( α i ) b ,   ( y i = 1 , α i < C ) o r ( y i = 1 , α i > 0 ) y i ( α i ) b ,   ( y i = 1 , α i > 0 ) o r ( y i = 1 , α i < C )

g ( α i ) = y i ( α i ) ,则

所有的 g ( α i ) , ( y i = 1 , α i > 0 ) ( y i = 1 , α i < C )

大于所有的 g ( α i ) , ( y i = 1 , α i < C ) ( y i = 1 , α i > 0 ) 。这里 b 作为中间数被忽略了,因为 b 是可以由 α i 推导得到的。

2 算法部分

对于样本数量比较多的时候(几千个),SVM所需要的内存是计算机所不能承受的。目前,对于这个问题的解决方法主要有两种:块算法和分解算法。这里,libSVM采用的是分解算法中的SMO(串行最小化)方法,其每次训练都只选择两个样本。基本流程如下:

这里有两个重要的算法,一个是 α 的选择,另一个是 α 的更新。

2.1 α 的选择算法

选择两个和KKT条件违背的最严重的两个 α i ,包含两层循环:

外层循环:优先选择遍历非边界样本,因为非边界样本更有可能需要调整,而边界样本常常不能得到进一步调整而留在边界上。在遍历过程中找出 ( y i = 1 , α i < C ) ( y i = 1 , α i > 0 ) 的所有样本中 y i ( α i ) 值最大的那个(这个样本是最有可能不满足 y i ( α i ) b 条件的样本。

内层循环:对于外层循环中选定的那个样本 α i ,找到这样的样本 α j ,使得:

{ ( ( α i ) + ( α j ) ) 2 ( K e r n e l ( i , i ) + K e r n e l ( j , j ) 2 K e r n e l ( i , j ) ) ,   y 1 y 2 = 1 ( ( α i ) + ( α j ) ) 2 ( K e r n e l ( i , i ) + K e r n e l ( j , j ) + 2 K e r n e l ( i , j ) ) ,   y 1 y 2 = + 1

最大,上式是更新 α 中的一个算式,表示的是在选定 α i α j 为更新算子的情况下, δ ( α j ) 最大。

如果选择 α 的过程中发现 KKT 条件已经满足了,那么算法结束。

2.2 \alpha 的更新算法

由于SMO每次都只选择2个样本,那么等式约束可以转化为直线约束:

α 1 + y 1 y 2 α 2 = d ( )

转化为图形表示为:

那么 α 2 的取值范围是:

{ L = m a x ( 0 , α 1 α 2 ) , H = m i n ( C 2 , C 1 + α 2 α 1 ) , y 1 y 2 = 1 L = m a x ( 0 , α 2 + α 1 C 1 ) , H = m i n ( C 2 , α 2 + α 1 ) , y 1 y 2 = + 1

α 1 + y 1 y 2 α 2 = d 代入 1 2 Σ i Σ j α i α j y i y j K e r n e l ( x i , x j ) Σ i α i 中,得到一个一元二次方程,求极值得到:

{ α 2 n e w = α 2 + ( α 1 ) ( α 2 ) K ( 1 , 1 ) + K ( 2 , 2 ) + 2 K ( 1 , 2 ) ,   y 1 y 2 = 1 α 2 n e w = α 2 + ( α 1 ) ( α 2 ) K ( 1 , 1 ) + K ( 2 , 2 ) 2 K ( 1 , 2 ) ,   y 1 y 2 = + 1

最终:

α 2 n e w = { H ,   α 2 n e w H α 2 n e w ,   0 < α 2 n e w < H L , α 2 n e w L

2.3 其他

上面说到 SVM 用到的内存巨大,另一个缺陷就是计算速度,因为数据大了,计算量也就大,很显然计算速度就会下降。因此,一个好的方式就是在计算过程中逐步去掉不参与计算的数据。因为,实践证明,在训练过程中, α i 一旦达到边界( α i = 0 或者 α i = C ), α i 的值就不会变,随着训练的进行,参与运算的样本会越来越少。

LibSVM 采用的策略是在计算过程中,检测 active_size 中的 α i 值,如果 α i 到了边界,那么就应该把相应的样本去掉(变成 inactived ),并放到栈的尾部,从而逐步缩小 active_size 的大小。

b的计算 ,基本计算公式为: b = y i Σ j α j y j K e r n e l ( x i , x j )

理论上, b 的值是不定的。当程序达到最优后,只要用任意一个标准支持向量机( 0 < α i < C )的样本带入上式,得到的 b 值都是可以的。目前,求 b 的方法也有很多种。在 libSVM 中,分别对 y = + 1 y = 1 的两类所有支持向量求 b ,然后取平均值。

猜你喜欢

转载自blog.csdn.net/Neuf_Soleil/article/details/82319110
今日推荐