原始形式梯度下降法求解请参考我的上一篇博客: 硬间隔SVM原始形式梯度下降法求解
1、对偶形式求解原理
引入拉格朗日乘子法
L
(
w
,
b
,
λ
)
=
1
2
∣
∣
w
∣
∣
2
+
∑
i
=
1
N
λ
i
(
1
−
y
i
(
w
T
x
i
+
b
)
)
L(w,b,\lambda) = \frac{1}{2}||w||^2+\displaystyle\sum_{i=1}^N\lambda_i(1-y_i(w^Tx_i+b))
L(w,b,λ)=21∣∣w∣∣2+i=1∑Nλi(1−yi(wTxi+b))
则原问题可以写作:
min
w
,
b
max
λ
L
(
w
,
b
,
λ
)
s
.
t
.
λ
i
≥
0
\min\limits_{w,b}\ \max\limits_{\lambda} \ L(w,b,\lambda) \\s.t. \lambda_i\geq 0
w,bmin λmax L(w,b,λ)s.t.λi≥0
这样写的好处在于:任取一点
(
x
i
,
y
i
)
(x_i,y_i)
(xi,yi)
当 1 − y i ( w T x i + b ) > 0 1-y_i(w^Tx_i+b)>0 1−yi(wTxi+b)>0时, max λ L ( w , b , λ ) = + ∞ \max\limits_{\lambda}\ L(w,b,\lambda) = +\infin λmax L(w,b,λ)=+∞,而当当 1 − y i ( w T x i + b ) < = 0 1-y_i(w^Tx_i+b)<=0 1−yi(wTxi+b)<=0时, max λ L ( w , b , λ ) = 1 2 ∣ ∣ w ∣ ∣ 2 \max\limits_{\lambda}\ L(w,b,\lambda) = \frac{1}{2}||w||^2 λmax L(w,b,λ)=21∣∣w∣∣2
这样 min w , b max λ L ( w , b , λ ) = min w , b ( + ∞ , 1 2 ∣ ∣ w ∣ ∣ 2 ) = min w , b 1 2 ∣ ∣ w ∣ ∣ 2 \min\limits_{w,b}\ \max\limits_{\lambda} \ L(w,b,\lambda) = \min\limits_{w,b} (+\infin,\frac{1}{2}||w||^2) = \min\limits_{w,b}\frac{1}{2}||w||^2 w,bmin λmax L(w,b,λ)=w,bmin(+∞,21∣∣w∣∣2)=w,bmin21∣∣w∣∣2
相当于把不符合条件的点给筛除,而且将约束条件写在了 L L L里,把带约束的原问题变为无约束的原问题
但现,我们首先就要面对带有需要求解的参数
w
,
b
w,b
w,b的方程,而
λ
\lambda
λ又是不等式约束,这个求解过程不好做。所以,我们需要使用拉格朗日函数对偶性,将最小和最大的位置交换一下,这样就变成了:
max
λ
min
w
,
b
L
(
w
,
b
,
λ
)
s
.
t
.
λ
i
≥
0
\max\limits_{\lambda}\ \min\limits_{w,b}\ L(w,b,\lambda) \\s.t. \lambda_i\geq 0
λmax w,bmin L(w,b,λ)s.t.λi≥0
要实现这样的转化,需要满足两个条件:
- 是凸优化问题
- 满足KKT条件
显然我们以及满足了第一个条件,而要满足第二个条件,即要求:
{
∂
L
∂
w
=
0
,
∂
L
∂
b
=
0
λ
i
(
1
−
y
i
(
w
T
x
i
+
b
)
)
=
0
λ
i
≥
0
1
−
y
i
(
w
T
x
i
+
b
)
≤
0
\large\begin{cases}\large\frac{\partial L}{\partial w}=0\ ,\ \frac{\partial L}{\partial b }=0 \\ \lambda_i(1-y_i(w^Tx_i+b))=0 \\\lambda_i\geq0\\1-y_i(w^Tx_i+b)\leq0\end{cases}
⎩⎪⎪⎪⎪⎪⎨⎪⎪⎪⎪⎪⎧∂w∂L=0 , ∂b∂L=0λi(1−yi(wTxi+b))=0λi≥01−yi(wTxi+b)≤0
让我们重新回到原问题,对于
w
,
b
w,b
w,b而言,
min
w
,
b
L
(
w
,
b
,
λ
)
\min\limits_{w,b}L(w,b,\lambda)
w,bminL(w,b,λ)是一个无约束问题,那么对他两求偏导就好了:
对 b b b求偏导, ∂ L ∂ b = ∑ i = 1 N λ i y i = 0 \frac{\partial L}{\partial b} = \displaystyle\sum_{i=1}^N\lambda_iy_i = 0 ∂b∂L=i=1∑Nλiyi=0,其中( ∣ ∣ w ∣ ∣ 2 ||w||^2 ∣∣w∣∣2可以写作 w T w w^Tw wTw)
带入
L
(
w
,
b
,
λ
)
=
1
2
∣
∣
w
∣
∣
2
+
∑
i
=
1
N
λ
i
(
1
−
y
i
(
w
T
x
i
+
b
)
)
L(w,b,\lambda) = \frac{1}{2}||w||^2+\displaystyle\sum_{i=1}^N\lambda_i(1-y_i(w^Tx_i+b))
L(w,b,λ)=21∣∣w∣∣2+i=1∑Nλi(1−yi(wTxi+b)),得:
L
(
w
,
b
,
λ
)
=
1
2
∣
∣
w
∣
∣
2
+
∑
i
=
1
N
λ
i
−
∑
i
=
1
N
λ
i
y
i
w
T
x
i
L(w,b,\lambda) = \frac{1}{2}||w||^2+\displaystyle\sum_{i=1}^N\lambda_i-\displaystyle\sum_{i=1}^N\lambda_iy_iw^Tx_i
L(w,b,λ)=21∣∣w∣∣2+i=1∑Nλi−i=1∑NλiyiwTxi
再对
w
w
w求导,
∂
L
∂
w
=
w
−
∑
i
=
1
N
λ
i
y
i
x
i
=
0
\large\frac{\partial L}{\partial w} =w-\displaystyle\sum_{i=1}^N\lambda_iy_ix_i = 0
∂w∂L=w−i=1∑Nλiyixi=0,可得
w
=
∑
i
=
1
N
λ
i
y
i
x
i
w = \displaystyle\sum_{i=1}^N\lambda_iy_ix_i
w=i=1∑Nλiyixi
带入
L
L
L,得:
L
(
w
,
b
,
λ
)
=
−
1
2
∑
i
=
1
N
∑
j
=
1
N
λ
i
λ
j
y
i
y
j
x
i
T
x
j
+
∑
i
=
1
N
λ
i
L(w,b,\lambda) = -\frac{1}{2}\displaystyle\sum_{i=1}^N\displaystyle\sum_{j=1}^N \lambda_i\lambda_jy_iy_jx_i^Tx_j + \displaystyle\sum_{i=1}^N\lambda_i
L(w,b,λ)=−21i=1∑Nj=1∑NλiλjyiyjxiTxj+i=1∑Nλi
最后得到:
min
w
,
b
max
λ
L
(
w
,
b
,
λ
)
=
−
1
2
∑
i
=
1
N
∑
j
=
1
N
λ
i
λ
j
y
i
y
j
x
i
T
x
j
+
∑
i
=
1
N
λ
i
s
.
t
.
λ
i
≥
0
,
∑
i
=
1
N
λ
i
y
i
=
0
\min\limits_{w,b}\ \max\limits_{\lambda} \ L(w,b,\lambda) = -\frac{1}{2}\displaystyle\sum_{i=1}^N\displaystyle\sum_{j=1}^N \lambda_i\lambda_jy_iy_jx_i^Tx_j + \displaystyle\sum_{i=1}^N\lambda_i\\s.t.\ \lambda_i\geq0, \ \ \displaystyle\sum_{i=1}^N\lambda_iy_i=0
w,bmin λmax L(w,b,λ)=−21i=1∑Nj=1∑NλiλjyiyjxiTxj+i=1∑Nλis.t. λi≥0, i=1∑Nλiyi=0
其中,
λ
=
{
λ
1
,
λ
2
.
.
.
,
λ
N
}
\lambda=\{\lambda_1,\lambda_2...,\lambda_N\}
λ={λ1,λ2...,λN}为一组向量
在求梯度时已经得到
w
=
∑
i
=
1
N
λ
i
y
i
x
i
w = \displaystyle\sum_{i=1}^N\lambda_iy_ix_i
w=i=1∑Nλiyixi,而对于支持向量
(
x
k
,
y
k
)
(x_k,y_k)
(xk,yk),总有
1
−
y
k
(
w
T
x
k
+
b
)
=
0
1-y_k(w^Tx_k+b) = 0
1−yk(wTxk+b)=0,转化一下:
y
k
(
w
T
x
k
+
b
)
=
1
y
k
2
(
w
T
x
k
+
b
)
=
y
k
w
T
x
k
+
b
=
y
k
b
=
y
k
−
w
T
x
k
\begin{aligned} y_k(w^Tx_k+b ) &= 1\\ y_k^2(w^Tx_k+b)&=y_k\\ w^Tx_k+b &= y_k\\ b &= y_k - w^Tx_k \end{aligned}
yk(wTxk+b)yk2(wTxk+b)wTxk+bb=1=yk=yk=yk−wTxk
即最后可根据
λ
\lambda
λ算出
w
w
w和
b
b
b,即确定分离超平面。
而求解
λ
\lambda
λ,需要用到SMO算法
2、SMO算法求 λ \lambda λ
2.1 原始解
对于对偶问题
max
λ
L
(
w
,
b
,
λ
)
=
−
1
2
∑
i
=
1
N
∑
j
=
1
N
λ
i
λ
j
y
i
y
j
x
i
T
x
j
+
∑
i
=
1
N
λ
i
s
.
t
.
λ
i
≥
0
,
∑
i
=
1
N
λ
i
y
i
=
0
\max\limits_{\lambda} \ L(w,b,\lambda) = -\frac{1}{2}\displaystyle\sum_{i=1}^N\displaystyle\sum_{j=1}^N \lambda_i\lambda_jy_iy_jx_i^Tx_j + \displaystyle\sum_{i=1}^N\lambda_i\\s.t.\ \lambda_i\geq0\ \ \ ,\ \displaystyle\sum_{i=1}^N \lambda_iy_i = 0
λmax L(w,b,λ)=−21i=1∑Nj=1∑NλiλjyiyjxiTxj+i=1∑Nλis.t. λi≥0 , i=1∑Nλiyi=0
SMO算法每次选择一对变量
(
λ
i
,
λ
j
)
(\lambda_i,\lambda_j)
(λi,λj)优化,剩下的固定
在优化中,谨记 y i ⋅ y i = 1 y_i·y_i=1 yi⋅yi=1,这个式子可以正反互相转化,在SMO中多处用到
假设选取
λ
1
,
λ
2
\lambda_1,\lambda_2
λ1,λ2进行优化,
λ
3
,
λ
4
,
.
.
.
,
λ
N
\lambda_3,\lambda_4,...,\lambda_N
λ3,λ4,...,λN固定,做常数处理,将SVM的优化问题展开可得:
W
(
λ
1
,
λ
2
)
=
λ
1
+
λ
2
−
1
2
K
1
,
1
y
1
2
λ
1
2
−
1
2
K
2
,
2
y
2
2
λ
2
2
−
K
1
,
2
y
1
y
2
λ
1
λ
2
−
y
1
λ
1
∑
i
=
3
N
λ
i
y
i
K
i
,
1
−
y
2
λ
2
∑
i
=
3
N
λ
i
y
i
K
i
,
2
+
C
W (\lambda_1,\lambda_2) = \lambda_1+\lambda_2-\frac{1}{2}K_{1,1}y_1^2\lambda_1^2-\frac{1}{2}K_{2,2}y_2^2\lambda_2^2-K_{1,2}y_1y_2\lambda_1\lambda_2 - y_1\lambda_1\displaystyle\sum_{i=3}^N\lambda_iy_iK_{i,1} - y_2\lambda_2\displaystyle\sum_{i=3}^N\lambda_iy_iK_{i,2}+C
W(λ1,λ2)=λ1+λ2−21K1,1y12λ12−21K2,2y22λ22−K1,2y1y2λ1λ2−y1λ1i=3∑NλiyiKi,1−y2λ2i=3∑NλiyiKi,2+C
其中
C
C
C表示与
λ
1
,
λ
2
\lambda_1,\lambda_2
λ1,λ2无关的常数,
K
i
,
j
K_{i,j}
Ki,j表示
x
i
T
x
j
x_i^Tx_j
xiTxj,即
x
i
,
x
j
x_i,x_j
xi,xj的内积
根据条件 ∑ i = 1 N λ i y i = 0 \displaystyle\sum_{i=1}^N\lambda_iy_i=0 i=1∑Nλiyi=0,可得:
λ 1 y 1 + λ 2 y 2 = − ∑ i = 3 N λ i y i = ζ \lambda_1y_1+\lambda_2y_2 = -\displaystyle\sum_{i=3}^N\lambda_iy_i=\zeta λ1y1+λ2y2=−i=3∑Nλiyi=ζ
两边同乘 y 1 y_1 y1,由于 y i ⋅ y i = 1 y_i·y_i = 1 yi⋅yi=1可得
λ 1 = y 1 ζ − λ 2 y 1 y 2 \lambda_1 = y_1\zeta-\lambda_2y_1y_2 λ1=y1ζ−λ2y1y2
即得到一个 λ i \lambda_i λi的值可以换算出另一个
为了便于计算,我们引入:
v
1
=
∑
i
=
3
N
λ
i
y
i
K
i
,
1
v
2
=
∑
i
=
3
N
λ
i
y
i
K
i
,
2
v_1 = \displaystyle\sum_{i=3}^N\lambda_iy_iK_{i,1}\\ v_2 = \displaystyle\sum_{i=3}^N\lambda_iy_iK_{i,2}
v1=i=3∑NλiyiKi,1v2=i=3∑NλiyiKi,2
联合
λ
1
、
λ
2
\lambda_1、\lambda_2
λ1、λ2的关系式带入
W
(
λ
1
,
λ
2
)
W(\lambda_1,\lambda_2)
W(λ1,λ2)中,得:
W
(
λ
2
)
=
−
1
2
K
1
,
1
(
ζ
−
λ
2
y
2
)
2
−
1
2
K
2
,
2
λ
2
2
−
y
2
(
ζ
−
λ
2
y
2
)
λ
2
K
1
,
2
−
v
1
(
ζ
−
λ
2
y
2
)
−
v
2
y
2
λ
2
+
ζ
y
1
−
λ
2
y
1
y
2
+
λ
2
+
C
W(\lambda_2) =-\frac{1}{2}K_{1,1}(\zeta-\lambda_2y_2)^2-\frac{1}{2}K_{2,2}\lambda_2^2-y_2(\zeta-\lambda_2y_2)\lambda_2K_{1,2}-v_1(\zeta-\lambda_2y_2)-v_2y_2\lambda_2+\zeta y_1-\lambda_2y_1y_2+\lambda_2+C
W(λ2)=−21K1,1(ζ−λ2y2)2−21K2,2λ22−y2(ζ−λ2y2)λ2K1,2−v1(ζ−λ2y2)−v2y2λ2+ζy1−λ2y1y2+λ2+C
就变为了只包含
λ
2
\lambda_2
λ2的式子,此时可直接对
λ
2
\lambda_2
λ2求导:
∂
W
(
λ
2
)
∂
λ
2
=
K
1
,
1
y
2
(
ζ
−
λ
2
y
2
)
−
K
2
,
2
λ
2
+
2
K
1
,
2
λ
2
−
K
1
,
2
y
2
ζ
+
v
1
y
2
−
v
2
y
2
−
y
1
y
2
+
1
=
−
(
K
1
,
1
+
K
2
,
2
−
2
K
1
,
2
)
λ
2
+
K
1
,
1
ζ
y
2
−
K
1
,
2
y
2
ζ
+
v
1
y
2
−
v
2
y
2
−
y
1
y
2
+
1
\begin{aligned} \frac{\partial W(\lambda_2)}{\partial \lambda_2} &= K_{1,1}y_2(\zeta-\lambda_2y_2)-K_{2,2}\lambda_2+2K_{1,2}\lambda_2-K_{1,2}y_2\zeta+v_1y_2-v_2y_2-y_1y_2+1 \\&=-(K_{1,1}+K_{2,2}-2K_{1,2})\lambda_2+K_{1,1}\zeta y_2-K_{1,2}y_2\zeta+v_1y_2-v_2y_2-y_1y_2+1 \end{aligned}
∂λ2∂W(λ2)=K1,1y2(ζ−λ2y2)−K2,2λ2+2K1,2λ2−K1,2y2ζ+v1y2−v2y2−y1y2+1=−(K1,1+K2,2−2K1,2)λ2+K1,1ζy2−K1,2y2ζ+v1y2−v2y2−y1y2+1
这里需要变换一下,使得我们能使用更新前的
λ
2
o
l
d
\lambda_2^{old}
λ2old表示更新后的
λ
2
n
e
w
\lambda_2^{new}
λ2new,而不是难以计算的
ζ
\zeta
ζ
SVM模型对数据点的预测为: f ( x ) = ∑ i = 1 N λ i y i K ( x i , x ) + b f(x) = \displaystyle\sum_{i=1}^N\lambda_iy_iK(x_i,x)+b f(x)=i=1∑NλiyiK(xi,x)+b
注意,在对偶形式中,可以看做将原始形式的 w T x w^Tx wTx替换为 ∑ i = 1 N λ i y i K ( x i , x ) \displaystyle\sum_{i=1}^N\lambda_iy_iK(x_i,x) i=1∑NλiyiK(xi,x)
则
v
1
,
v
2
v_1,v_2
v1,v2可以表示为:
v
1
=
∑
i
=
3
N
λ
i
y
i
K
1
,
i
=
f
(
x
1
)
−
λ
1
y
1
K
1
,
1
−
λ
2
y
2
K
1
,
2
−
b
v
2
=
∑
i
=
3
N
λ
i
y
i
K
2
,
i
=
f
(
x
2
)
−
λ
1
y
1
K
1
,
2
−
λ
2
y
2
K
2
,
2
−
b
v_1 = \displaystyle\sum_{i=3}^N\lambda_iy_iK_{1,i}=f(x_1)-\lambda_1y_1K_{1,1}-\lambda_2y_2K_{1,2}-b \\ v_2 = \displaystyle\sum_{i=3}^N\lambda_iy_iK_{2,i}=f(x_2)-\lambda_1y_1K_{1,2}-\lambda_2y_2K_{2,2}-b
v1=i=3∑NλiyiK1,i=f(x1)−λ1y1K1,1−λ2y2K1,2−bv2=i=3∑NλiyiK2,i=f(x2)−λ1y1K1,2−λ2y2K2,2−b
且已知
λ
1
=
(
ζ
−
λ
2
y
2
)
y
1
\lambda_1 = (\zeta-\lambda_2y_2)y_1
λ1=(ζ−λ2y2)y1,可得:
v
1
−
v
2
=
f
(
x
1
)
−
f
(
x
2
)
−
ζ
K
1
,
1
+
ζ
K
1
,
2
+
(
K
1
,
1
+
K
2
,
2
−
2
K
1
,
2
)
λ
2
y
2
v_1-v_2 = f(x_1)-f(x_2)-\zeta K_{1,1}+\zeta K_{1,2}+(K_{1,1}+K_{2,2}-2K_{1,2})\lambda_2y_2
v1−v2=f(x1)−f(x2)−ζK1,1+ζK1,2+(K1,1+K2,2−2K1,2)λ2y2
将
v
1
−
v
2
v_1-v_2
v1−v2的表达式带入
∂
W
(
λ
2
)
∂
λ
2
\frac{\partial W(\lambda_2)}{\partial\lambda_2}
∂λ2∂W(λ2)中,得:
∂ W ∂ λ 2 = − ( K 1 , 1 + K 2 , 2 − 2 K 1 , 2 ) λ 2 n e w + ( K 1 , 1 + K 2 , 2 − 2 K 1 , 2 ) λ 2 o l d + y 2 ( y 2 − y 1 + f ( x 1 ) − f ( x 2 ) \frac{\partial W}{\partial \lambda_2} = -(K_{1,1}+K_{2,2}-2K_{1,2})\lambda_2^{new}+(K_{1,1}+K_{2,2}-2K_{1,2})\lambda_2^{old}+y_2(y_2-y_1+f(x_1)-f(x_2) ∂λ2∂W=−(K1,1+K2,2−2K1,2)λ2new+(K1,1+K2,2−2K1,2)λ2old+y2(y2−y1+f(x1)−f(x2)
在这里, v 1 v_1 v1和 v 2 v_2 v2中的 λ 2 \lambda_2 λ2是初始化(或更新前)确认的值, λ 2 \lambda_2 λ2,记为 λ 2 o l d \lambda_2^{old} λ2old,而求导求出的值是新的 λ 2 \lambda_2 λ2,记为 λ 2 n e w \lambda_2^{new} λ2new
为了进一步精简式子,我们记 E i E_i Ei为数据 x i x_i xiSVM预测值与真实值之间的误差: E i = f ( x i ) − y i E_i= f(x_i)-y_i Ei=f(xi)−yi
令
η
=
K
1
,
1
+
K
1
,
2
−
2
K
1
,
2
\eta=K_{1,1}+K_{1,2}-2K_{1,2}
η=K1,1+K1,2−2K1,2,得:
∂
W
(
λ
2
)
∂
λ
2
=
−
η
λ
2
n
e
w
+
η
λ
2
o
l
d
+
y
2
(
E
1
−
E
2
)
=
0
\frac{\partial W(\lambda_2)}{\partial \lambda_2} = -\eta\lambda_2^{new}+\eta\lambda_2^{old}+y_2(E_1-E_2) = 0
∂λ2∂W(λ2)=−ηλ2new+ηλ2old+y2(E1−E2)=0
得:
λ
2
n
e
w
=
λ
2
o
l
d
+
y
2
(
E
1
−
E
2
)
η
\lambda_2^{new} = \lambda_2^{old}+\frac{y_2(E_1-E_2)}{\eta}
λ2new=λ2old+ηy2(E1−E2)
这样便通过旧的
λ
2
\lambda_2
λ2获得了新的
λ
2
\lambda_2
λ2,再根据两个因子之间的关系求出更新后的
λ
1
\lambda_1
λ1
2.2 对原始解进行修剪
上述得到的原始解 λ 2 n e w \lambda_2^{new} λ2new是未考虑约束条件得到的,记为 λ 2 n e w , u n c l i p p e d \lambda_2^{new,unclipped} λ2new,unclipped
但在SVM中有约束,即:
{
λ
1
y
1
+
λ
2
y
2
=
ζ
0
≤
λ
i
≤
C
\begin{cases}\lambda_1y_1+\lambda_2y_2 = \zeta \\ 0\leq\lambda_i\leq C \end{cases}
{λ1y1+λ2y2=ζ0≤λi≤C
说明:这里的C是在软间隔SVM中的惩罚因子,在硬间隔SVM中可以看作无穷大
画成图:
说明:其实这里的 k k k就是公式中的 ζ \zeta ζ
边界为边长为 C C C的正方形,而 λ 1 \lambda_1 λ1和 λ 2 \lambda_2 λ2的约束可以用图中平行于对角线的红蓝两条线表示
当 y 1 ≠ y 2 y_1≠y_2 y1=y2的时候,设 y 1 − y 2 = k y_1-y_2=k y1−y2=k
由于直线可以平行移动,所以分情况讨论,当直线在对角线下侧时(k>0),此时
λ 2 \lambda_2 λ2的下界 L L L为0,上界 H H H为 C − k = C − λ 1 + λ 2 C-k = C-\lambda_1+\lambda_2 C−k=C−λ1+λ2
而当直线在对角线上侧时(k<0),此时
λ 2 \lambda_2 λ2的下界 L L L为 − k = λ 2 − λ 1 -k = \lambda_2-\lambda_1 −k=λ2−λ1,上界 H H H为 C C C
写在一起:
{
L
=
m
a
x
(
0
,
λ
2
−
λ
1
)
H
=
m
i
n
(
C
,
C
+
λ
2
−
λ
1
)
\begin{cases} L = max(0,\lambda_2-\lambda_1) \\ H = min(C,C+\lambda_2-\lambda_1) \end{cases}
{L=max(0,λ2−λ1)H=min(C,C+λ2−λ1)
同理,对于
y
1
=
y
2
y_1=y_2
y1=y2的情况,有
λ
1
+
λ
2
=
k
\lambda_1+\lambda_2=k
λ1+λ2=k,此时
λ
2
\lambda_2
λ2上下界为:
{
L
=
m
a
x
(
0
,
λ
1
+
λ
1
−
C
)
H
=
m
i
n
(
C
,
λ
1
+
λ
2
)
\begin{cases} L = max(0,\lambda_1+\lambda_1-C) \\ H = min(C,\lambda_1+\lambda_2) \end{cases}
{L=max(0,λ1+λ1−C)H=min(C,λ1+λ2)
注意,上下界中的
λ
i
\lambda_i
λi均为修剪之前的
λ
i
o
l
d
\lambda_i^{old}
λiold
根据上下界,我们可以得到修剪后的
λ
2
n
e
w
\lambda_2^{new}
λ2new:
λ
2
n
e
w
=
{
H
λ
2
n
e
w
,
u
n
c
l
i
p
p
e
d
>
H
λ
2
n
e
w
,
u
n
c
l
i
p
p
e
d
L
≤
λ
2
n
e
w
,
u
n
c
l
i
p
p
e
d
≤
H
L
λ
2
n
e
w
,
u
n
c
l
i
p
p
e
d
<
L
\lambda_2^{new} = \begin{cases} H &\lambda_2^{new,unclipped}>H \\ \lambda_2^{new,unclipped} & L\leq\lambda_2^{new,unclipped}\leq H \\ L &\lambda_2^{new,unclipped}<L \end{cases}
λ2new=⎩⎪⎨⎪⎧Hλ2new,unclippedLλ2new,unclipped>HL≤λ2new,unclipped≤Hλ2new,unclipped<L
最后得到
λ
2
n
e
w
\lambda_2^{new}
λ2new即可根据
λ
1
o
l
d
y
1
+
λ
2
o
l
d
y
2
=
λ
1
n
e
w
y
1
+
λ
2
n
e
w
y
2
\lambda_1^{old}y_1+\lambda_2^{old}y_2 = \lambda_1^{new}y_1+\lambda_2^{new}y_2
λ1oldy1+λ2oldy2=λ1newy1+λ2newy2得到
λ
1
n
e
w
\lambda_1^{new}
λ1new,即:
λ
1
n
e
w
=
λ
1
o
l
d
+
y
1
y
2
(
λ
2
o
l
d
−
λ
2
n
e
w
)
\lambda_1^{new} = \lambda_1^{old}+y_1y_2(\lambda_2^{old}-\lambda_2^{new})
λ1new=λ1old+y1y2(λ2old−λ2new)
原因是这两个值都等于固定的其他值
2.2 更新 b b b
因为 b b b涉及到SVM中 f ( x ) f(x) f(x)的计算以及误差 E i E_i Ei的计算,所以每次需要额外更新 b b b
当 0 < λ 1 n e w < C 0<\lambda_1^{new}<C 0<λ1new<C时,根据 K K T KKT KKT条件 λ i ( 1 − y i ( w T x i + b ) ) = 0 \lambda_i(1-y_i(w^Tx_i+b))=0 λi(1−yi(wTxi+b))=0 可知此时
y 1 ( w T x 1 + b ) = 1 y_1(w^Tx_1+b)=1 y1(wTx1+b)=1,换算成对偶形式为: y 1 ∑ i = 1 N λ i y i K i , 1 + b = 1 y_1\displaystyle\sum_{i=1}^N\lambda_iy_iK_{i,1}+b=1 y1i=1∑NλiyiKi,1+b=1
即相应的数据点为支持向量
两边同时乘上 y 1 y_1 y1:
∑ i = 1 N λ i y i K i , 1 + b = y 1 \displaystyle\sum_{i=1}^N\lambda_iy_iK_{i,1}+b=y_1 i=1∑NλiyiKi,1+b=y1
即可得
b
1
n
e
w
b_1^{new}
b1new的值:
b
1
n
e
w
=
y
1
−
∑
i
=
3
N
λ
i
y
i
K
i
,
1
−
λ
1
n
e
w
y
1
K
1
,
1
−
λ
2
n
e
w
y
2
K
2
,
1
b_1^{new} = y_1-\displaystyle\sum_{i=3}^N\lambda_iy_iK_{i,1}-\lambda_1^{new}y_1K_{1,1}-\lambda_2^{new}y_2K_{2,1}
b1new=y1−i=3∑NλiyiKi,1−λ1newy1K1,1−λ2newy2K2,1
其中前两项可以变形:
y
1
−
∑
i
=
3
N
λ
i
y
i
K
i
,
1
=
−
E
1
+
λ
1
o
l
d
y
1
K
1
,
1
+
λ
2
o
l
d
y
2
K
2
,
1
+
b
o
l
d
y_1-\displaystyle\sum_{i=3}^N\lambda_iy_iK_{i,1} = -E_1+\lambda_1^{old}y_1K_{1,1}+\lambda_2^{old}y_2K_{2,1}+b^{old}
y1−i=3∑NλiyiKi,1=−E1+λ1oldy1K1,1+λ2oldy2K2,1+bold
当
0
<
λ
2
n
e
w
<
C
0<\lambda_2^{new}<C
0<λ2new<C,即可得到:
b 2 n e w = − E 2 − y 1 K 1 , 2 ( λ 1 n e w − λ 1 o l d ) − y 2 K 2 , 2 ( λ 2 n e w − λ 2 o l d ) + b o l d b_2^{new} = -E_2-y_1K_{1,2}(\lambda_1^{new}-\lambda_1^{old})-y_2K_{2,2}(\lambda_2^{new}-\lambda_2^{old})+b^{old} b2new=−E2−y1K1,2(λ1new−λ1old)−y2K2,2(λ2new−λ2old)+bold
此时他们相等,即 b n e w = b 1 n e w = b 2 n e w b^{new}=b_1^{new}=b_2^{new} bnew=b1new=b2new
当
λ
1
,
λ
2
\lambda_1,\lambda_2
λ1,λ2都在边界上且
L
≠
H
L≠H
L=H时,
b
1
,
b
2
b_1,b_2
b1,b2之间的值就是KKT条件的阈值,SMO算法选取中点作为新的阈值:
b
n
e
w
=
1
2
(
b
1
n
e
w
+
b
2
n
e
w
)
b^{new} = \frac{1}{2}(b_1^{new}+b_2^{new})
bnew=21(b1new+b2new)
3、代码实现
其实只需要最后的公式,就足够写出代码了
import numpy as np
import random
import matplotlib.pyplot as plt
def simple_smo(dataset, labels, C, max_iter):
dataset = np.array(dataset)
m, n = dataset.shape #样本数量,特征数量
labels = np.array(labels)
# 初始化参数λ,b为0
lambds = np.zeros(m) #每个样本都有一个λ乘子
b = 0
it = 0
while it < max_iter:
pair_changed = 0 #选取的一对值相较于之前是否有变化
for i in range(m):
λ_i, x_i, y_i = lambds[i], dataset[i], labels[i] #选取一组λ
fx_i = SVM_predict(x_i,lambds,dataset,labels,b)
E_i = fx_i - y_i
j = select_j(i, m) #选取另一个λ
λ_j, x_j, y_j = lambds[j], dataset[j], labels[j]
fx_j = SVM_predict(x_j,lambds,dataset,labels,b)
E_j = fx_j - y_j
K_ii, K_jj, K_ij = np.dot(x_i, x_i), np.dot(x_j, x_j), np.dot(x_i, x_j)
eta = K_ii + K_jj - 2*K_ij #
if eta <= 0:
print('WARNING eta <= 0')
continue
# 获取更新的alpha对
λ_i_old, λ_j_old = λ_i, λ_j #未更新前的参数
λ_j_new = λ_j_old + y_j*(E_i - E_j)/eta
# 对alpha进行修剪
if y_i != y_j:
L = max(0, λ_j_old - λ_i_old)
H = min(C, C + λ_j_old - λ_i_old)
else:
L = max(0, λ_i_old + λ_j_old - C)
H = min(C, λ_j_old + λ_i_old)
λ_j_new = clip(λ_j_new, L, H) #根据上下界修剪
λ_i_new = λ_i_old + y_i*y_j*(λ_j_old - λ_j_new) #根据公式反推另一个参数
if abs(λ_j_new - λ_j_old) < 0.00001: #这个参数已经优化到最佳,换下一个
#print('WARNING alpha_j not moving enough')
continue
#更新b
lambds[i], lambds[j] = λ_i_new, λ_j_new
b_i = -E_i - y_i*K_ii*(λ_i_new - λ_i_old) - y_j*K_ij*(λ_j_new - λ_j_old) + b
b_j = -E_j - y_i*K_ij*(λ_i_new - λ_i_old) - y_j*K_jj*(λ_j_new - λ_j_old) + b
if 0 < λ_i_new < C:
b = b_i
elif 0 < λ_j_new < C:
b = b_j
else:
b = (b_i + b_j)/2
pair_changed += 1
print('INFO iteration:{} i:{} pair_changed:{}'.format(it, i, pair_changed))
if pair_changed == 0: #参数优化完成,下一轮
it += 1
else: #参数没有优化完成,继续迭代
it = 0
print('iteration number: {}'.format(it))
return lambds, b
def SVM_predict(x,lambds,data,label,b):
"SVM分类器函数 y = w^Tx + b,即文中的f(x)"
res = 0
for i in range(data.shape[0]):
res += lambds[i]*label[i]*(data[i].dot(x.T))
return res + b
def get_w(lambdas, dataset, labels):
#通过λ求w
w = 0
for i in range(len(dataset)):
w += lambdas[i]*y[i]*dataset[i]
return w
def clip(alpha, L, H):
#修建λ的值到L和H之间.
if alpha < L:
return L
elif alpha > H:
return H
else:
return alpha
def select_j(i, m):
#在m中随机选择除了i之外剩余的
l = list(range(m))
seq = l[: i] + l[i+1:]
return random.choice(seq)
def get_point():
x_true = [[1,1.5],[1,3],[4,5],[2,4]]
x_false = [[1,0.5],[4,2],[5,1],[4,1]]
x_all = np.array(x_true+x_false)
y = [1]*len(x_true) + [-1]*len(x_false)
return x_all,y,x_true,x_false
def plot(x_true,x_false,w,b):
plot_x = np.arange(0,7)
plot_y = -(w[0]*plot_x+b)/w[1]
plt.scatter([x[0] for x in x_true],[x[1] for x in x_true] , c='r' , label='+1')
plt.scatter([x[0] for x in x_false],[x[1] for x in x_false] , c='b',label='-1')
plt.plot(plot_x,plot_y,c = 'green')
plt.xlim(0,6)
plt.ylim(0,6)
plt.legend()
plt.plot()
plt.show()
if __name__ == '__main__':
x,y,x_true,x_false = get_point()
lambdas, b = simple_smo(x, y, 10, 10)
w = get_w(lambdas, x, y)
print('-'*40+'result'+'-'*40)
print('lambdas:{}\nw:{}\nb:{}'.format(lambdas,w,b))
plot(x_true,x_false,w,b)
实验结果:
测试一下支持向量到直线的距离(忽略相同的分母):
print(w.dot(np.array([1,1.5]))+b)
print(w.dot(np.array([1, 0.5])) + b)
结果:
除了精度上的差异,基本上已经相等
4、参考文献及联系方式
SMO算法部分参考https://zhuanlan.zhihu.com/p/29212107
对偶原理部分参考:https://www.bilibili.com/video/BV1aE411o7qd?from=search&seid=7374859475814254502&spm_id_from=333.337.0.0
以上仅为我的理解,新人自学,自知才疏学浅,如有纰漏谬误恳请指出
如有问题,欢迎评论留言,或者联系我的邮箱:
1759412770@qq.com