阅读提示:1.文章中的斜体符号表示单个元素,加粗斜体表示向量。2.本篇文章公式大多较长,手机端需要左右滑动查看。3.文章中只给出了部分关键代码,如需全部代码可访问我的Github获取:https://github.com/luliu-fighting/Statistical-Learning-Method。代码为之前复现李航的《统计学习方法》的代码,注释没改。
1.前言
在前一篇文章中我们推导出了非线性可分支持向量机最优化问题的数学表达式:
α
m
i
n
1
2
∑
i
=
1
N
∑
j
=
1
N
α
i
α
j
y
i
y
j
K
(
x
i
,
x
j
)
−
∑
i
=
1
N
α
i
s
.
t
.
∑
i
=
1
N
α
i
y
i
=
0
0
≤
α
i
≤
C
{_\boldsymbol{\alpha}^{min}}\ \frac{1}{2}\sum_{i=1}^{N}\sum_{j=1}^{N}\alpha_i \alpha_j y_i y_jK(\boldsymbol{x}_i,\boldsymbol{x}_j)-\sum_{i=1}^{N}\alpha_i \\ s.t.\ \sum_{i=1}^{N}\alpha_i y_i =0 \\ 0 \le \alpha_i \le C
αmin 21i=1∑Nj=1∑NαiαjyiyjK(xi,xj)−i=1∑Nαis.t. i=1∑Nαiyi=00≤αi≤C其中变量
α
i
\alpha_i
αi的个数与样本点
(
x
i
,
y
i
)
(\boldsymbol{x}_i,y_i)
(xi,yi)的个数
N
N
N是相等的,也就是求解的复杂度与训练集的样本个数是成正比的,当训练数据集容量很大时,求解过程会变得十分复杂。为了提高支持向量机的求解效率,Platt在1998年提出了序列最小最优化(sequential minimal optimization, SMO)算法。
SMO算法的基本思路是:将原来的最优化问题分解为若干个子最优化问题,每个子问题都是两个变量的最优化问题,其他变量是固定的可以看作是常量;子问题的求解是比较简单的,因为子问题可以通过解析方法求得具体的值。当所有的变量的解都满足此最优化问题的KKT条件时,那么此时的解就是要求的最优化问题的解。对于SMO算法为什么高效,我的理解是:SMO算法不是每次都对所有的变量进行优化,而是每次按照某种规则选择两个变量进行优化,当所有的解都满足KKT条件时,问题就求解完成了,无论训练样本个数即变量个数有多少,SMO算法每次都只优化更新两个变量。
SMO算法可以分为两个部分,一个是每次如何选取子问题的两个变量,另一个是选取的两个变量的子最优化问题的求解。下文将先讲子问题的求解,再讲变量的选取。
2.两个变量的子最优化问题的求解
2.1 α 1 n e w , α 2 n e w \alpha^{new}_1,\alpha^{new}_2 α1new,α2new的求解
假设此时已经根据变量的选择规则选出了变量
α
1
\alpha_1
α1和
α
2
\alpha_2
α2,注意这里的索引1并不是指
α
\boldsymbol{\alpha}
α的第一个分量,而是指被第一个选择出来要进行优化的分量,也就是说
α
1
\alpha_1
α1可以是
α
\boldsymbol{\alpha}
α中的任意分量。此时,其他变量可以视为常量,所以有:
∑
i
=
1
N
y
i
α
i
=
α
1
y
1
+
α
2
y
2
+
∑
i
=
3
N
y
i
α
i
=
0
α
1
y
1
+
α
2
y
2
=
−
∑
i
=
3
N
y
i
α
i
=
k
\sum_{i=1}^{N}y_i \alpha_i=\alpha_1y_1+\alpha_2y_2+\sum_{i=3}^{N}y_i\alpha_i=0 \\ \alpha_1y_1+\alpha_2y_2=-\sum_{i=3}^{N}y_i\alpha_i=k
i=1∑Nyiαi=α1y1+α2y2+i=3∑Nyiαi=0α1y1+α2y2=−i=3∑Nyiαi=k其中
k
k
k为常数,于是我们可以写出子最优化问题的表达式:
α
1
,
α
2
m
i
n
W
(
α
1
,
α
2
)
=
1
2
K
11
α
1
2
+
1
2
K
22
α
2
2
+
y
1
y
2
K
12
α
1
α
2
−
(
α
1
+
α
2
)
+
y
1
α
1
∑
i
=
3
N
y
i
α
i
K
i
1
+
y
2
α
2
∑
i
=
3
N
y
i
α
i
K
i
2
+
C
o
n
s
t
a
n
t
s
.
t
.
α
1
y
1
+
α
2
y
2
=
k
0
≤
α
1
≤
C
0
≤
α
2
≤
C
{_{\alpha_1,\alpha_2}^{min}}\ W(\alpha_1,\alpha_2)=\frac{1}{2}K_{11}\alpha^2_1+\frac{1}{2}K_{22}\alpha^2_2+y_1y_2K_{12}\alpha_1\alpha_2-(\alpha_1+\alpha_2) \\ +y_1\alpha_1\sum_{i=3}^{N}y_i\alpha_iK_{i1}+y_2\alpha_2\sum_{i=3}^{N}y_i\alpha_iK_{i2}+Constant \\ s.t. \ \alpha_1y_1+\alpha_2y_2=k \\ 0 \le \alpha_1 \le C \\ 0 \le \alpha_2 \le C
α1,α2min W(α1,α2)=21K11α12+21K22α22+y1y2K12α1α2−(α1+α2)+y1α1i=3∑NyiαiKi1+y2α2i=3∑NyiαiKi2+Constants.t. α1y1+α2y2=k0≤α1≤C0≤α2≤C在目标函数中,
K
i
j
=
K
(
x
i
,
x
j
)
K_{ij}=K(\boldsymbol{x}_i,\boldsymbol{x}_j)
Kij=K(xi,xj),
C
o
n
s
t
a
n
t
Constant
Constant代表一些不含
α
1
,
α
2
\alpha_1,\alpha_2
α1,α2的常数项,不影响最优化问题的求解。
由约束条件
α
1
y
1
+
α
2
y
2
=
k
\alpha_1y_1+\alpha_2y_2=k
α1y1+α2y2=k及
y
1
2
=
1
y^2_1=1
y12=1可得:
α
1
=
y
1
(
k
−
α
2
y
2
)
\alpha_1=y_1(k-\alpha_2y_2)
α1=y1(k−α2y2)将目标函数中的
α
1
\alpha_1
α1全部用
α
2
\alpha_2
α2代替可得:
α
2
m
i
n
W
(
α
2
)
=
1
2
K
11
(
k
−
α
2
y
2
)
2
+
1
2
K
22
α
2
2
+
y
2
K
12
(
k
−
α
2
y
2
)
α
2
−
y
1
(
k
−
α
2
y
2
)
−
α
2
+
(
k
−
α
2
y
2
)
∑
i
=
3
N
y
i
α
i
K
i
1
+
y
2
α
2
∑
i
=
3
N
y
i
α
i
K
i
2
+
C
o
n
s
t
a
n
t
{_{\alpha_2}^{min}}\ W(\alpha_2)=\frac{1}{2}K_{11}(k-\alpha_2y_2)^2+\frac{1}{2}K_{22}\alpha^2_2+y_2K_{12}(k-\alpha_2y_2)\alpha_2-y_1(k-\alpha_2y_2)-\alpha_2 \\ +(k-\alpha_2y_2)\sum_{i=3}^{N}y_i\alpha_iK_{i1}+y_2\alpha_2\sum_{i=3}^{N}y_i\alpha_iK_{i2}+Constant
α2min W(α2)=21K11(k−α2y2)2+21K22α22+y2K12(k−α2y2)α2−y1(k−α2y2)−α2+(k−α2y2)i=3∑NyiαiKi1+y2α2i=3∑NyiαiKi2+Constant设
g
(
x
)
g(\boldsymbol{x})
g(x)为对样本
(
x
,
y
)
(\boldsymbol{x},y)
(x,y)的预测标签值,即分离决策函数
f
(
x
)
f(\boldsymbol{x})
f(x)去掉了符号函数输出:
g
(
x
)
=
∑
i
=
1
N
α
i
y
i
K
(
x
i
,
x
)
+
b
g(\boldsymbol{x})=\sum_{i=1}^{N}\alpha_iy_iK(\boldsymbol{x}_i,\boldsymbol{x})+b
g(x)=i=1∑NαiyiK(xi,x)+b由此可以得出:
∑
i
=
3
N
y
i
α
i
K
i
1
=
g
(
x
1
)
−
y
1
α
1
K
11
−
y
2
α
2
K
22
−
b
∑
i
=
3
N
y
i
α
i
K
i
2
=
g
(
x
2
)
−
y
1
α
1
K
11
−
y
2
α
2
K
22
−
b
\sum_{i=3}^{N}y_i\alpha_iK_{i1}=g(\boldsymbol{x}_1)-y_1\alpha_1K_{11}-y_2\alpha_2K_{22}-b \\ \sum_{i=3}^{N}y_i\alpha_iK_{i2}=g(\boldsymbol{x}_2)-y_1\alpha_1K_{11}-y_2\alpha_2K_{22}-b
i=3∑NyiαiKi1=g(x1)−y1α1K11−y2α2K22−bi=3∑NyiαiKi2=g(x2)−y1α1K11−y2α2K22−b对
α
2
\alpha_2
α2求导数并令其等于0:
d
W
d
α
2
=
K
11
α
2
+
K
22
α
2
−
2
K
12
α
2
−
K
11
k
y
2
+
K
12
k
y
2
+
y
1
y
2
−
1
−
y
2
∑
i
=
3
N
y
i
α
i
K
i
1
+
y
2
∑
i
=
3
N
y
i
α
i
K
i
2
=
0
(
K
11
+
K
22
−
2
K
12
)
α
2
=
y
2
(
y
2
−
y
1
+
k
K
11
−
k
K
12
+
∑
i
=
3
N
y
i
α
i
K
i
1
−
∑
i
=
3
N
y
i
α
i
K
i
2
)
\frac{dW}{d\alpha_2}=K_{11}\alpha_2+K_{22}\alpha_2-2K_{12}\alpha_2-K_{11}ky_2+K_{12}ky_2+y_1y_2-1 \\ -y_2\sum_{i=3}^{N}y_i\alpha_iK_{i1}+y_2\sum_{i=3}^{N}y_i\alpha_iK_{i2}=0 \\ (K_{11}+K_{22}-2K_{12})\alpha_2=y_2(y_2-y_1+kK_{11}-kK_{12}+\sum_{i=3}^{N}y_i\alpha_iK_{i1}-\sum_{i=3}^{N}y_i\alpha_iK_{i2})
dα2dW=K11α2+K22α2−2K12α2−K11ky2+K12ky2+y1y2−1−y2i=3∑NyiαiKi1+y2i=3∑NyiαiKi2=0(K11+K22−2K12)α2=y2(y2−y1+kK11−kK12+i=3∑NyiαiKi1−i=3∑NyiαiKi2)将
k
=
α
1
o
l
d
y
1
+
α
2
o
l
d
y
2
∑
i
=
3
N
y
i
α
i
K
i
1
=
g
(
x
1
)
−
y
1
α
1
o
l
d
K
11
−
y
2
α
2
o
l
d
K
22
−
b
∑
i
=
3
N
y
i
α
i
K
i
2
=
g
(
x
2
)
−
y
1
α
1
o
l
d
K
11
−
y
2
α
2
o
l
d
K
22
−
b
k=\alpha^{old}_1y_1+\alpha^{old}_2y_2 \\ \sum_{i=3}^{N}y_i\alpha_iK_{i1}=g(\boldsymbol{x}_1)-y_1\alpha^{old}_1K_{11}-y_2\alpha^{old}_2K_{22}-b \\ \sum_{i=3}^{N}y_i\alpha_iK_{i2}=g(\boldsymbol{x}_2)-y_1\alpha^{old}_1K_{11}-y_2\alpha^{old}_2K_{22}-b
k=α1oldy1+α2oldy2i=3∑NyiαiKi1=g(x1)−y1α1oldK11−y2α2oldK22−bi=3∑NyiαiKi2=g(x2)−y1α1oldK11−y2α2oldK22−b代入上式:
(
K
11
+
K
22
−
2
K
12
)
α
2
n
e
w
,
u
n
c
=
(
K
11
+
K
22
−
2
K
12
)
α
2
o
l
d
+
y
2
(
g
(
x
1
)
−
y
1
−
(
g
(
x
2
)
−
y
2
)
)
(K_{11}+K_{22}-2K_{12})\alpha^{new,unc}_2=(K_{11}+K_{22}-2K_{12})\alpha^{old}_2+y_2\big(g(\boldsymbol{x}_1)-y_1-(g(\boldsymbol{x}_2)-y_2)\big)
(K11+K22−2K12)α2new,unc=(K11+K22−2K12)α2old+y2(g(x1)−y1−(g(x2)−y2))令:
η
=
K
11
+
K
22
−
2
K
12
E
i
=
g
(
x
i
)
−
y
i
\eta=K_{11}+K_{22}-2K_{12} \\ E_i=g(\boldsymbol{x}_i)-y_i
η=K11+K22−2K12Ei=g(xi)−yi则:
α
2
n
e
w
,
u
n
c
=
α
2
o
l
d
+
y
2
(
E
1
−
E
2
)
η
\alpha^{new,unc}_2=\alpha^{old}_2+\frac{y_2(E_1-E_2)}{\eta}
α2new,unc=α2old+ηy2(E1−E2)此时求得的
α
2
n
e
w
,
u
n
c
\alpha^{new,unc}_2
α2new,unc仅仅是根据求导并令导数等于0得到的,还并未考虑到最优化问题的约束条件,其有可能不在约束条件的取值范围内,所以要得到最后的
α
2
n
e
w
\alpha^{new}_2
α2new,还应该知道
α
2
\alpha_2
α2根据约束条件的取值范围。
根据约束条件
α
1
y
1
+
α
2
y
2
=
k
\alpha_1y_1+\alpha_2y_2=k
α1y1+α2y2=k和
0
≤
α
2
≤
C
0 \le \alpha_2 \le C
0≤α2≤C可知,
α
2
\alpha_2
α2的取值范围不仅与其本身有关,而且与
α
1
,
y
1
,
y
2
\alpha_1,y_1,y_2
α1,y1,y2有关。
(1)当
y
1
≠
y
2
y_1 \not= y_2
y1=y2时,因为有
0
≤
α
1
≤
C
0 \le \alpha_1 \le C
0≤α1≤C,所以有:
α
2
n
e
w
=
α
1
o
l
d
−
k
∈
[
0
−
k
,
C
−
k
]
=
[
α
2
o
l
d
−
α
1
o
l
d
,
C
−
α
1
o
l
d
+
α
2
o
l
d
]
\alpha^{new}_2=\alpha^{old}_1-k \in[0-k,C-k]=[\alpha^{old}_2-\alpha^{old}_1,C-\alpha^{old}_1+\alpha^{old}_2]
α2new=α1old−k∈[0−k,C−k]=[α2old−α1old,C−α1old+α2old]即
α
2
o
l
d
−
α
1
o
l
d
≤
α
2
n
e
w
≤
C
−
α
1
o
l
d
+
α
2
o
l
d
\alpha^{old}_2-\alpha^{old}_1 \le \alpha^{new}_2 \le C-\alpha^{old}_1+\alpha^{old}_2
α2old−α1old≤α2new≤C−α1old+α2old再结合
α
2
n
e
w
\alpha^{new}_2
α2new自己的约束
0
≤
α
2
n
e
w
≤
C
0 \le \alpha^{new}_2 \le C
0≤α2new≤C取交集可得:
L
≤
α
2
n
e
w
≤
H
L \le \alpha^{new}_2 \le H
L≤α2new≤H其中:
L
=
m
a
x
(
0
,
α
2
o
l
d
−
α
1
o
l
d
)
H
=
m
i
n
(
C
,
C
−
α
1
o
l
d
+
α
2
o
l
d
)
L=max(0,\alpha^{old}_2-\alpha^{old}_1) \\ H=min(C,C-\alpha^{old}_1+\alpha^{old}_2)
L=max(0,α2old−α1old)H=min(C,C−α1old+α2old)
(2)当
y
1
=
y
2
y_1=y_2
y1=y2时,有:
α
2
n
e
w
=
k
−
α
1
o
l
d
∈
[
k
−
C
,
k
]
=
[
α
2
o
l
d
+
α
1
o
l
d
−
C
,
α
1
o
l
d
+
α
2
o
l
d
]
\alpha^{new}_2=k-\alpha^{old}_1 \in[k-C,k]=[\alpha^{old}_2+\alpha^{old}_1-C,\alpha^{old}_1+\alpha^{old}_2]
α2new=k−α1old∈[k−C,k]=[α2old+α1old−C,α1old+α2old]即
α
2
o
l
d
−
α
1
o
l
d
≤
α
2
n
e
w
≤
C
−
α
1
o
l
d
+
α
2
o
l
d
\alpha^{old}_2-\alpha^{old}_1 \le \alpha^{new}_2 \le C-\alpha^{old}_1+\alpha^{old}_2
α2old−α1old≤α2new≤C−α1old+α2old再结合
α
2
n
e
w
\alpha^{new}_2
α2new自己的约束
0
≤
α
2
n
e
w
≤
C
0 \le \alpha^{new}_2 \le C
0≤α2new≤C取交集可得:
L
≤
α
2
n
e
w
≤
H
L \le \alpha^{new}_2 \le H
L≤α2new≤H其中:
L
=
m
a
x
(
0
,
α
2
o
l
d
+
α
1
o
l
d
−
C
)
H
=
m
i
n
(
C
,
α
1
o
l
d
+
α
2
o
l
d
)
L=max(0,\alpha^{old}_2+\alpha^{old}_1-C) \\ H=min(C,\alpha^{old}_1+\alpha^{old}_2)
L=max(0,α2old+α1old−C)H=min(C,α1old+α2old)将根据约束条件求得的
α
2
n
e
w
\alpha^{new}_2
α2new的取值范围与前面求导得到的
α
2
n
e
w
\alpha^{new}_2
α2new结合,就可以得到
α
n
e
w
\alpha^{new}
αnew的更新公式:
α
2
n
e
w
=
{
H
,
if
α
n
e
w
,
u
n
c
>
H
α
n
e
w
,
u
n
c
,
if
L
≤
α
n
e
w
,
u
n
c
≤
H
L
,
if
α
n
e
w
,
u
n
c
<
L
\alpha^{new}_2 = \begin{cases} H ,&\text{if} \enspace \alpha^{new,unc} > H \\ \alpha^{new,unc} ,&\text{if} \enspace L \le \alpha^{new,unc} \le H \\ L ,&\text{if} \enspace \alpha^{new,unc} < L \\ \end{cases}
α2new=⎩⎪⎨⎪⎧H,αnew,unc,L,ifαnew,unc>HifL≤αnew,unc≤Hifαnew,unc<L根据公式:
y
1
α
1
n
e
w
+
y
2
α
2
n
e
w
=
k
=
y
1
α
1
o
l
d
+
y
2
α
2
o
l
d
y_1\alpha^{new}_1+y_2\alpha^{new}_2=k=y_1\alpha^{old}_1+y_2\alpha^{old}_2
y1α1new+y2α2new=k=y1α1old+y2α2old可得
α
1
n
e
w
\alpha^{new}_1
α1new的更新公式为:
α
1
n
e
w
=
α
1
o
l
d
+
y
1
y
2
(
α
2
o
l
d
−
α
2
n
e
w
)
\alpha^{new}_1=\alpha^{old}_1+y_1y_2(\alpha^{old}_2-\alpha^{new}_2)
α1new=α1old+y1y2(α2old−α2new)至此,子最优化问题的解
(
α
1
n
e
w
,
α
2
n
e
w
)
(\alpha^{new}_1,\alpha^{new}_2)
(α1new,α2new)就得到了。
(
α
1
n
e
w
,
α
2
n
e
w
)
(\alpha^{new}_1,\alpha^{new}_2)
(α1new,α2new)的更新过程代码如下:
alpha2_new = self.alpha[i2] + self.trainlabel[i2]*(E1 - E2)/eta
if alpha2_new < L:
alpha2_new = L
elif alpha2_new > H:
alpha2_new = H
#式(7.109)
alpha1_new = self.alpha[i1] + self.trainlabel[i1]*self.trainlabel[i2]*(self.alpha[i2] - alpha2_new)
2.2 常数b的求解
当
0
<
α
1
n
e
w
<
C
0 < \alpha^{new}_1 < C
0<α1new<C时,根据KKT条件可知:
∑
i
=
1
N
α
i
y
i
K
i
1
+
b
=
y
1
\sum_{i=1}^{N}\alpha_iy_iK_{i1}+b=y_1
i=1∑NαiyiKi1+b=y1所以:
b
1
n
e
w
=
y
1
−
∑
i
=
3
N
α
i
y
i
K
i
1
−
α
1
n
e
w
y
1
K
11
−
α
2
n
e
w
y
2
K
21
b^{new}_1=y_1-\sum_{i=3}^{N}\alpha_iy_iK_{i1}-\alpha^{new}_1y_1K_{11}-\alpha^{new}_2y_2K_{21}
b1new=y1−i=3∑NαiyiKi1−α1newy1K11−α2newy2K21由
E
1
=
∑
i
=
3
N
α
i
y
i
K
i
1
+
α
1
o
l
d
y
1
K
11
+
α
2
o
l
d
y
2
K
21
+
b
o
l
d
−
y
1
E_1=\sum_{i=3}^{N}\alpha_iy_iK_{i1}+\alpha^{old}_1y_1K_{11}+\alpha^{old}_2y_2K_{21}+b^{old}-y_1
E1=i=3∑NαiyiKi1+α1oldy1K11+α2oldy2K21+bold−y1可得:
y
1
−
∑
i
=
3
N
α
i
y
i
K
i
1
=
−
E
1
+
α
1
o
l
d
y
1
K
11
+
α
2
o
l
d
y
2
K
21
+
b
o
l
d
y_1-\sum_{i=3}^{N}\alpha_iy_iK_{i1}=-E_1+\alpha^{old}_1y_1K_{11}+\alpha^{old}_2y_2K_{21}+b^{old}
y1−i=3∑NαiyiKi1=−E1+α1oldy1K11+α2oldy2K21+bold于是可得:
b
1
n
e
w
=
−
E
1
−
y
1
K
11
(
α
1
n
e
w
−
α
1
o
l
d
)
−
y
2
K
21
(
α
2
n
e
w
−
α
2
o
l
d
)
+
b
o
l
d
b^{new}_1=-E_1-y_1K_{11}(\alpha^{new}_1-\alpha^{old}_1)-y_2K_{21}(\alpha^{new}_2-\alpha^{old}_2)+b^{old}
b1new=−E1−y1K11(α1new−α1old)−y2K21(α2new−α2old)+bold
同样,当$ 0 < \alpha^{new}_2 < C$时可以得到:
b
2
n
e
w
=
−
E
2
−
y
1
K
12
(
α
1
n
e
w
−
α
1
o
l
d
)
−
y
2
K
22
(
α
2
n
e
w
−
α
2
o
l
d
)
+
b
o
l
d
b^{new}_2=-E_2-y_1K_{12}(\alpha^{new}_1-\alpha^{old}_1)-y_2K_{22}(\alpha^{new}_2-\alpha^{old}_2)+b^{old}
b2new=−E2−y1K12(α1new−α1old)−y2K22(α2new−α2old)+bold当
0
<
α
1
n
e
w
<
C
0 < \alpha^{new}_1 < C
0<α1new<C并且
0
<
α
2
n
e
w
<
C
0 < \alpha^{new}_2 < C
0<α2new<C时,
b
1
n
e
w
b^{new}_1
b1new和
b
2
n
e
w
b^{new}_2
b2new是相同的,所以
b
n
e
w
=
b
1
n
e
w
=
b
2
n
e
w
b^{new}=b^{new}_1=b^{new}_2
bnew=b1new=b2new,但是若
α
1
n
e
w
,
α
2
n
e
w
\alpha^{new}_1,\alpha^{new}_2
α1new,α2new是0或
C
C
C时,二者就不再相等,这时
b
n
e
w
b^{new}
bnew应取二者的平均值,其实在前一种情况中也是取二者的平均值,因为二者是相同的,所以
b
b
b的更新公式就是:
b
n
e
w
=
b
1
n
e
w
+
b
2
n
e
w
2
b^{new}=\frac{b^{new}_1+b^{new}_2}{2}
bnew=2b1new+b2new参数b的更新过程代码如下:
b1_new = -E1 - self.trainlabel[i1] * self.k[1, 1] * (alpha1_new - self.alpha[i1]) - \
self.trainlabel[i2] * self.k[2, 1] * (alpha2_new - self.alpha[i2]) + self.b
#式(7.116)
b2_new = -E2 - self.trainlabel[i1] * self.k[1, 2] * (alpha1_new - self.alpha[i1]) - \
self.trainlabel[i2] * self.k[2, 2] * (alpha2_new - self.alpha[i2]) + self.b
if 0 < alpha1_new < self.C:
b_new = b1_new
elif 0 < alpha2_new < self.C:
b_new = b2_new
else:
# 选择中点,P148倒数第二段
b_new = (b1_new + b2_new) / 2
3.变量的选择方法
SMO算法在每个子问题中选择两个变量进行优化,其中至少一个变量时违反KKT条件的(具体可参考李航《统计学习方法》P128,需要pdf版的可以私聊获取)。
3.1 第一个变量的选择
选择第一个变量的过程为外层循环,外层循环在训练样本中选取违反KKT条件最严重的样本点,并将其对应的变量作为第一个变量。即检验样本
(
x
i
,
y
i
)
(\boldsymbol{x}_i,y_i)
(xi,yi)是否满足KKT条件(由李航《统计学习方法》P128推出来的):
{
α
i
=
0
,
y
i
g
(
x
i
)
≥
1
0
<
α
i
<
C
,
y
i
g
(
x
i
)
=
1
α
i
=
C
,
y
i
g
(
x
i
)
≤
1
\begin{cases} \alpha_i=0,y_ig(\boldsymbol{x}_i) \ge 1\\ 0 < \alpha_i < C,y_ig(\boldsymbol{x}_i)=1\\ \alpha_i=C,y_ig(\boldsymbol{x}_i) \le 1 \end{cases}
⎩⎪⎨⎪⎧αi=0,yig(xi)≥10<αi<C,yig(xi)=1αi=C,yig(xi)≤1其中
g
(
x
i
)
=
∑
j
=
1
N
α
j
y
j
K
(
x
i
,
x
j
)
+
b
g(\boldsymbol{x}_i)=\sum_{j=1}^{N}\alpha_jy_jK(\boldsymbol{x}_i,\boldsymbol{x}_j)+b
g(xi)=∑j=1NαjyjK(xi,xj)+b。
在检验过程中,外层循环首先遍历在间隔边界上的样本点,即
0
<
α
i
<
C
0 < \alpha_i < C
0<αi<C的样本点,因为这些点比较容易违反KKT条件;如果这些点都满足KKT条件,再遍历剩下的点。判断是否符合KKT条件的代码如下:
#判断样本是否满足KKT条件,用于SMO中第一个变量的选择
def isSatisfyKKT(self, i):
y_g = self.calcGxi(i) * self.trainlabel[i]
#式(7.111)-式(7.113)
if (self.alpha[i] == 0) and (y_g >= 1):
return True
elif (0 < self.alpha[i] < self.C) and (y_g == 1):
return True
elif (self.alpha[i] == self.C) and (y_g <= 1):
return True
else:
return False
3.2 第二个变量的选择
选择第二个变量的过程为内层循环,假设外层循环已经找到第1个变量 α 1 \alpha_1 α1,内层循环则是要找到第二个变量 α 2 \alpha_2 α2。第二个变量的选择标准时希望能使 α 2 \alpha_2 α2有足够大的变化。在前面的推导中,我们可以看到 α 2 n e w \alpha^{new}_2 α2new是依赖于 ∣ E 1 − E 2 ∣ |E_1-E_2| ∣E1−E2∣的,当 ∣ E 1 − E 2 ∣ |E_1-E_2| ∣E1−E2∣较大时, α 2 \alpha_2 α2的更新速度也会较快,这样就加快了计算速度。所以在选择第二个样本点时,可以使 ∣ E 1 − E 2 ∣ |E_1-E_2| ∣E1−E2∣的值最大的 α 2 \alpha_2 α2。因为已经确定了 α 1 \alpha_1 α1,这样 E 1 E_1 E1的值就确定了。如果 E 1 E_1 E1是正的,那么选择最小的 E i E_i Ei作为 E 2 E_2 E2,如果 E 1 E_1 E1是负的,那么选择最大的 E i E_i Ei作为 E 2 E_2 E2,这样就能最大化 ∣ E 1 − E 2 ∣ |E_1-E_2| ∣E1−E2∣了,因为在每次迭代中都需要判断 ∣ E 1 − E 2 ∣ |E_1-E_2| ∣E1−E2∣的值,所以可以将所有 E i E_i Ei值保存在一个列表中,当然,在每次迭代后,因为 α 1 \alpha_1 α1和 α 2 \alpha_2 α2都变了,因此也需要对 E i E_i Ei列表进行更新。计算 E i E_i Ei的代码如下:
#计算g(xi)
def calcGxi(self, i):
#式(7.104)
gxi = self.b
for j in range(self.m):
#在“7.2.3支持向量”开头第一句话有说到“对应于α > 0的样本点
# (xi, yi)的实例xi称为支持向量”。也就是说只有支持向量的α是大于0的,在求和式内的
# 对应的αi*yi*K(xi, xj)不为0,非支持向量的αi*yi*K(xi, xj)必为0,也就不需要参与
# 到计算中。也就是说,在g(xi)内部求和式的运算中,只需要计算α>0的部分,其余部分可
# 忽略。因为支持向量的数量是比较少的,这样可以再很大程度上节约时间
# 从另一角度看,抛掉支持向量的概念,如果α为0,αi*yi*K(xi, xj)本身也必为0,从数学
# 角度上将也可以扔掉不算
if self.alpha[j] == 0:
continue
else:
gxi += self.alpha[j] * self.trainlabel[j] * self.k[j, i]
return gxi
#计算序列最小最优化算法的(SMO)中的E(i)
def calcEi(self, i):
#式(7.105)
return self.calcGxi(i) - self.trainlabel[i]
两个变量的选择过程代码如下:
#SMO中两个变量的选择
def getAlpha(self):
#根据P147的中间那段话
#先找出满足条件0<alpha[i]<C的样本点,检验是否满足KKT条件
index_list = np.array([i for i in range(self.m) if 0 < self.alpha[i] < self.C])
#如果index_list中的样本均满足KKT条件,则遍历剩下的样本点,检验是否满足KKT条件
index_other = np.array([i for i in range(self.m) if i not in index_list])
index = np.hstack([index_list, index_other])
for i in index:
#在Debug过程中发现hstack指令会将int型变为float型,所以要进行调整
i = int(i)
if self.isSatisfyKKT(i):
continue
#选择样本中违反KKT条件最严重的样本点作为第一个变量
E1 = self.E[i]
#根据P147倒数第二段选择第二个变量
if E1 >= 0:
j = self.E.index(min(self.E))
else:
j = self.E.index(max(self.E))
return i, j
4.参考资料
1.李航《统计学习方法》
2.https://www.jianshu.com/p/eef51f939ace
3.https://zhuanlan.zhihu.com/p/248862271
4.https://github.com/Dod-o/Statistical-Learning-Method_Code
5.https://github.com/fengdu78/lihang-code