SMO算法是John C. Platt在1998年提出的。论文的题目是”Sequential Minimal Optimization:A Fast Algorithm for Training Support Vector Machines”。它很快便成为最快的二次规划优化算法,特别是在针对线性SVM和数据稀疏时性能更优。
当然了,SMO优越性能的背后是其相当复杂的数学推导,所以,我也把这块最难理解的内容放在了整个SVM学习笔记的最后一篇,我将尝试尽可能地把SMO的算法逻辑讲清楚,如有疏忽或错误,欢迎留言讨论。
1. SMO基本原理
我在之前的4篇博客当中,一直有一个遗留问题没有解决,那就是具体如何求解SVM对偶问题,比如我在第3篇博客 SVM解释:三、线性可分的情况 中的公式(3)中表示的优化问题,这个问题在加入了松弛变量和惩罚因子后,也就是我在第4篇博客 SVM解释:四、线性不可分的情况 中的公式(3)中表示的优化问题,具体如下:
min 12∑i,j=1nαiαjyiyjXTiXj−∑i=1nαis.t. 0≤αi≤C ∑j=1mαiyi=0(1)
我们观察一下这个优化问题,X和Y(即训练数据)已知,然后在一定的约束范围内求取最优解(即拉格朗日乘子
α
),使目标函数达到最小值。
实际上,求解此类问题的经典算法有很多,但是放在SVM中的话,会在效率上“不尽人意”。因为观察这个目标函数就会发现,其计算的复杂度是依赖于样本数
n
的,如果SVM中训练的数据集比较大,性能就成了问题。出于提高计算效率的目的,SMO算法应运而生。
总结起来一句话:SMO算法是用来高效地求解公式(1)所示的SVM核心优化问题的
我们知道,解决这样一个有多变量(
n
个
αi
)的优化问题确实比较困难,但是如果能多次迭代,每次选择两个变量优化,同时把其他变量看做是固定的常数,这样“分而治之”的话,问题似乎就容易多了。SMO算法的基本思想正是这样一种“分治法”。
显然,这样做有两个问题需要解决:
这两个问题实际上就是SMO算法的两个组成部分,下面我分别就这两个问题展开阐述。我先说优化计算的过程,最后再谈每次迭代计算是如何选择变量的。
2. 优化计算
2.1 新的优化问题
首先想想为什么要选择两个变量进行优化。假设我选择的是变量
α1,α2
,那就把其他的
n−2
个
αi
看做是固定的常数,因为有约束条件
∑mj=1αiyi=0
存在(公式(1)的第二个约束条件),所以如果我确定了
α1
迭代后的新值,自然可以通过等式关系确定
α2
迭代后的值。
回到(1)式所示的SVM核心优化问题,假设选择的两个变量是
α1,α2
,则此时的目标函数展开如下:
f(α1,α2)=12K11α21+12K22α22+y1y2K12α1α2+y1α1v1+y2α2v2−α1−α2+r(2)
关于这个式子,有以下3点需要说明:
为表示简洁,记
K(Xi,Xj)=Ki,j
,你可能会问,(1)式里面不涉及核函数
K(,)
啊,为什么这里冒出来了?其实没有没核函数的参与,并不影响SMO算法的推导。为了和大多SMO算法相关的文献一致,我将
X1
与
X2
的内积直接用核函数的形式表示了,你可以理解为先用核函数映射,再执行加入松弛变量和惩罚因子的线性分类。
v1,v2
如下表示。其中
α∗i
表示
αi
在上一次迭代中的值。你可以这样理解:每次迭代
α1
与
α2
的值都是由上一轮迭代结束时的
αi
的值计算得到的。
⎧⎩⎨⎪⎪⎪⎪⎪⎪⎪⎪⎪⎪v1=∑i=3nyiα∗iKi1v2=∑i=3nyiα∗iKi2(3)
r
表示常数项的组合,因为与后面的推导无关,我不写出来了。
新的目标函数有了,再看约束条件,根据公式(1)的两个约束条件,可以得到新约束条件如下:
⎧⎩⎨⎪⎪⎪⎪⎪⎪⎪⎪0≤α1≤C0≤α2≤Cy1α1+y2α2=−∑i=3nyiαi=γ(4)
根据公式(2),(4),我们当前得到了一个两个未知数的,带等式与不等式约束的二次优化问题。
2.2 模型分析
二次优化问题是我们熟悉的内容,观察一下上面的公式(4),很显然,这个约束是在边长为
C
的正方形范围内的直线。给约束条件的第3条两侧同时乘
y1
,得到:
α1=y1γ−y1y2α2(5)
那现在只需要考虑
α2
即可了,两变量的优化问题也就变成了单变量的优化问题。我们按照现在的约束条件在Fig.1画出了
α2
的可行域,不论是哪种情况,可行域都是在边长为
C
的正方形中的一条直线段:
大体上说,可行域有两种可能性:
y1
与
y2
异号(一个1,一个-1),此时的直线段斜率为1,如Fig.1(a)所示。我们可以根据
y1,y2
的不同取值以及
γ
的不同范围分析
α2
的取值范围,我用下界
L
和上界
H
表示:
L=max(0,α2−α1)H=min(C,C+α2−α1)(1)
y1
与
y2
同号(都是1,或都是-1),此时的直线段斜率为-1,如Fig.1(b)所示。我们可以根据
y1,y2
的不同取值以及
γ
的不同范围分析
α2
的取值范围,我用下界
L
和上界
H
表示:
L=max(0,α2+α1−C)H=min(C,α2+α1)(2)
那也就是说,现在的优化问题是一个单变量的二次优化,且有一定的约束范围。那下面的思路就清晰了:(1)判断二次项系数的正负;(2)求解极小值;(3)判断极小值和约束范围的关系。
2.3 优化计算
把公式(5)代入公式(2),得到下面的公式(6),这就是单变量二次优化的目标函数:
f(α2)=12(K11+K22−2K12)α22+(AB⋅K12−AB⋅K11+y2v2−y2v1+B+1)α2+r′(6)
其中,
A=y1γ,B=y1y2
,
r′
为常数项,和之前一样,具体的表示我们忽略。
我们知道二次项系数
K11+K22−2K12≥0
,想想什么时候是等于0的呢?就是
X1=X2
的时候,为方便推导,我们暂时假定不会有重复的数据参与计算,也就是说
X1≠X2
,那么
K11+K22−2K12>0
。其实,等于0的情况与大于0的解法是类似的,他是一个一次函数的图像。我们不需要求解极值,直接判断约束区域和一次函数的关系即可。
言归正传,先讨论大于0的情况,此时是一个标准的二次优化问题,是一个开口朝上的抛物线。
令
αnew,unclipped2
表示经过迭代之后,这个二次函数未经剪辑的最小值(也就是极值点)。剪辑在此处的意思是根据约束修正最小值。
令
αnew2
表示经过迭代之后,又剪辑了的最小值(也就是考虑了约束条件的),那么我们有如下结论成立:
αnew2=⎧⎩⎨⎪⎪⎪⎪H, αnew,unclipped2>Hαnew,unclipped2, L≤αnew,unclipped2≤HL, αnew,unclipped2<L(7)
下面求取极值。对公式(6)关于
α2
求导,并令导数为0:
f(α2)′=(K11+K22−2K12)α2+(AB⋅K12−AB⋅K11+y2v2−y2v1+B+1)=0(8)
现在,我把公式(3)中的
v1,v2
带入上面这个公式(8),化简就能知道如何根据上一轮迭代的结果计算出本轮迭代中目标函数的极值了(即
αnew,unclipped2
),再根据约束范围判定最优解即可。但是,后面我会讲到如何选择每轮迭代的两个变量,所以,为了方便后面的讲解,我在此求取极值的时候,按照如下的方式化简:(注意,做法一样,只是在极值表示结果的形式上做了点处理)
先设置两个新的变量
u1,u2
,如下:
⎧⎩⎨⎪⎪⎪⎪⎪⎪⎪⎪⎪⎪u1=∑i=1nyiα∗iKi1+bu2=∑i=1nyiαiKi2+b(9)
我们发现,
u1,u2
就是每一轮迭代中,得到的“临时分类器”对元组
X1
和
X2
分类的结果。同时他们与公式(3)中的
v1,v2
还存在如下的等式关系:
{v1=u1−y1α∗1K11−y2α∗2K21−bv2=u2−y1α∗1K12−y2α∗2K22−b(10)
把公式(9)中的
v1,v2
代入公式(8):
(K11+K22−2K12)α2=AB⋅(K11−K12)+y2(v1−v2)−B+1=(K11+K22−2K12)α∗2+y2(u1−y1−(u2−y2))(11)
公式(11)中,
α∗2
表示
α2
在上一轮迭代结束后的值,为了更形象,记为
αold2
.
记
Ei=ui−yi
,显然,这个值代表预测值与真实值的差。这里不展开谈,你先有个印象,后面讲解选择变量的时候会用到。
记
η=K11+K22−2K12
,令公式(10)两侧同时除
η
,得到下式:
αnew,unclipped2=αold2+y2E1−E2η(12)
公式(12)展示了迭代中变量是如何迭代优化的,当然这还是个未经剪辑的结果,我们考虑他的约束条件形成的可行域,这一点我们上面已经说过了,参见公式(7)。最终得到经过剪辑的
α2
的最优解。再根据公式(4)就可得到
αnew1
.
综上,一轮迭代的优化计算就算是完成了,我们通过上一轮迭代的结果,计算出了本轮迭代中所选取的两个变量的新值。
3. 变量选择
SMO算法中对于变量的选择采用的是一种启发式规则。简单来说,在每轮迭代中,选取优化变量的基本指导思想应该是这样的:每轮迭代会确定一个“临时分类器”。显然,我们不关心这个临时分类器的侧面(
H1,H2
)之外的元组,而只是关心在侧面之上以及侧面之间(即边缘内)的点,所以在下一轮迭代中,就应该在这些关心的元组中选择两个,对它们对应的拉格朗日乘子进行优化,至于优化计算,上面已经说得比较详细了。
虽然大致确定了变量选择的范围,但是到底应该选择哪两个
αi
还是问题,假设选择的是
αi
和
αj
,那么SMO的启发式规则是这样选择的:
- 先确定在当前的分类器中,违反KKT条件的元组
Xi
;
- 根据
Xi
,找到使得
|Ei−Ej|
最大的元组
Xj
;
在解释上面的规则之前,先回顾一下我在上一篇博客中,讲到了加入松弛变量和惩罚因子后,如何根据拉格朗日乘子
αi
确定对应训练元组
Xi
与分类器的关系。相关内容可以参见上一篇博客中的公式(4),我也把它抄在下面:
⎧⎩⎨⎪⎪if αi=0, yi(WXi+b)≥1if αi=C, yi(WXi+b)≤1if 0<αi<C, yi(WXi+b)=1(14)
寻找
αi
:
上面说到,SMO算法的迭代中,我们关心的是那些侧面之上以及侧面之间的点,因此,我们先找那些拉格朗日乘子
0<αi<C
所对应的元组,看看它们是否满足公式(14)表示的KKT条件,直到找到一个不满足的,也就确定了第一个优化变量
αi
;如果都满足、找不到违反KKT的呢,那就再找那些
αi=C
的,最后找
αi=0
的,如果都满足,则SMO算法的迭代终止。
寻找
αj
:
由公式(12)可以知道,本轮迭代的最优解的变化程度与
|Ei−Ej|
是呈正比的,为了加快迭代的速度,我们自然想到得找这种变化大的变量进行优化计算,所以在上一步确定了
αi
后,我们遍历样本集,找到使得
|Ei−Ej|
最大的
Xj
,以它对应的
αj
为另一个优化变量即可。
上面说到,SMO算法的迭代中,我们关心的是那些侧面之上以及侧面之间的点,因此,我们先找那些拉格朗日乘子
0<αi<C
所对应的元组,看看它们是否满足公式(14)表示的KKT条件,直到找到一个不满足的,也就确定了第一个优化变量
αi
;如果都满足、找不到违反KKT的呢,那就再找那些
αi=C
的,最后找
αi=0
的,如果都满足,则SMO算法的迭代终止。
3.
b
值的选择
每轮迭代结束之后,我们都要更新相关的
W
,
b
以及对应每个元组的
Ei
。
W
不用多说了,根据迭代新得到的
α
计算就行,至于
b
则需要找到侧面上的点,结合
W
计算。具体地说,
当
0<α1<C
时,
X1
在侧面上,满足下式:
y1−∑i=1nαiyiKi1=0(3)
根据这个式子,解出此时新的
b
值即可(记为
bnew1
)。计算过程我省略了,直接看结果:
bnew1=−E1−y1K11(αnew1−αold1)−y2K21(αnew2−αold2)+bold(4)
同理,当
0<α2<C
时,
X2
在侧面上,新的
b
值也可以这样计算(记为
bnew2
):
bnew2=−E2−y1K12(αnew1−αold1)−y2K22(αnew2−αold2)+bold(5)
其实,很容易证明得到,当
α1,α2
都在区间
(0,C)
中时,上面两个
b
的计算结果是一致的。那如果现在
α1,α2
都不在区间
(0,C)
中呢,我们就去上面两个
b
的平均值,即
bnew=(bnew1+bnew2)/2
综上,得到
b
的计算公式,即下面的公式(15):
bnew=⎧⎩⎨⎪⎪bnew1, 0<α1<Cbnew2, 0<α2<C(bnew1+bnew2)/2, otherwise(15)
4. SMO算法步骤
到这里,SMO算法的大致介绍总算是说完了。我把它的步骤概括式的总结一下:
- 初始化
α
,一般情况下令初始的
αi
全部为0;
- 选取优化变量
α1
和
α2
,执行相关的优化计算,得到更新后的
α1,α2
;
- 开始新的一轮迭代,重复执行上面的第2步,知道全部的
αi
满足公式(14)的KKT条件以及公式(1)中的约束条件;