软间隔
对于线性可分的数据,我们仅仅使用硬间隔便可以求解。但是还有个问题。假如数据本身就线性不可分呢?又或者我们的数据存在噪声,比如途中,显然直线左边有一个噪声,右边也有一个噪声。
对这一类问题,怎么办?
这很好解决。我们直接训练的时候允许其存在一丢丢的错误不久可以了嘛?怎么做?当燃是调整损失函数
min
w
,
b
1
2
w
T
w
+
g
(
x
)
\min\limits_{w,b}\frac{1}{2}w^Tw+g(x)
w,bmin21wTw+g(x)
这个f(x)可以当作是允许存在一丢丢错误的损失。
如何设置这个损失?令
z
i
=
y
i
(
w
T
x
i
+
b
)
z_i=y_i(w^Tx_i+b)
zi=yi(wTxi+b)直接
g
(
x
)
=
{
1
,
z
i
<
1
0
,
z
i
≥
1
g(x)= \left \{ \begin{matrix} 1,z_i<1 \\ 0,z_i\ge1 \end{matrix} \right.
g(x)={1,zi<10,zi≥1
看起来是一个不错的方法,因为在我们之前提到之中,我们认为
y
i
(
w
T
x
i
+
b
)
≥
1
y_i(w^Tx_i+b)\ge1
yi(wTxi+b)≥1是所有分类正确的前提,如果为负数,那么则证明是错误的。但是,有一个致命问题——这个函数并不连续,无法求导。而我们求极值就不可避免地使用求导。要知道,不连续的函数是无法求导的。
怎么办?我们不妨这样设定
g
(
x
)
=
m
a
x
{
0
,
1
−
z
i
}
g(x)=max\left\{0,1-z_i \right\}
g(x)=max{0,1−zi}
当
y
i
(
w
T
x
i
+
b
)
<
1
y_i(w^Tx_i+b)<1
yi(wTxi+b)<1,则说明是错误的点,那么我们就用
1
−
y
i
(
w
T
x
i
+
b
)
=
1
−
z
1-y_i(w^Tx_i+b)=1-z
1−yi(wTxi+b)=1−z来代表错误点损失,如果
y
i
(
w
T
x
i
+
b
)
≥
1
y_i(w^Tx_i+b)\ge1
yi(wTxi+b)≥1代表正确,所以所得就为0,代表无错误点损失。这是他的图像
令
δ
=
m
a
x
{
0
,
1
−
z
i
}
\delta=max\left\{0,1-z_i\right\}
δ=max{0,1−zi},我们损失函数就可以为
{
1
2
w
T
w
+
C
∑
i
=
1
n
δ
i
\left \{ \frac{1}{2}w^Tw+C\sum\limits_{i=1}^n\delta_i \right.
{21wTw+Ci=1∑nδi
其中C是一个惩罚系数,越大惩罚力度越大,反之越小。
那么约束条件呢?当燃不能沿用之前的。我是这么理解的 1 − z i 1-z_i 1−zi的
坐标中,点 K 1 K_1 K1是一个错误点,那么 1 − z i 1-z_i 1−zi意为线段 K 1 N K_1N K1N,
对于硬间隔的损失函数为
{
min
w
,
b
1
2
w
T
w
s
.
t
.
y
i
(
w
T
x
i
+
b
)
≥
1
,
i
=
1
,
2
⋯
,
n
\begin{equation} \begin{aligned} \left\{ \begin{matrix} &\min\limits_{w,b}\frac{1}{2}w^Tw \\&s.t.\hspace{1cm} &y_i(w^Tx_i+b)\ge1,i=1,2 \cdots ,n \end{matrix} \right. \end{aligned} \end{equation}
{w,bmin21wTws.t.yi(wTxi+b)≥1,i=1,2⋯,n
所以软间隔的损失函数则为
{
1
2
w
T
w
+
C
∑
i
=
1
n
δ
i
s
.
t
.
y
i
(
w
T
x
i
+
b
)
+
δ
i
≥
1
δ
i
≥
0
;
i
=
1
,
2
,
⋯
,
n
\begin{equation} \begin{aligned} \left \{ \begin{matrix} &\frac{1}{2}w^Tw+C\sum\limits_{i=1}^n\delta_i\\ s.t.\hspace{1cm} &y_i(w^Tx_i+b)+\delta_i\ge1\\ &\delta_i\ge0;i=1,2,\cdots,n \end{matrix} \right. \end{aligned} \end{equation}
⎩
⎨
⎧s.t.21wTw+Ci=1∑nδiyi(wTxi+b)+δi≥1δi≥0;i=1,2,⋯,n
以下步骤不做解释,详细可看硬间隔的部分,因为差不多是一样的。
拉格朗日函数
L
(
w
,
b
,
δ
,
α
,
β
)
=
1
2
w
T
w
+
C
∑
i
=
1
n
δ
i
+
∑
i
=
1
n
[
α
i
(
1
−
δ
i
−
y
i
(
w
T
x
i
+
b
)
)
]
−
∑
i
=
1
n
β
i
δ
i
L(w,b,\delta,\alpha,\beta)=\frac{1}{2}w^Tw+C\sum\limits_{i=1}^n\delta_i+\sum\limits_{i=1}^n\left[ \alpha_i(1-\delta_i-y_i(w^Tx_i+b))\right]-\sum\limits_{i=1}^n\beta_i\delta_i
L(w,b,δ,α,β)=21wTw+Ci=1∑nδi+i=1∑n[αi(1−δi−yi(wTxi+b))]−i=1∑nβiδi
求原问题再求对偶问题,然后对其求导
∂
L
∂
w
→
w
=
∑
i
=
1
n
α
i
y
i
x
i
∂
L
∂
b
→
∑
i
=
1
n
α
i
y
i
=
0
∂
L
∂
δ
i
→
α
i
+
β
i
=
C
\begin{equation} \begin{aligned} &\frac{\partial{L}}{\partial{w}}\rightarrow w=\sum\limits_{i=1}^n\alpha_iy_ix_i \\&\frac{\partial{L}}{\partial{b}}\rightarrow\sum\limits_{i=1}^n\alpha_iy_i=0 \\&\frac{\partial{L}}{\partial{\delta_i}}\rightarrow \alpha_i+\beta_i=C \end{aligned} \end{equation}
∂w∂L→w=i=1∑nαiyixi∂b∂L→i=1∑nαiyi=0∂δi∂L→αi+βi=C
令
β
i
=
C
−
α
i
\beta_i=C-\alpha_i
βi=C−αi和另外两个求导所得代入拉格朗日函数。最终
max
α
∑
i
=
1
n
α
i
−
1
2
∑
i
=
1
n
∑
j
=
1
n
α
i
y
i
α
j
y
j
x
i
T
x
j
s
.
t
.
0
≤
α
i
≤
C
,
i
=
1.2.
⋯
,
n
.
∑
i
=
1
n
α
i
y
i
=
0
,
\begin{equation} \begin{aligned} &\max\limits_{\alpha}\sum\limits_{i=1}^n\alpha_i-\frac{1}{2}\sum\limits_{i=1}^n\sum\limits_{j=1}^n\alpha_iy_i\alpha_jy_jx_i^Tx_j \\&s.t. \hspace{1cm} 0\le\alpha_i \le C,i=1.2.\cdots,n.\\&\hspace{2cm}\sum\limits_{i=1}^n\alpha_iy_i=0, \end{aligned} \end{equation}
αmaxi=1∑nαi−21i=1∑nj=1∑nαiyiαjyjxiTxjs.t.0≤αi≤C,i=1.2.⋯,n.i=1∑nαiyi=0,
可以发现,目标函数和硬间隔是一样的,只是约束条件从
a
l
p
h
a
i
≥
0
alpha_i\ge0
alphai≥0变成了
0
≤
α
i
≤
C
0\le\alpha_i \le C
0≤αi≤C,所以,最终使用SMO算法求解所得应为一样。但是在硬间隔的时候,我们仅仅是求解了,但是还有一个
α
i
≥
0
\alpha_i\ge0
αi≥0是没有使用的,也就是我们所求出来的
λ
2
n
e
w
\lambda_2^{new}
λ2new并非一定是解,因为我们还需要削减。
此处,我们仅仅求软间隔的取值范围,硬间隔的相对比较容易,读者可自求。
对此,我们先求出
α
2
n
e
w
\alpha_2^{new}
α2new的取值范围。
因为:
α
1
o
l
d
y
1
+
α
2
o
l
d
y
2
=
−
∑
i
=
3
n
α
i
y
i
=
K
分情况讨论:
①:
y
1
=
y
2
(
即标签值同号
)
对第一个等式左右乘以
y
1
得:
α
1
n
e
w
y
1
+
α
2
n
e
w
y
2
=
K
y
1
→
α
2
n
e
w
=
K
y
1
−
α
1
n
e
w
因为:
a
1
n
e
w
∈
[
0
,
C
]
所以:
−
a
1
n
e
w
∈
[
−
C
,
0
]
因为:
α
1
o
l
d
y
1
+
α
2
o
l
d
y
2
=
K
所以:
K
y
1
−
α
1
n
e
w
∈
[
K
y
1
−
C
,
K
y
1
]
→
[
α
1
o
l
d
+
α
2
o
l
d
−
C
,
α
1
o
l
d
+
α
2
o
l
d
]
因为:
α
2
n
e
w
=
K
y
1
−
α
1
n
e
w
所以:
α
2
n
e
w
∈
[
α
1
o
l
d
+
α
2
o
l
d
−
C
,
α
1
o
l
d
+
α
2
o
l
d
]
又因为:
α
2
∈
[
0
,
C
]
要同时满足这两个条件,就必须:
α
2
∈
[
max
{
0
,
α
1
o
l
d
+
α
2
o
l
d
−
C
}
,
m
i
n
{
C
,
α
1
o
l
d
+
α
2
o
l
d
}
]
同理得②:
y
1
≠
y
2
(
标签不同号
)
即:
α
2
∈
[
max
{
0
,
α
2
o
l
d
−
α
1
o
l
d
}
,
m
i
n
{
C
,
α
2
o
l
d
−
α
1
o
l
d
+
C
}
]
\begin{equation} \begin{aligned} 因为:& \alpha_1^{old}y_1+\alpha_2^{old}y_2=-\sum_{i=3}^n\alpha_iy_i=K \\分情况讨论:& \\①:&y_1={y_2}(即标签值同号) \\对第一个等式左右乘以y_1得:&\alpha_1^{new}y_1+\alpha_2^{new}y_2=Ky_1\rightarrow \alpha_2^{new}=Ky_1-\alpha_1^{new} \\因为:&a_1^{new}\in[0,C] \\所以:&-a_1^{new}\in[-C,0] \\因为:&\alpha_1^{old}y_1+\alpha_2^{old}y_2=K \\所以:&Ky_1-\alpha_1^{new}\in[Ky_1-C,Ky_1]\rightarrow[\alpha_1^{old}+\alpha_2^{old}-C,\alpha_1^{old}+\alpha_2^{old}] \\因为:&\alpha_2^{new}=Ky_1-\alpha_1^{new} \\所以:&\alpha_2^{new}\in[\alpha_1^{old}+\alpha_2^{old}-C,\alpha_1^{old}+\alpha_2^{old}] \\又因为:&\alpha_2\in[0,C] \\要同时满足这两个条件,就必须:&\alpha_2\in\left[\max\left\{0,\alpha_1^{old}+\alpha_2^{old}-C\right\},min\left\{C,\alpha_1^{old}+\alpha_2^{old}\right\}\right] \\同理得②:&y_1\neq{y_2}(标签不同号)\\ 即:&\alpha_2\in\left[\max\left\{0,\alpha_2^{old}-\alpha_1^{old}\right\},min\left\{C,\alpha_2^{old}-\alpha_1^{old}+C\right\}\right] \end{aligned} \end{equation}
因为:分情况讨论:①:对第一个等式左右乘以y1得:因为:所以:因为:所以:因为:所以:又因为:要同时满足这两个条件,就必须:同理得②:即:α1oldy1+α2oldy2=−i=3∑nαiyi=Ky1=y2(即标签值同号)α1newy1+α2newy2=Ky1→α2new=Ky1−α1newa1new∈[0,C]−a1new∈[−C,0]α1oldy1+α2oldy2=KKy1−α1new∈[Ky1−C,Ky1]→[α1old+α2old−C,α1old+α2old]α2new=Ky1−α1newα2new∈[α1old+α2old−C,α1old+α2old]α2∈[0,C]α2∈[max{0,α1old+α2old−C},min{C,α1old+α2old}]y1=y2(标签不同号)α2∈[max{0,α2old−α1old},min{C,α2old−α1old+C}]
因此,我们需要对
α
2
n
e
w
\alpha_2^{new}
α2new进行削减。
除此之外。还有一个问题,就是什么时候停止训练?总不能一直训练下去吧?
我们的一个思路是依据新的
α
\alpha
α值,如果全部满足以下,则说明已经是最优解。
{
y
i
(
w
T
x
i
+
b
)
=
1
,
0
<
α
i
<
C
y
i
(
w
T
x
i
+
b
)
≥
1
,
α
i
=
0
y
i
(
w
T
x
i
+
b
)
≤
1
,
α
i
=
C
\begin{equation} \begin{aligned} \left\{ \begin{matrix} &y_i(w^Tx_i+b)=1,0<\alpha_i<{C}\\ &y_i(w^Tx_i+b)\ge1,\alpha_i=0\\ &y_i(w^Tx_i+b)\le1,\alpha_i=C \end{matrix} \right. \end{aligned} \end{equation}
⎩
⎨
⎧yi(wTxi+b)=1,0<αi<Cyi(wTxi+b)≥1,αi=0yi(wTxi+b)≤1,αi=C
怎么得到的,先看一下KKT条件
{
∂
L
∂
w
;
∂
L
∂
b
;
∂
L
∂
δ
i
α
i
[
1
−
δ
i
−
y
i
(
w
T
x
i
+
b
)
]
=
0
;
−
β
i
δ
i
=
0
α
i
≥
0
;
β
i
≥
0
[
1
−
δ
i
−
y
i
(
w
T
x
i
+
b
)
]
≤
0
;
−
β
i
δ
i
≤
0
\left\{ \begin{matrix} \frac{\partial{L}}{\partial{w}};\frac{\partial{L}}{\partial{b}};\frac{\partial{L}}{\partial{\delta_i}}\\ \alpha_i[1-\delta_i-y_i(w^Tx_i+b)]=0; -\beta_i\delta_i=0 \\\alpha_i\ge0;\beta_i\ge0 \\{[1-\delta_i-y_i(w^Tx_i+b)]\le0};-\beta_i\delta_i\le0 \end{matrix} \right.
⎩
⎨
⎧∂w∂L;∂b∂L;∂δi∂Lαi[1−δi−yi(wTxi+b)]=0;−βiδi=0αi≥0;βi≥0[1−δi−yi(wTxi+b)]≤0;−βiδi≤0
前面我们知道,当
δ
i
≠
0
\delta_i\neq0
δi=0代表我们允许的错误点,那么对应的要使得
β
i
δ
i
=
0
\beta_i\delta_i=0
βiδi=0,所以
β
i
=
0
\beta_i=0
βi=0,依据
α
i
+
β
i
=
C
\alpha_i+\beta_i=C
αi+βi=C,所以当有错误点时,此时
α
i
=
C
\alpha_i=C
αi=C。
我们知道,我们需要计算出新的b。那么如何计算b呢?假如我们循环第一次得到的
α
2
\alpha_2
α2,如果
0
<
α
2
<
C
0<\alpha_2<C
0<α2<C,说明其是支持向量,我们知道,依据之前提到的KKT条件。那么
x
2
x_2
x2点是支持向量时,有
y
2
(
w
T
x
2
+
b
2
n
e
w
)
=
1
→
w
T
x
2
+
b
2
n
e
w
=
y
2
y_2(w^Tx_2+b_2^{new})=1 \rightarrow{w^Tx_2+b_2^{new}=y_2}
y2(wTx2+b2new)=1→wTx2+b2new=y2
所以
b
2
n
e
w
=
y
2
−
∑
i
=
1
n
α
i
y
i
K
i
2
=
y
2
−
α
1
n
e
w
y
1
K
12
−
α
2
n
e
w
y
2
K
22
−
∑
i
=
3
n
α
i
y
i
K
i
2
b_2^{new}=y_{2}-\sum\limits_{i=1}^n\alpha_iy_iK_{i2}=y_2-\alpha_1^{new}y_1K_{12}-\alpha_2^{new}y_2K_{22}-\sum\limits_{i=3}^n\alpha_iy_iK_{i2}
b2new=y2−i=1∑nαiyiKi2=y2−α1newy1K12−α2newy2K22−i=3∑nαiyiKi2
因为
f
(
x
2
)
−
y
2
=
α
1
o
l
d
y
1
K
12
+
α
2
o
l
d
y
2
K
22
+
∑
i
=
3
n
α
i
y
i
K
i
2
+
b
o
l
d
−
y
2
移向得:
y
2
−
∑
i
=
3
n
α
i
y
i
K
i
2
=
−
[
f
(
x
2
)
−
y
2
]
+
α
1
o
l
d
y
1
K
12
+
α
2
o
l
d
y
2
K
22
+
b
o
l
d
等式左右同时减去:
(
α
1
n
e
w
y
1
K
12
+
α
2
n
e
w
y
2
K
22
)
所以依据上一个公式得:
b
2
n
e
w
=
−
[
f
(
x
2
)
−
y
2
]
+
(
α
1
o
l
d
−
α
1
n
e
w
)
y
1
K
12
+
(
α
2
o
l
d
−
α
2
n
e
w
)
y
2
K
22
+
b
o
l
d
\begin{equation} \begin{aligned} &f(x_2)-y_2=\alpha_1^{old}y_1K_{12}+\alpha_2^{old}y_2K_{22}+\sum\limits_{i=3}^n\alpha_iy_iK_{i2}+b^{old}-y_2 \\移向得:&y_2-\sum\limits_{i=3}^n\alpha_iy_iK_{i2}=-[f(x_2)-y_2]+\alpha_1^{old}y_1K_{12}+\alpha_2^{old}y_2K_{22}+b^{old} \\等式左右同时减去:&(\alpha_1^{new}y_1K_{12}+\alpha_2^{new}y_2K_{22}) \\所以依据上一个公式得:&b_2^{new}=-[f(x_2)-y_2]+(\alpha_1^{old}-\alpha_1^{new})y_1K_{12}+(\alpha_2^{old}-\alpha_2^{new})y_2K_{22}+b^{old} \end{aligned} \end{equation}
移向得:等式左右同时减去:所以依据上一个公式得:f(x2)−y2=α1oldy1K12+α2oldy2K22+i=3∑nαiyiKi2+bold−y2y2−i=3∑nαiyiKi2=−[f(x2)−y2]+α1oldy1K12+α2oldy2K22+bold(α1newy1K12+α2newy2K22)b2new=−[f(x2)−y2]+(α1old−α1new)y1K12+(α2old−α2new)y2K22+bold
令
E
i
=
f
(
x
i
)
−
y
i
E_i=f(x_i)-y_i
Ei=f(xi)−yi,得
b
n
e
w
=
b
2
n
e
w
=
−
E
2
+
(
α
1
o
l
d
−
α
1
n
e
w
)
y
1
K
12
+
(
α
2
o
l
d
−
α
2
n
e
w
)
y
2
K
22
+
b
o
l
d
b^{new}=b_2^{new}=-E_2+(\alpha_1^{old}-\alpha_1^{new})y_1K_{12}+(\alpha_2^{old}-\alpha_2^{new})y_2K_{22}+b^{old}
bnew=b2new=−E2+(α1old−α1new)y1K12+(α2old−α2new)y2K22+bold
同理如果
0
<
α
1
<
C
0<\alpha_1<C
0<α1<C,那么
b
n
e
w
=
b
1
n
e
w
=
−
E
1
+
(
α
1
o
l
d
−
α
1
n
e
w
)
y
1
K
11
+
(
α
2
o
l
d
−
α
2
n
e
w
)
y
2
K
21
+
b
o
l
d
b^{new}=b_1^{new}=-E_1+(\alpha_1^{old}-\alpha_1^{new})y_1K_{11}+(\alpha_2^{old}-\alpha_2^{new})y_2K_{21}+b^{old}
bnew=b1new=−E1+(α1old−α1new)y1K11+(α2old−α2new)y2K21+bold
当
0
<
α
1
<
C
,
0
<
α
2
<
C
0<\alpha_1<C,0<\alpha_2<C
0<α1<C,0<α2<C,那么,
b
1
n
e
w
=
b
2
n
e
w
b_1^{new}=b_2^{new}
b1new=b2new
当
α
i
=
0
或
C
\alpha_i=0或C
αi=0或C,此时
b
n
e
w
=
b
1
n
e
w
+
b
2
n
e
w
2
b^{new}=\frac{b_1^{new}+b_2^{new}}{2}
bnew=2b1new+b2new
对于这个式子,我无法理解。书上写的是
b
1
n
e
w
b_1^{new}
b1new和
b
2
n
e
w
b_2^{new}
b2new是
b
n
e
w
b^{new}
bnew的取值范围。可是我当
a
i
=
0
a_i=0
ai=0时,此时
y
i
(
w
T
x
i
+
b
)
≥
1
y_i(w^Tx_i+b)\ge1
yi(wTxi+b)≥1,那么理应新的
b
n
e
w
b^{new}
bnew应该要取
b
1
n
e
w
,
b
n
e
w
b_1^{new},b^{new}
b1new,bnew的最大值,如果只是取到中间值,这无疑只能够满足其中的一个条件。后来我觉得,会不会是
b
1
n
e
w
=
b
2
n
e
w
b_1^{new}=b_2^{new}
b1new=b2new,结果我发现也不恒等。再者,如果说
α
1
=
0
,
α
2
=
C
\alpha_1=0,\alpha_2=C
α1=0,α2=C,而
α
1
\alpha_1
α1所对应的是
b
1
,
b
2
b_1,b_2
b1,b2,那么
b
1
≤
b
n
e
w
≤
b
2
b_1\le{b_{new}}\le{b_2}
b1≤bnew≤b2,但是问题又来了,假如
b
1
>
b
2
b_1>b_2
b1>b2(我并不知道会不会有这种情况,在这里我们姑且算是存在这种情况),那不等式将没有意义了啊?所以,究竟是怎么一回事?
我在网上寻找答案。发现了有一些人是不顾 α i \alpha_i αi的取值。直接就是 b n e w = b 1 n e w + b 2 n e w 2 b^{new}=\frac{b_1^{new}+b_2^{new}}{2} bnew=2b1new+b2new,不分任何情况。
后来我又去图书馆,找了一本《机器学习》的书看了一下(书名和作者我记不清了),发现要分不同 α i \alpha_i αi取不同的 b n e w b^{new} bnew,按照我的想法,这种方式也雀食更加合理。我没有看过原始论文,但貌似论文中也是这么写的。
可是,有意思的是,无论分不分类讨论,最终都可以收敛,甚至当属于硬间隔的情况下,在 b 1 n e w = 0 , b 2 n e w = 0 b_1^{new}=0,b_2^{new}=0 b1new=0,b2new=0下,我直接取最大的一个 b n e w b^{new} bnew,依然可以收敛。无非就是收敛的快慢的问题。
于是,我就想,有没有一种可能,对于不同的 b 1 n e w , b 2 n e w b_1^{new},b_2^{new} b1new,b2new,我们选择一个新的 b n e w b^{new} bnew时,只要满足其中一个条件也是可行的?或者说,取一个中间值,也很接近两个条件,是不是也可以呢?
我个人认为是可行的。模型的收敛需要一定的迭代次数,我们固定其余变量而更改两个,但是更改的这两个在其余变量不变的情况下才属于最优值。可一旦其他变量也通过更新改变了,那么第一次改变的那两个变量有可能就不是最优值了。牵一发而动全身,也正是因为如此,我认为对于b的值其实没有必要都把控的对,因为后面还是要改的啊,所以为了简单起见,取一个中间值,脚踏两条船,未尝不是一个方法,反正 b b b的取值也是要慢慢收敛的。具体的,可以在代码中尝试。
以上这一段加粗的内容,是个人猜想,正确的可能性不大,只是想说出我的疑惑,书上并无解释,但书上写的是 b 1 n e w b_1^{new} b1new和 b 2 n e w b_2^{new} b2new是 b n e w b^{new} bnew的取值范围,这一句话,似乎打破了我所有的幻想,应该是我脑子不太好使的原因,想了好几天也没想明白。有懂哥解释下,万分感谢。
启发式变量选择
在算法中,我们初始的想法对于所有的拉格朗日算子α,我们是按顺序两个两个地更新,或者随机选取两个。这种方式无疑要耗费大量的时间。
所以,我们选择要更新的变量的时候,最好选择的那个变量刚好需要更新。
那怎么做呢?我们知道,我们最终的结果无外乎三种
{
y
i
(
w
T
x
i
+
b
)
=
1
,
0
<
α
i
<
C
y
i
(
w
T
x
i
+
b
)
≥
1
,
α
i
=
0
y
i
(
w
T
x
i
+
b
)
≤
1
,
α
i
=
C
\begin{equation} \begin{aligned} \left\{ \begin{matrix} &y_i(w^Tx_i+b)=1,0<\alpha_i<{C}\\ &y_i(w^Tx_i+b)\ge1,\alpha_i=0\\ &y_i(w^Tx_i+b)\le1,\alpha_i=C \end{matrix} \right. \end{aligned} \end{equation}
⎩
⎨
⎧yi(wTxi+b)=1,0<αi<Cyi(wTxi+b)≥1,αi=0yi(wTxi+b)≤1,αi=C
因为我们每一次要选择两个变量算子,因此这第一个
α
1
\alpha_1
α1,我们可以选择违反了上述公式的点。如何确定其是否违反了上述公式?令
E
i
=
f
(
x
i
)
−
y
i
E_i=f(x_i)-y_i
Ei=f(xi)−yi
所以
y
i
∗
E
i
=
y
i
f
(
x
i
)
−
1
y_i*E_i=y_if(x_i)-1
yi∗Ei=yif(xi)−1
所以,当
y
i
∗
E
i
≥
0
,
α
i
=
0
y_i*E_i\ge0,\alpha_i=0
yi∗Ei≥0,αi=0,当
y
i
∗
E
i
≤
0
,
α
i
=
C
y_i*E_i\le0,\alpha_i=C
yi∗Ei≤0,αi=C
因此,我们所要的违反上述公式的点就可以写成
(yi*Ei>0 and α>0) or (yi*Ei<0 and α<C)
但是,书上讲的是,此处并不是 y i ∗ E i > 0 y_i*E_i>0 yi∗Ei>0,而是
(yi*Ei>tol and α>0) or (yi*Ei<-tol and α<C)
此处tol一般取0.001,被称为容忍度。因为我们在训练的过程中,所有的点并不是严格符合KKT条件,所以我们就放缓一点点这样。
我们有了 α 1 \alpha_1 α1,那么 α 2 \alpha_2 α2呢,我们一般会选择 ∣ 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,其会导致模型无法收敛,而在有一些文章中,有人也表示如果无法收敛,可以选择遍历所有的点作为 α 2 \alpha_2 α2,或者随机选择一个。
因此,为了简单起见,我在代码中。 α 2 \alpha_2 α2我直接随机选择,这样的收敛速度或许会比不上选择最大的,但是依然可以收敛。
至于核函数,我觉得不用懂原理,可以直接用就行。在这里为了可视化过程,就不用核函数了,因为有了核函数,那么直线的权重就算不出来了。
代码复现
import numpy as np
from scipy import stats
import matplotlib.pyplot as plt
plt.ion()
class SVM():
def __init__(self):
pass
def train(self,x,y):
self.x=x #数据点 ,维度(n,2)
self.w=np.zeros((self.x.shape[1],1)) #初始化全为0的w权重,维度(2,1)
self.y=y #标签值
self.C=1.0 #惩罚系数
self.tol=1e-3 #容忍度
self.alpha=np.zeros((self.x.shape[0],1)) #初始化全为0的α值
self.b=np.zeros(1) #初始化偏置项
self.alpha_copy=np.ones((self.x.shape[0],1)) #生成一份复制的α,初始值设置和真正的α不同,用于判断是否模型收敛
flag = 1 #记录
for epoch in range(500):#循环500次
if (self.alpha_copy==self.alpha).all(): #判断是否一样
if flag==100: #如果循环了一百次都一样,则认为模型已经收敛
print("结束循环")
print("w:",self.w)
exit()
else: #否则继续迭代更新,并计数加一
flag+=1
self.updata() #更新α
else:
# 如果并不全部一样,则认为数据更新过了,把新的α赋给复制的那一份,然后进行更新
self.alpha_copy = self.alpha.copy()
flag=0
self.updata()
print(self.w)
def updata(self):
for i in np.arange(0, self.x.shape[0]): #迭代所有的点
self.w = self.x.T @ (self.y * self.alpha) #计算出w
y1 = self.y[i] #取出a1的标签值
alpha1_old = self.alpha[i] #取出a1
E1 = self.w.T @ self.x[i] + self.b - y1 #计算E1
#判断是否违法KKT条件
if ((E1 * y1 > self.tol and alpha1_old > 0) or (E1 * y1 < -self.tol and alpha1_old < self.C)):
#随机选取一个点作为a2,但是不能与a1相等
j = i
while j == i:
j = np.random.choice(self.alpha.shape[0], size=1)[0]
alpha2_old = self.alpha[j] #取出a2
y2 = self.y[j] #取出a2的标签值
E2 = self.w.T @ self.x[j] + self.b - y2 #计算E2
K11 = self.x[i].T @ self.x[i]
K22 = self.x[j].T @ self.x[j]
K12 = self.x[i].T @ self.x[j]
eta = K11 + K22 - 2 * K12 #计算η
if eta == 0: #如果等于0无意义,直接跳过计算
continue
alpha2_unclip = alpha2_old + y2 * (E1 - E2) / eta #计算没有剪裁过的a2
if y1 == y2:
L = max(0, alpha1_old + alpha2_old - self.C)
R = min(self.C, alpha1_old + alpha2_old)
else:
L = max(0, alpha2_old - alpha1_old)
R = min(self.C, alpha2_old - alpha1_old + self.C)
alpha2 = np.clip(alpha2_unclip, L, R) #剪裁a2
alpha1 = alpha1_old + (alpha2_old - alpha2) * y1 * y2 #计算a1
self.alpha[i], self.alpha[j] = alpha1, alpha2 #修改α,将新的赋值过去
#计算b1,b2
new_b1 = -E1 + (alpha1_old - alpha1) * y1 * K11 + \
(alpha2_old - alpha2) * y2 * K12 + self.b
new_b2 = -E2 + (alpha1_old - alpha1) * y1 * K12 + \
(alpha2_old - alpha2) * y2 * K22 + self.b
#计算新的w,画图用的,按理说不用计算
self.w = self.x.T @ (self.y * self.alpha)
# 分类讨论决定新的b的取值
if 0 < alpha1 < self.C:
self.b = new_b1
elif 0 < alpha2 < self.C:
self.b = new_b2
else:
self.b = (new_b1 + new_b2) / 2
figure_plot(x, y, self.w, self.b) #绘图函数
def figure_plot(x,y,w,b):
#绘图函数
color_map={-1:"r",1:"b"}
color=[color_map[i] for i in y.squeeze()]
x_1=np.arange(-2.5,3)
x_2=(-w[0]*x_1-b.reshape(-1))/(w[1]+1e-3)
plt.cla()
plt.scatter(x[:,0],x[:,1],c=color)
plt.plot(x_1,x_2)
plt.xlim((-2.5, 2.5))
plt.ylim((-2.5, 3))
plt.pause(0.1)
if __name__ == '__main__':
x1=stats.norm.rvs(5,1,(100,2)) #第一类数据
y1=np.ones((100,1)) #第一类数据的类别
x2=stats.norm.rvs(0,1 ,(100,2)) #第二类数据
y2 = np.ones((100, 1))*-1 #第二类数据类别
#合并数据
x=np.concatenate((x1,x2),axis=0)
y=np.concatenate((y1,y2),axis=0)
x_mean=np.mean(x,axis=0) #均值
x_std=np.std(x,axis=0) #标准差
x=(x-x_mean)/x_std #标准化数据
svm=SVM() #初始化
svm.train(x,y) #训练
结束
以上就是我学习到了SVM的推导过程了,过程并不研究,如有问题,还望指出,阿里嘎多。