支持向量机学了很久,有些地方始终没明白,觉得很有必要总结一下:
1. 线性可分支持向量机:
然后将中间的平面(也可以是分离平面或超平面)往左平移,当第一次经过一个数据点的时候,就不能再平移了,算是达到了最大的限度,意思就是如果再平移,将有点在该平移平面的右侧,将达不到分离的效果了。当把中间的这个平面往右平移经过同样的步骤,这样就又得到了两个支持平面(这里暂且这样叫),这时的效果如下:
支持向量机给出的标准是:当两个支持平面中间的距离达到最大值,那么就认为中间的分离平面是最好的,也就是中间的区域越宽,那么冗余度越大,分离的效果也就越好。但是要注意我们要求的不是两个支持平面,而是中间的分离平面。而中间的分离平面刚好和两边的支持平面的距离是相等的,即是在中间位置。
就是这种效果,黄色是所谓的隔离地带,两边的是支持平面,在支持平面上的点是支持向量,而我们要求的就是这些个支持向量,求支持向量的算法就是支持向量机,但右边的支持向量是两个,一般应该是一个,这里可能也是一种巧合的情况。下面就要求中间的分离平面。
中间的分离平面:
W⋅X+b=0
W
⋅
X
+
b
=
0
其中
W
W
和都是向量,
W⋅X
W
⋅
X
是内积的形式,其实也是:
既是其几何意义。
现在求 W W 和, b b 可以理解为平面的截距,是平面的法向量。
此时可以通过取适当的 W W 和使得两个支持平面分别为: W⋅X+b=1 W ⋅ X + b = 1 和 W⋅X+b=−1 W ⋅ X + b = − 1 ,此过程的简单推倒为:
两个支持平面的距离d的推到为:
2. 转换为凸优化问题:
从上式可以看出约束有很多,和训练集的个数相同, W W 也是一个向量,而b一个常数。到现在为止都应该是很清晰的。
而解决凸优化问题的方法是拉格朗日乘子法:
∂L∂w=0⇒w=∑ni=1aiyixi ∂ L ∂ w = 0 ⇒ w = ∑ i = 1 n a i y i x i
∂L∂b=0⇒∑ni=1aiyi=0 ∂ L ∂ b = 0 ⇒ ∑ i = 1 n a i y i = 0
为什么求极值问题变成了求偏导的问题,例如:
最下面的是梯度
3. 转化为拉格朗日乘子法的问题
拉格朗日乘子法的几何解释:
从上图可以看出约束是在二维平面上,而要求的极值是三维的,这时就要用到等高线来求,用一个平面去切 f(x,y) f ( x , y ) 得到一个切平面,然后投影到约束所在的平面,直到 f(x,y) f ( x , y ) 的切平面的等高线和约束线相切,此时的切点就是要求的极值点。
看下图:
可以看出此时在切点处的蓝色箭头代表
f(x,y)
f
(
x
,
y
)
在切点处的梯度,红色箭头代表
g(x,y)
g
(
x
,
y
)
在切点处的梯度,方向相反,并且在一条直线上。
理论推导:
注意:上述的推倒是在约束是等式的情况下。
而对于不等式约束的KKT,这里可以简单理解为拉格朗日乘子法的推广。
4. 进一步转化为对偶问题
对于等式约束的拉格朗日函数,可以通过求偏导等于零,还有其它的条件联合求解得到极值,而对于KKT条件的问题,此时还不能求解,但可以进一步简化为:
L(w,b,a)=12||w||2−∑ni=1ai(yi(wTxi+b)−1) L ( w , b , a ) = 1 2 | | w | | 2 − ∑ i = 1 n a i ( y i ( w T x i + b ) − 1 )
∂L∂w=0⇒w=∑ni=1aiyixi ∂ L ∂ w = 0 ⇒ w = ∑ i = 1 n a i y i x i
∂L∂b=0⇒∑ni=1aiyi=0 ∂ L ∂ b = 0 ⇒ ∑ i = 1 n a i y i = 0
代入后得到新的拉格朗日函数:
L(w,b,a)=12∑ni=1ai−12∑ni,j=1aiajyiyjxTixj L ( w , b , a ) = 1 2 ∑ i = 1 n a i − 1 2 ∑ i , j = 1 n a i a j y i y j x i T x j
此时只剩下拉格朗日乘子和样本向量,而样本向量又是已知的,此时只剩下求解拉格朗日系数了,这称为原拉格朗日的对偶问题,可以看出对偶问题的形式更简洁了,只涉及内积,所以更有利于求解核函数的问题。而且中间的计算只涉及支持向量,所以计算规模很小。
对偶后的凸优化问题为:
此时要求解的拉格朗问题多了约束,而原拉格朗日问题可以通过求导代入变为没有约束的求极值,而现在的问题看来明显复杂了些,具体的求解算法后面再说。
5. 松弛变量和惩罚函数
其中要注意的是 εi ε i 代表的是平移量,也就是往分错的点的方向平移的量,分错的点离支持平面越远,那平移的距离越大,但怎样体现出尽量接近分错的点的含义呢?即怎样体现出分错的点越少越好,分错点离边界越近越好?这时的惩罚项系数c和 εi ε i 联合起来就起到这个作用了。
线性不可分问题的最后对偶问题:
和前面一样由凸优化问题变为拉格朗日乘子法,再变为对偶问题。
在有松弛变量的情况下,问题描述差别很大,但转化为对偶后每一个拉格朗日乘子就仅仅多了一个上界。
5. SMO算法求解对偶问题
算法基本思想是每次只更新两个乘子,迭代获得最终解。
既是:
(1)每次按照一定的规则抽出两个乘子,其余的赋给初值,假如抽出的是
α1,α2
α
1
,
α
2
,即
α1,α2
α
1
,
α
2
未知,其余的已知,此时结合约束条件可以求出
α1,α2
α
1
,
α
2
的值,因为这是二元一次的问题,在平面上就可以画出:
(2)然后重复上面的过程按照一定的规则抽取两个乘子,假如是
α3,α4
α
3
,
α
4
,然后又可以求出其值。
(3)迭代循环上述的过程,直到随便抽出两个乘子,它俩的值都不怎么变化了,停止循环。此时也就得到了所有的乘子的值。
在循环过程中为什么留下两个变量,其余的变量赋值,原因很简单,就是通过约束条件,选两个变量其实只有一个自由度。
求解的过程:
现在是其中两个变量未知,其余的变量已知,目标函数是一个二元二次函数,但通过约束条件其中一个变量可以由另一个变量表示出来,代入目标函数后,很明显,目标函数变为一个只含一个变量的一元二次函数,也就是类似于抛物线的函数。既是求抛物线的极值问题,但根据约束条件此极值点可能有三种情况:极值点的点、左边界点和右边界点这三个点,这也就是为什么在SMO的代码中会有约束边界点的判别。
而其中乘子对的选择会用到启发式:
所谓的启发式:就是说在数学上不一定有严格的推倒,但是日常的经验显示往往有很好的效果。
怎么启发的呢?现在我们已经知道
α1,α2
α
1
,
α
2
的值,还有其余的乘子,其中后面的是随便给的初值,下一步选哪俩个作为我们要求解的变量呢?由约束条件可知:
0⩽αi⩽c
0
⩽
α
i
⩽
c
,当
αi=0
α
i
=
0
或者
αi=c
α
i
=
c
时,那么下一次的循环就不再选择该
αi
α
i
作为新一次要求解的变量了,因为它基本上就不会再发生变化了,这是SMO算法的经验总结,所以应该循环求解那些
0<αi<c
0
<
α
i
<
c
的
αi
α
i
,这就是机器学习实战SMO源代码中一些continue跳出循环的原因。
核函数
1. 非线性映射到高维空间:
在线性不可分的情况下,支持向量机首先在低维空间中完成计算,然后通过核函数将输入空间映射到高维特征空间,最终在高维特征空间中构造出最优分离超平面,从而把平面上本身不好分的非线性数据分开。如下图,上面的一堆数据在二维空间无法划分,下面映射到三维空间里则可以划分:
另一种解释:
可以看出从xoy平面映射到xyz平面后,用黄色平面就可以把样本点分开了。
2. 维数灾难
原先低维空间的问题,通过映射函数
ϕ(xi)
ϕ
(
x
i
)
就变为了高维空间的
yi,ϕ(xi)
y
i
,
ϕ
(
x
i
)
的问题了,既是通过映射把低维非线性的问题变为了高维线性的问题。这时就要在高维空间中通过样本求解支持向量机。
这时主要的问题就变成了在高维空间里的计算问题,维数灾难就是关键,这时核函数就发挥重大作用了。
核函数形式化定义,如果原始特征内积是
<x,z>
<
x
,
z
>
<script type="math/tex" id="MathJax-Element-153">
</script>,映射后为
<ϕ(x),ϕ(z)>
<
ϕ
(
x
)
,
ϕ
(
z
)
>
<script type="math/tex" id="MathJax-Element-154"><\phi (x),\phi (z)></script>,那么定义核函数(Kernel)为
k(x,z)=ϕ(x)Tϕ(z)
k
(
x
,
z
)
=
ϕ
(
x
)
T
ϕ
(
z
)
到这里,我们可以得出结论,如果要实现该节开头的效果,只需先计算
ϕ(x)
ϕ
(
x
)
,然后计算
ϕ(x)Tϕ(z)
ϕ
(
x
)
T
ϕ
(
z
)
即可,然而这种计算方式是非常低效的。比如最初的特征是
n
n
维的,我们将其映射到维,然后再计算,这样需要
o(n2)
o
(
n
2
)
的时间。那么我们能不能想办法减少计算时间呢?
先看一个例子,假设x和z都是n维的;
k(x,z)=(xTz)2
k
(
x
,
z
)
=
(
x
T
z
)
2
展开后,得
这个时候发现我们可以只计算原始特征x和z内积的平方(时间复杂度是 O(n) O ( n ) ),就等价与计算映射后特征的内积。也就是说我们不需要花 o(n2) o ( n 2 ) 时间了。
现在看一下映射函数(n=3时),根据上面的公式,得到
也就是说核函数 k(x,z)=(xTz)2 k ( x , z ) = ( x T z ) 2 只能在选择这样的 ϕ ϕ 作为映射函数时才能够等价于映射后特征的内积。
从上面的例子可以看出在低维空间中计算核函数的值就相当于在高维空间中计算映射后的内积。
这时就有一种想法假如对任何的映射
ϕ
ϕ
,我们都能找出一种核函数代替高维的
ϕ
ϕ
内积,那么维数灾难将会被消除,既是给出映射
ϕ
ϕ
,找出核函数。
现在有一定理:可以先在低维空间里找一个合理的核函数k,在此基础上可以构造映射,此映射完全可以达到要求的一种效果,并且k就是
ϕ
ϕ
的核函数。也就是说根本不需要找到
ϕ
ϕ
,只需要在低维空间里给出一个合理的核函数,那么可以证明一定存在一个对应的
ϕ
ϕ
使低维非线性映射为高维的线性,并且这个
ϕ
ϕ
是以k作为有效核函数。但什么样的才是合理的核函数呢?
Mercer定理:
如果函数K是
Rn×Rn→R
R
n
×
R
n
→
R
上的映射(也就是从两个n维向量映射到实数域)。那么如果K是一个有效核函数(也称为Mercer核函数),那么当且仅当对于训练样例
{x(1),x(2),x(3),⋯x(m)}
{
x
(
1
)
,
x
(
2
)
,
x
(
3
)
,
⋯
x
(
m
)
}
,其相应的核函数矩阵是对称半正定的。
Mercer定理表明为了证明K是有效的核函数,那么我们不用去寻找 ϕ ϕ ,而只需要在训练集上求出各个 kij k i j ,然后判断矩阵K是否是半正定(使用左上角主子式大于等于零等方法)即可。
来看一种常用的核函数,高斯核函数:
这时,如果x和z很相近(
||x−z||≈0
|
|
x
−
z
|
|
≈
0
),那么核函数值为1,如果x和z相差很大(
||x−z||≫0
|
|
x
−
z
|
|
≫
0
),那么核函数值约等于0。由于这个函数类似于高斯分布,因此称为高斯核函数,也叫做径向基函数(Radial Basis Function 简称RBF)。它能够把原始特征映射到无穷维。
既然高斯核函数能够比较x和z的相似度,并映射到0到1,回想logistic回归,sigmoid函数可以,因此还有sigmoid核函数等等。
下面有张图说明在低维线性不可分时,映射到高维后就可分了,使用高斯核函数。
核函数可以理解为描述投影样本向量的相似度:数学原理其实就是逼近,就像在高数中可以用泰勒级数展开,用幂函数展开来逼近任意一个函数,或者用傅里叶级数展开来逼近任何一个周期函数。
核函数不仅仅用在SVM上,但凡在一个模型后算法中出现了 <x,z> < x , z > <script type="math/tex" id="MathJax-Element-180"> </script>,我们都可以常使用 k(x,z) k ( x , z ) 去替换,这可能能够很好地改善我们的算法.
在拉格朗日函数中使用核函数简化:
现在就可以用SMO算法继续求解了。
注意,使用核函数后,怎么分类新来的样本呢?线性的时候我们使用SVM学习出w和b,新来样本x的话,我们使用
wTx+b
w
T
x
+
b
来判断,如果值大于等于1,那么是正类,小于等于是负类。在两者之间,认为无法确定。如果使用了核函数后,
wTx+b
w
T
x
+
b
就变成了
wTϕ(x)+b
w
T
ϕ
(
x
)
+
b
,是否先要找到
ϕ(x)
ϕ
(
x
)
,然后再预测?答案肯定不是了,找
ϕ(x)
ϕ
(
x
)
很麻烦,但有:
只需将
<x(i),x>
<
x
(
i
)
,
x
>
<script type="math/tex" id="MathJax-Element-187">
</script>替换成
k(x(i),x)
k
(
x
(
i
)
,
x
)
,然后值的判断同上。
经历了一番折腾,先总结到这,比较粗糙,有理解错误的地方,请大神指出。
参考: http://www.cnblogs.com/jerrylead/archive/2011/03/18/1988406.html
机器学习视频 讲师 黄志洪