SVM支持向量机与SMO学习笔记(二)[数学推导]

在上一篇文章SVM支持向量机与SMO学习笔记(一)中,已经将待求解的未知量由w变成了α,这一节主要介绍求解α的常用算法-SMO算法,序列最小化(Sequence Minimal Optimization)算法,由John Platt于1996年发布。

1. 任务提取

在上一篇中,我们需要求解的目标函数与约束条件为:
在这里插入图片描述
通过构造拉格朗日函数,利用KKT条件进行求解出的极值条件为:

1. ∂ L ( w , b , α ) ∂ w = w − ∑ i = 1 m α i y i x i = 0 1. \frac{\partial L(w,b,\alpha)}{\partial w}=w-\sum_{i=1}^{m}\alpha_iy_ix_i=0 1.wL(w,b,α)=wi=1mαiyixi=0

2. ∂ L ( w , b , α ) ∂ b = ∑ i = 1 m y i α i = 0 2. \frac{\partial L(w,b,\alpha)}{\partial b}=\sum_{i=1}^m y_i\alpha_i=0 2.bL(w,b,α)=i=1myiαi=0

Tip:这里是累加求和为零,并不一定每个式子为0

约束条件为:
1. α i ∗ ( 1 − y i ( w T x i + b ) ) = 0 1. \alpha_i*(1-y_i(w^Tx_i + b))=0 1.αi(1yi(wTxi+b))=0
2. α i ≥ 0 2.\alpha_i \ge0 2.αi0
3. y i ( w T x i + b ) − 1 ≥ 0 3.y_i(w^Tx_i + b)-1\ge0 3.yi(wTxi+b)10

推导得出其他条件:

L ( w , b , α ) = 1 2 ∣ ∣ w ∣ ∣ 2 + ∑ i = 1 m α i ∗ ( 1 − y i ( w T x i + b ) ) L(w,b,\alpha)=\frac{1}{2}||w||^2+\sum_{i=1}^{m} \alpha_i *(1-y_i(w^Tx_i + b)) L(w,b,α)=21w2+i=1mαi(1yi(wTxi+b))

1. α i ∗ ( 1 − y i ( w T x i + b ) ) = 0 1.\alpha_i *(1-y_i(w^Tx_i + b))=0 1.αi(1yi(wTxi+b))=0

2. m i n w m a x α L ( w , b , α ) = m a x α m i n w L ( w , b , α ) = m i n w f ( w ) = f ( w ∗ ) 2. min_w max_\alpha L(w,b,\alpha)=max_\alpha min_w L(w,b,\alpha) = min_wf(w)=f(w^*) 2.minwmaxαL(w,b,α)=maxαminwL(w,b,α)=minwf(w)=f(w)

原待求解式为 m i n w m a x α L ( w , b , α ) min_w max_\alpha L(w,b,\alpha) minwmaxαL(w,b,α),经对偶转换可以先进行求解 m i n w L ( w , b , α ) min_w L(w,b,\alpha) minwL(w,b,α),将极值条件代入到 m a x α m i n w L ( w , b , α ) max_\alpha min_w L(w,b,\alpha) maxαminwL(w,b,α)中,可以得到:

m i n w m a x α L ( w , b , α ) = m a x α m i n w L ( w , b , α ) = m a x α m i n w 1 2 ∑ i = 1 m ∑ j = 1 m α i α j y i y j x i x j T + ∑ i = 1 m ( α i − α i y i ∑ j = 1 m α j y j x j T x i − b ∗ α i y i ) = m a x α ∑ i = 1 m α i − 1 2 ∑ i = 1 m ∑ j = 1 m α i α j y i y j x i x j T min_w max_\alpha L(w,b,\alpha)=max_\alpha min_w L(w,b,\alpha) = max_\alpha min_w\frac{1}{2}\sum_{i=1}^{m}\sum_{j=1}^{m}\alpha_i\alpha_jy_iy_jx_ix_j^T + \sum_{i=1}^{m}(\alpha_i-\alpha_iy_i\sum_{j=1}^{m}\alpha_jy_jx_j^Tx_i-b*\alpha_iy_i) = max_\alpha \sum_{i=1}^{m}\alpha_i - \frac{1}{2}\sum_{i=1}^{m}\sum_{j=1}^{m}\alpha_i\alpha_jy_iy_jx_ix_j^T minwmaxαL(w,b,α)=maxαminwL(w,b,α)=maxαminw21i=1mj=1mαiαjyiyjxixjT+i=1m(αiαiyij=1mαjyjxjTxibαiyi)=maxαi=1mαi21i=1mj=1mαiαjyiyjxixjT

SMO算法的目标是求解一系列 α \alpha α和b来求得上述式子中的最优值。

SMO算法工作原理为,每次选择一对α进行优化处理,一旦找到一对合适的α,就增大一个α同时减小另一个α(这是由限制条件 ∑ i = 1 m y i α i = 0 \sum_{i=1}^m y_i\alpha_i=0 i=1myiαi=0的原因)。这里的合适的α需要满足一定条件,条件之一是两个α必须在间隔边界外(限制条件 0 ≤ α i ≤ C 0\le\alpha_i\le C 0αiC),而第二个条件则是两个α没有进行过区间化处理或者不在边界上。

选一对α进行优化:

m a x α ( α 1 + α 2 ) − 1 2 ( y 1 2 x 1 x 1 T ∗ α 1 2 + y 2 2 x 2 x 2 T ∗ α 2 2 + y 1 y 2 x 1 x 2 T ∗ α 1 α 2 + y 1 y 2 x 1 T x 2 ∗ α 1 α 2 + y 1 x 1 ∑ i = 1 m − 2 y i x i T α i ∗ α 1 + y 1 x 1 T ∑ i = 1 m − 2 y i x i α i ∗ α 1 + y 2 x 2 ∑ i = 1 m − 2 y i x i T α i ∗ α 2 + y 2 x 2 T ∑ i = 1 m − 2 y i α i x i ∗ α 2 ) max_\alpha (\alpha_1+\alpha_2) - \frac{1}{2}(y_1^2x_1x_1^T*\alpha_1^2+y_2^2x_2x_2^T * \alpha_2^2 + y_1y_2x_1x_2^T*\alpha_1\alpha_2 + y_1y_2x_1^Tx_2*\alpha_1\alpha_2+y_1x_1\sum_{i=1}^{m-2}y_ix_i^T\alpha_i *\alpha_1 + y_1x_1^T\sum_{i=1}^{m-2}y_ix_i\alpha_i*\alpha_1 + y_2x_2\sum_{i=1}^{m-2}y_ix_i^T\alpha_i * \alpha_2 + y_2x_2^T\sum_{i=1}^{m-2}y_i\alpha_ix_i *\alpha_2) maxα(α1+α2)21(y12x1x1Tα12+y22x2x2Tα22+y1y2x1x2Tα1α2+y1y2x1Tx2α1α2+y1x1i=1m2yixiTαiα1+y1x1Ti=1m2yixiαiα1+y2x2i=1m2yixiTαiα2+y2x2Ti=1m2yiαixiα2)

y i 2 = 1 y_i^2=1 yi2=1;简化方程表示令 K i j = x i ∗ x j T = x i T ∗ x j K_{ij} = x_i*x_j^T=x_i^T*x_j Kij=xixjT=xiTxj;便于最小化求解,对整个式子取相反数可得:

原式 = m i n α 1 , α 2 1 2 K 11 α 1 2 + 1 2 K 22 α 2 2 + y 1 y 2 K 12 α 1 α 2 + y 1 ∑ i = 1 m − 2 K i 1 y i α i ∗ α 1 + y 2 ∑ i = 1 m − 2 K i 2 y i α i ∗ α 2 − ( α 1 + α 2 ) =min_{\alpha_1,\alpha_2} \frac{1}{2}K_{11}\alpha_1^2+\frac{1}{2}K_{22}\alpha_2^2+y_1y_2K_{12}\alpha_1\alpha_2 + y_1\sum_{i=1}^{m-2}K_{i1}y_i\alpha_i *\alpha_1+y_2\sum_{i=1}^{m-2}K_{i2}y_i\alpha_i * \alpha_2-(\alpha_1+\alpha_2) =minα1,α221K11α12+21K22α22+y1y2K12α1α2+y1i=1m2Ki1yiαiα1+y2i=1m2Ki2yiαiα2(α1+α2)

约束条件
1. α 1 y 1 + α 2 y 2 = − ∑ i = 1 m − 2 α i y i = ζ 1.\alpha_1y_1 + \alpha2y_2=-\sum_{i=1}^{m-2}\alpha_iy_i = \zeta 1.α1y1+α2y2=i=1m2αiyi=ζ

2.0 ≤ α i ≤ C 2.0\le\alpha_i\le C 2.0αiC

现在上述问题转变成为了一个类似于二次函数求极值的问题。

2.问题求解

首先,根据 α 1 y 1 + α 2 y 2 = − ∑ i = 1 m − 2 α i y i = ζ \alpha_1y_1 + \alpha_2y_2=-\sum_{i=1}^{m-2}\alpha_iy_i = \zeta α1y1+α2y2=i=1m2αiyi=ζ得到 α 1 = ( ζ − α 2 y 2 ) / y 1 \alpha_1=(\zeta-\alpha_2y_2)/y_1 α1=(ζα2y2)/y1,将该式代入到求解式中进行消元。
消元后,原式 = 1 2 K 11 ( ζ − α 2 y 2 ) 2 / y 1 2 + 1 2 K 22 α 2 2 + K 12 y 2 α 2 ( ζ − α 2 y 2 ) + ( ζ − α 2 y 2 ) ∑ i = 1 m − 2 K i 1 y i α i + y 2 α 2 ∑ i = 1 m − 2 K i 2 y i α i − ( ( ζ − α 2 y 2 ) / y 1 + α 2 ) =\frac{1}{2}K_{11}(\zeta-\alpha_2y_2)^2/y_1^2+\frac{1}{2}K_{22}\alpha_2^2+K_{12}y_2\alpha_2(\zeta-\alpha_2y_2)+(\zeta-\alpha_2y_2)\sum_{i=1}^{m-2}K_{i1}y_i\alpha_i+y_2\alpha_2\sum_{i=1}^{m-2}K_{i2}y_i\alpha_i-((\zeta-\alpha_2y_2)/y_1+\alpha_2) =21K11(ζα2y2)2/y12+21K22α22+K12y2α2(ζα2y2)+(ζα2y2)i=1m2Ki1yiαi+y2α2i=1m2Ki2yiαi((ζα2y2)/y1+α2)

2.1.极值点求解

首先对 α 2 \alpha_2 α2进行求导,求出其极值点:

f ′ ( α 2 ) = K 11 ( ζ − α 2 y 2 ) + K 22 α 2 + K 12 y 2 ζ − 2 K 12 − y 2 ∑ i = 1 m − 2 K i 2 y i α i − ( 1 − y 2 / y 1 ) f^{'}(\alpha_2)=K_{11}(\zeta-\alpha_2y_2)+K_{22}\alpha_2+K_{12}y_2\zeta-2K_{12}-y_2\sum_{i=1}^{m-2}K_{i2}y_i\alpha_i-(1-y_2/y_1) f(α2)=K11(ζα2y2)+K22α2+K12y2ζ2K12y2i=1m2Ki2yiαi(1y2/y1)

f ′ ( α 2 ) = 0 f^{'}(\alpha_2)=0 f(α2)=0,可以推出 ( K 11 + K 22 − 2 K 12 ) α 2 = y 2 ( y 2 − y 1 + ( K 11 − K 12 ) ζ + ∑ i = 3 m α i y i ( K i 1 − K i 2 ) ) (K_{11}+K_{22}-2K_{12})\alpha_2=y_2(y_2-y_1+(K_{11}-K_{12})\zeta+\sum_{i=3}^{m}\alpha_iy_i(K_{i1}-K_{i2})) (K11+K222K12)α2=y2(y2y1+(K11K12)ζ+i=3mαiyi(Ki1Ki2))

由上一篇提到的核函数可以得出 g ( x ) = ∑ i = 1 m α i y i K ( x i , x ) + b g(x)=\sum_{i=1}^m\alpha_iy_iK(x_i,x)+b g(x)=i=1mαiyiK(xi,x)+b

v i = ∑ j = 3 m α j y j K ( x i , x j ) = g ( x i ) − ∑ i = 1 2 α j y j K ( x i , x j ) − b v_i=\sum_{j=3}^m\alpha_jy_jK(x_i,x_j)=g(x_i)-\sum_{i=1}^2\alpha_jy_jK(x_i,x_j)-b vi=j=3mαjyjK(xi,xj)=g(xi)i=12αjyjK(xi,xj)b

则上式可变为 ( K 11 + K 22 − 2 K 12 ) α 2 = y 2 ( y 2 − y 1 + ( K 11 − K 12 ) ζ + v 1 − v 2 ) (K_{11}+K_{22}-2K_{12})\alpha_2=y_2(y_2-y_1+(K_{11}-K_{12})\zeta+v_1-v_2) (K11+K222K12)α2=y2(y2y1+(K11K12)ζ+v1v2)

= y 2 ( y 2 − y 1 + ( K 11 − K 12 ) ζ + g ( x 1 ) − g ( x 2 ) + α 1 y 1 ( K 12 − K 11 ) + α 2 y 2 ( K 22 − K 21 ) ) =y_2(y_2-y_1+(K_{11}-K_{12})\zeta+g(x_1)-g(x_2)+\alpha_1y_1(K_{12}-K_{11})+\alpha_2y_2(K_{22}-K_{21})) =y2(y2y1+(K11K12)ζ+g(x1)g(x2)+α1y1(K12K11)+α2y2(K22K21))

再将 α 2 o l d y 2 + α 1 o l d y 1 = ζ \alpha_2^{old}y_2+\alpha_1^{old}y_1=\zeta α2oldy2+α1oldy1=ζ代入

( K 11 + K 22 − 2 K 12 ) α 2 = α 2 o l d ( K 11 + K 22 − 2 K 12 ) + y 2 ( E 1 − E 2 ) (K_{11}+K_{22}-2K_{12})\alpha_2=\alpha_2^{old}(K_{11}+K_{22}-2K_{12})+y_2(E_1-E_2) (K11+K222K12)α2=α2old(K11+K222K12)+y2(E1E2)

其中 E i = g ( x i ) − y i , g ( x i ) 为 估 计 值 , y i 为 实 际 值 , E i 为 误 差 E_i=g(x_i)-y_i,g(x_i)为估计值,y_i为实际值,E_i为误差 Ei=g(xi)yig(xi),yi,Ei

综 上 可 得 : α 2 n e w = α 2 o l d + y 2 ( E 1 − E 2 ) / η ; η = ( K 11 + K 22 − 2 K 12 ) 综上可得:\alpha_2^{new}=\alpha_2^{old}+y_2(E_1-E_2)/\eta;\eta=(K_{11}+K_{22}-2K_{12}) :α2new=α2old+y2(E1E2)/η;η=(K11+K222K12)

2.2.定义域考察

在高中我们就知道,求二次函数极值时,还需要考察极值点是否在定义域内,高中数学老师经常说的就是千万不要忘记定义域!

首先我们的约束条件为:

1. α 1 y 1 + α 2 y 2 = ζ 1.\alpha_1y_1+\alpha_2y_2=\zeta 1.α1y1+α2y2=ζ

2.0 ≤ α i ≤ C 2.0\le\alpha_i\le C 2.0αiC

其中约束范围可通过画图看出来,图为SMO论文内的图。
在这里插入图片描述
图中方形区域就是指 0 ≤ α 1 ≤ C 0\le\alpha_1\le C 0α1C 0 ≤ α 2 ≤ C 0\le\alpha_2\le C 0α2C共同围起来的区域,几条直线就是对应 α 1 y 1 + α 2 y 2 = ζ \alpha_1y_1+\alpha_2y_2=\zeta α1y1+α2y2=ζ的几种不同的情况.

α 1 y 1 + α 2 y 2 = ζ \alpha_1y_1+\alpha_2y_2=\zeta α1y1+α2y2=ζ式子中, y 1 y_1 y1 y 2 y_2 y2分别可以去-1,1,所以一共可分为4种情况:

(1) y 1 = 1 , y 2 = 1 y_1=1,y_2=1 y1=1y2=1,式子变为 α 1 + α 2 = ζ \alpha_1+\alpha_2=\zeta α1+α2=ζ

图像变为图像中右图所示,其截距为 ζ \zeta ζ,我们针对 ζ \zeta ζ不同取值范围来讨论.

ζ &lt; 0 o r ζ &gt; 2 C \zeta\lt0 or \zeta&gt;2C ζ<0orζ>2C

直线未落到矩形可行范围内,即可行域无解,为空集。

0 ≤ ζ ≤ C 0\le\zeta\le C 0ζC

图形对应右图中左下角的直线

α 2 \alpha_2 α2可行范围为 [ 0 , ζ ] [0,\zeta] [0,ζ]

C &lt; ζ ≤ 2 C C\lt\zeta\le2C C<ζ2C

图形对应右图中右上角的直线

α 2 \alpha_2 α2可行范围为 [ ζ − C , C ] [\zeta-C,C] [ζC,C]

综上考虑 ζ \zeta ζ有可行域时, ζ \zeta ζ范围可表示为 [ m a x ( 0 , ζ − C ) , m i n ( ζ , C ) ] 即 [ m a x ( 0 , α 1 + α 2 − C ) , m i n ( α 1 + α 2 , C ) ] [max(0,\zeta-C),min(\zeta,C)]即[max(0,\alpha_1+\alpha_2-C),min(\alpha_1+\alpha_2,C)] [max(0,ζC),min(ζ,C)][max(0,α1+α2C),min(α1+α2,C)]

(2) y 1 = − 1 , y 2 = − 1 y_1=-1,y_2=-1 y1=1y2=1,式子变为 α 1 + α 2 = − ζ \alpha_1+\alpha_2=-\zeta α1+α2=ζ
图像仍为图像中右图所示,其截距为 − ζ -\zeta ζ,我们针对 − ζ -\zeta ζ不同取值范围来讨论.
其情况同(1)类似,所以可以看出图中截距k不一定为 ζ \zeta ζ
− ζ &lt; 0 o r − ζ &gt; 2 C -\zeta\lt0 or -\zeta&gt;2C ζ<0orζ>2C

直线未落到矩形可行范围内,即可行域无解,为空集。

0 ≤ − ζ ≤ C 0\le-\zeta\le C 0ζC

图形对应右图中左下角的直线

α 2 \alpha_2 α2可行范围为 [ 0 , − ζ ] [0,-\zeta] [0,ζ]

C &lt; − ζ ≤ 2 C C\lt-\zeta\le2C C<ζ2C

图形对应右图中右上角的直线

α 2 \alpha_2 α2可行范围为 [ − ζ − C , C ] [-\zeta-C,C] [ζC,C]

综上考虑 − ζ -\zeta ζ有可行域时, − ζ -\zeta ζ范围可表示为 [ m a x ( 0 , − ζ − C ) , m i n ( − ζ , C ) ] 即 [ m a x ( 0 , α 1 + α 2 − C ) , m i n ( α 1 + α 2 , C ) ] [max(0,-\zeta-C),min(-\zeta,C)]即[max(0,\alpha_1+\alpha_2-C),min(\alpha_1+\alpha_2,C)] [max(0,ζC),min(ζ,C)][max(0,α1+α2C),min(α1+α2,C)]

(3) y 1 = 1 , y 2 = − 1 y_1=1,y_2=-1 y1=1y2=1,式子变为 α 1 − α 2 = ζ \alpha_1-\alpha_2=\zeta α1α2=ζ

图形变为左图中的情况,截距为 ζ \zeta ζ,我们针对 ζ \zeta ζ不同取值范围来讨论.

ζ &lt; − C o r ζ &gt; C \zeta\lt-Cor\zeta\gt C ζ<Corζ>C

直线未落到矩形可行范围内,即可行域无解,为空集。

0 &lt; ζ ≤ C 0\lt\zeta\le C 0<ζC

图形对应左图中右下角的直线

α 2 \alpha_2 α2可行范围为 [ 0 , C − ζ ] [0,C-\zeta] [0,Cζ]

− C ≤ ζ ≤ 0 -C\le \zeta \le0 Cζ0

图形对应左图中左上角的直线

α 2 \alpha_2 α2可行范围为 [ − ζ , C ] [-\zeta,C] [ζ,C]

综上考虑 ζ \zeta ζ有可行域时, ζ \zeta ζ范围可表示为 [ m a x ( 0 , − ζ ) , m i n ( C − ζ , C ) ] 即 [ m a x ( 0 , α 2 − α 1 ) , m i n ( C + α 2 − α 1 , C ) ] [max(0,-\zeta),min(C-\zeta,C)]即[max(0,\alpha_2-\alpha_1),min(C+\alpha_2-\alpha_1,C)] [max(0,ζ),min(Cζ,C)][max(0,α2α1),min(C+α2α1,C)]

(4) y 1 = − 1 , y 2 = 1 y_1=-1,y_2=1 y1=1y2=1,式子变为 α 1 − α 2 = − ζ \alpha_1-\alpha_2=-\zeta α1α2=ζ

情况同前面类似

综合以上四种情况,我们可以得到,
(1) y 1 = y 2 时 y_1=y_2时 y1=y2

α 2 可 行 范 围 为 [ m a x ( 0 , α 1 + α 2 − C ) , m i n ( α 1 + α 2 , C ) ] \alpha_2可行范围为[max(0,\alpha_1+\alpha_2-C),min(\alpha_1+\alpha_2,C)] α2[max(0,α1+α2C),min(α1+α2,C)]

区 间 端 点 L = m a x ( 0 , α 1 + α 2 − C ) , H = m i n ( α 1 + α 2 , C ) 区间端点L=max(0,\alpha_1+\alpha_2-C),H=min(\alpha_1+\alpha_2,C) L=max(0,α1+α2C),H=min(α1+α2,C)

(2) y 1 ! = y 2 时 y_1!=y_2时 y1!=y2

α 2 可 行 范 围 为 [ m a x ( 0 , α 2 − α 1 ) , m i n ( C + α 2 − α 1 , C ) ] \alpha_2可行范围为[max(0,\alpha_2-\alpha_1),min(C+\alpha_2-\alpha_1,C)] α2[max(0,α2α1),min(C+α2α1,C)]

区 间 端 点 L = m a x ( 0 , α 2 − α 1 ) , H = m i n ( C + α 2 − α 1 , C ) 区间端点L=max(0,\alpha_2-\alpha_1),H=min(C+\alpha_2-\alpha_1,C) L=max(0,α2α1)H=min(C+α2α1,C)

2.3.开口方向

我们的目标是上文的 m i n α 1 , α 2 1 2 K 11 α 1 2 + 1 2 K 22 α 2 2 + y 1 y 2 K 12 α 1 α 2 + y 1 ∑ i = 1 m − 2 K i 1 y i α i ∗ α 1 + y 2 ∑ i = 1 m − 2 K i 2 y i α i ∗ α 2 − ( α 1 + α 2 ) min_{\alpha_1,\alpha_2} \frac{1}{2}K_{11}\alpha_1^2+\frac{1}{2}K_{22}\alpha_2^2+y_1y_2K_{12}\alpha_1\alpha_2 + y_1\sum_{i=1}^{m-2}K_{i1}y_i\alpha_i *\alpha_1+y_2\sum_{i=1}^{m-2}K_{i2}y_i\alpha_i * \alpha_2-(\alpha_1+\alpha_2) minα1,α221K11α12+21K22α22+y1y2K12α1α2+y1i=1m2Ki1yiαiα1+y2i=1m2Ki2yiαiα2(α1+α2),要求其最小值,还需要判断极值点是否为极小值点。

(1)开口向上: K 11 + K 22 − 2 K 12 &gt; 0 K_{11}+K_{22}-2K_{12}&gt;0 K11+K222K12>0

判断极值点是否在定义域内,进行参数更新,可以想象一个二次函数

①如果这个极值点在可行域左边,那么我们可以得到这个可行域内二次函数一定在单增,所以此时L应该是那个取最小值的地方。就如大括号的第三种情况

②如果这个极值点在可行域右边,那么此时可行域内一定单减,所以此时H就是那个取最小值的地方,就是大括号里的第一种情况。
在这里插入图片描述
(2)开口向下或者退化成为一次函数: K 11 + K 22 − 2 K 12 ≤ 0 K_{11}+K_{22}-2K_{12}\le0 K11+K222K120

这种情况下极小值在端点处取得,可以通过计算两端端点值取最小的。

3.参数更新总结

①求出的可行域

②根据这一项 K 11 + K 22 − 2 K 12 K_{11}+K_{22}-2K_{12} K11+K222K12和0的关系:

如果 K 11 + K 22 − 2 K 12 &gt; 0 K_{11}+K_{22}-2K_{12}&gt;0 K11+K222K12>0,那么就直接利用之前求好的公式求出新的极值点处的 α 2 \alpha_2 α2,然后看这个 α 2 \alpha_2 α2和可行域的关系,得到 α 2 \alpha_2 α2的新值

如果 K 11 + K 22 − 2 K 12 ≤ 0 K_{11}+K_{22}-2K_{12}\le0 K11+K222K120,那么就直接求出H和L对应的边界值,哪个小,就让 α 2 \alpha_2 α2取哪个值

③根据新的 α 2 \alpha_2 α2求出新的 α 1 \alpha_1 α1

④更新ω很简单,利用 w − ∑ i = 1 m α i y i x i = 0 w-\sum_{i=1}^{m}\alpha_iy_ix_i=0 wi=1mαiyixi=0求解,现在还需要说一下b的更新:

利用 1 − y i ( w T x i + b ) = 0 1-y_i(w^Tx_i + b)=0 1yi(wTxi+b)=0进行求解

上式进一步推导, b = 1 / y i − ∑ j = 1 m y i α i K ( x i , x j ) b=1/y_i-\sum_{j=1}^my_i\alpha_iK(x_i,x_j) b=1/yij=1myiαiK(xi,xj)

b 1 n e w = y 1 − y 1 α 1 n e w K 11 − y 2 α 2 n e w K 12 − ∑ i = 3 m y i α i K i 1 b_1^{new}=y_1-y_1\alpha_1^{new}K_{11}-y_2\alpha_2^{new}K_{12}-\sum_{i=3}^my_i\alpha_iK_{i1} b1new=y1y1α1newK11y2α2newK12i=3myiαiKi1

E 1 = g ( x 1 ) − y 1 = α 1 o l d y 1 K 11 + α 2 o l d y 2 K 12 + ∑ i = 3 m y i α i K i 1 + b 1 o l d − y 1 E_1=g(x_1)-y_1=\alpha_1^{old}y_1K_{11}+\alpha_2^{old}y_2K_{12}+\sum_{i=3}^my_i\alpha_iK_{i1}+b_1^{old} -y_1 E1=g(x1)y1=α1oldy1K11+α2oldy2K12+i=3myiαiKi1+b1oldy1

消元后可得:

b 1 n e w = b 1 o l d + ( α 1 o l d − α 1 n e w ) y 1 K 11 + ( α 2 o l d − α 2 n e w ) y 2 K 12 − E 1 b_1^{new}=b_1^{old}+(\alpha_1^{old}-\alpha_1^{new})y_1K_{11}+(\alpha_2^{old}-\alpha_2^{new})y_2K_{12}-E_1 b1new=b1old+(α1oldα1new)y1K11+(α2oldα2new)y2K12E1

4.更新参数 α \alpha α的选取

4.1.寻找第一个待更新 α \alpha α

①遍历一遍整个数据集,对每个不满足KKT条件的参数,选作第一个待修改参数

②在上面对整个数据集遍历一遍后,选择那些参数满足 0 &lt; α &lt; C 0\lt\alpha\lt C 0<α<C的子集,开始遍历,如果发现一个不满足KKT条件的,作为第一个待修改参数,然后找到第二个待修改的参数并修改,修改完后,重新开始遍历这个子集

③遍历完子集后,重新开始①②,直到在执行①和②时没有任何修改就结束

4.2.寻找第二个待更新 α \alpha α

①启发式找,找能让 ∣ E 1 − E 2 ∣ |E_1-E_2| E1E2最大的

②寻找一个随机位置的满足 0 &lt; α &lt; C 0\lt\alpha\lt C 0<α<C的可以优化的参数进行修改

③在整个数据集上寻找一个随机位置的可以优化的参数进行修改

④都不行那就找下一个第一个参数

ri = Eiyi
关于寻找不满足KKT条件第一个α认识(有疑问),伪码中 if ((r2<-tol) and (α<C))or((r2>tol)and(α>0)) tol为容错率

KKT条件为:

1. w − ∑ i = 1 m α i y i x i = 0 1.w-\sum_{i=1}^{m}\alpha_iy_ix_i=0 1.wi=1mαiyixi=0

2. ∑ i = 1 m y i α i = 0 2.\sum_{i=1}^m y_i\alpha_i=0 2.i=1myiαi=0

3. y i ( w T x i + b ) − 1 ≥ 0 3.y_i(w^Tx_i + b)-1\ge0 3.yi(wTxi+b)10

4.0 ≤ α ≤ C 4.0\le\alpha\le C 4.0αC

5. α i ∗ ( 1 − y i ( w T x i + b ) ) = 0 5.\alpha_i*(1-y_i(w^Tx_i + b))=0 5.αi(1yi(wTxi+b))=0

r i = E i y i = ( g ( x i ) − y i ) y i = y i g ( x i ) − 1 r_i=E_iy_i=(g(x_i)-y_i)y_i=y_ig(x_i)-1 ri=Eiyi=(g(xi)yi)yi=yig(xi)1

r i &lt; − t o l = &gt; y i g ( x i ) &lt; 1 − t o l &lt; 1 r_i&lt;-tol=&gt;y_ig(x_i)&lt;1-tol&lt;1 ri<tol=>yig(xi)<1tol<1又KKT条件中 y i ( w T x i + b ) ≥ 1 y_i(w^Tx_i + b)\ge1 yi(wTxi+b)1

r i &gt; t o l = &gt; y 2 g ( x i ) &gt; 1 + t o l &gt; 1 r_i&gt;tol=&gt;y_2g(x_i)&gt;1+tol&gt;1 ri>tol=>y2g(xi)>1+tol>1

以下为部分在机器学习实战中的代码,加深算法理解

import numpy as np
import random

def selectJrand(i,m):
    j = i
    while j == i:
        j = int(random.uniform(0,m))
        
    return j

def clipAlpha(aj,H,L):
    if aj>H:
        aj = H
    if aj<L:
        aj = L
    
    return aj

def svmSimple(dataMatIn,classLabels,C,toler,maxIter):
    dataMatrix = np.mat(dataMatIn)
    labelMat = np.mat(classLabels).transpose()
    b = 0
    m,n = np.shape(dataMatIn)
    alphas = np.zeros((m,1))
    iter = 0
    while iter < maxIter:
        alphaPairsChanged = 0
        for i in range(m):
            fXi = float(np.multiply(alphas,labelMat).T * dataMatrix * dataMatrix[i,:].T) + b
            Ei = fXi - float(labelMat[i])
            if ((labelMat[i]*Ei > toler) and (alphas[i] > 0)) or ((labelMat[i] * Ei < -toler) and (alphas[i] < C)): #误差超过容错率
                j = selectJrand(i,m)
                fXj = float(np.multiply(alphas,labelMat).T * dataMatrix * dataMatrix[j,:].T) + b
                Ej = fXj - labelMat[j]
                alphaIold = alphas[i].copy()
                alphaJold = alphas[j].copy()
                if labelMat[i] != labelMat[j]: # 定义域
                    L = max(0,alphas[j] - alphas[i])
                    H = min(C,C + alpha[j] - alpha[i])
                else:
                    L = max(0,alphas[j] + alphas[i] - C)
                    H = min(C,alphas[j] + alphas[i])
                if L == H:
                    print("L==H")
                    continue
                eta = 2.0 * dataMatrix[i,:]*dataMatrix[j,:].T -dataMatrix[i] * dataMatrix[i,:].T - dataMatrix[j,:]*dataMatrix[j,:].T
                if eta >= 0: # 开口方向
                    print("eta >= 0")
                    continue
                alphas[j] -= labelMat[j]*(Ei - Ej)/eta #减号因为eta符号与计算是相反的
                alphas[j] = clipAlpha(alphas[j],H,L)
                if abs(alphas[j] - alphaJold) < 0.00001:
                    print("j not moving enough")
                alphas[i] += labelMat[j]*labelMat[i] * (alphaJold - alphas[j])
                b1 = b - Ei - labelMat[i]*(alphas[i]-alphaIold)*dataMatrix[i,:]*dataMatrix[i,:].T - labelMat[j]*(alphas[j] - alphaJold)*dataMatrix[i,:]*dataMatrix[j,:].T
                b2 = b - Ej - labelMat[i]*(alphas[i]-alphaIold)*dataMatrix[i,:]*dataMatrix[j,:].T - labelMat[j]*(alphas[j] - alphaJold)*dataMatrix[j,:]*dataMatrix[j,:].T
                if (alphas[i] > 0) and (alphas[i] < C):
                    b = b1
                elif (alphas[j] > 0) and (alphas[j] < C):
                    b = b2
                else:
                    b = (b1 + b2) / 2.0
                alphaPairsChanged += 1
                print("iter:%d i:%d,pairs changed %d"%(iter,i,alphaPairsChanged))
        if alphaPairsChanged == 0:
            iter += 1
        else:
            iter = 0
        print("iteration number: %d"%iter)
    return b,alphas

class optStruct:
    def __init__(self,dataMatIn, classLabels, C, toler):
        self.X = dataMatIn
        self.labelMat = classLabels
        self.C = C
        self.tol = toler
        self.m = np.shape(dataMatIn)[0]
        self.alphas = np.mat(np.zeros((self.m,1)))
        self.b = 0
        self.eCache = np.mat(np.zeros((self.m,2)))

def calcEk(os, k):
    fXk = float(np.multiply(os.alphas,os.labelMat[k,:]).T * os.X * os.X[k,:].T) + os.b
    Ek = fXk - float(os.labelMat[k,:])
    return Ek

def selectJ(i,os,Ei):
    maxK = -1
    maxDeltaE = 0
    Ej = 0
    os.eCache[i] = [1,Ei]
    validEcacheList = np.nonzero(os.eCache[:,0].A)[0] #.A将mat转成array,返回第一维为0的可用eCache
    if len(validEcacheList) > 1:
        for k in validEcacheList:
            if k == i:
                continue
            Ek = calcEk(os,k)
            deltaE = abs(Ei - Ek)
            if deltaE > maxDeltaE:
                maxK = k
                maxDeltaE = deltaE
                Ej = Ek

        return maxK,Ej
    else: #第一次
        j = selectJrand(i,os.m)
        Ej = calcEk(os,j)
        return j,Ej

def updateEk(os,k):
    Ek = calcEk(os,k)
    os.eCache[k] = [1,Ek]

def innerL(i, os):
    Ei = calcEk(os, i)
    if ((os.labelMat[i] * Ei < -os.tol) and (os.alphas[i] < os.C)) or ((os.labelMat[i] * Ei > os.tol) and (os.alphas[i] > 0)):
        j,Ej = selectJ(i,os,Ei)
        alphaIold = os.alphas[i].copy()
        alphaJold = os.alphas[j].copy()
        if (os.labelMat[i] != os.labelMat[j]):
            L = max(0, os.alphas[j] - os.alphas[i])
            H = min(os.C, os.C + os.alphas[j] - os.alphas[i])
        else:
            L = max(0,os.alphas[j] + os.alphas[i] - os.C)
            H = min(os.C, os.alphas[j] + os.alphas[i])
        if L == H:
            print("L == H")
            return 0

        eta = 2.0 * os.X[i,:]*os.X[j,:].T - os.X[i,:]*os.X[i,:].T - os.X[j,:]*os.X[j,:].T
        if eta >= 0:
            print("eta >= 0")
            return 0

        os.alphas[j] -= os.labelMat[j] * (Ei - Ej)/eta
        os.alphas[j] = clipAlpha(os.alphas[j],H,L)
        updateEk(os,j)
        if (abs(os.alphas[j] - alphaJold) < 0.00001):
            print("j not moving enough")
            return 0
        os.alphas[i] += os.labelMat[j]*os.labelMat[i]*(alphaJold - os.alphas[j])
        updateEk(os,i)
        b1 = os.b - Ei - os.labelMat[i] *(os.alphas[i] - alphaIold)*os.X[i,:]*os.X[i,:].T - os.labelMat[j] * (os.alphas[j] - alphaJold)*os.X[i,:]*os.X[j,:].T
        b2 = os.b - Ej - os.labelMat[i] *(os.alphas[i] - alphaIold)*os.X[i,:]*os.X[j,:].T - os.labelMat[j] * (os.alphas[j] - alphaJold)*os.X[j,:]*os.X[j,:].T
        if (0<os.alphas[i]) and (os.C > os.alphas[i]):
            os.b = b1
        elif (0 < os.alphas[j]) and (os.C > os.alphas[j]):
            os.b = b2
        else:
            os.b = (b1 + b2) / 2.0
        return 1
    else:
        return 0

def smoP(dataMatIn, classLabels, C, toler, maxIter, kTup=('lin',0)):
    os = optStruct(np.mat(dataMatIn),np.mat(classLabels).transpose(),C,toler)
    iter = 0
    entireSet = True
    alphaPairsChanged = 0
    while (iter<maxIter) and ((alphaPairsChanged > 0) or (entireSet)):
        alphaPairsChanged = 0
        if entireSet:
            for i in range(os.m):
                alphaPairsChanged += innerL(i,os)
            print("fullSet,iter:%d i:%d, pairs changed %d"%(iter,i,alphaPairsChanged))
        else:
            nonBounfIs = np.nonzero((os.alphas.A > 0)*(os.alphas.A < C))[0]
            for i in nonBounfIs:
                alphaPairsChanged += innerL(i,os)
                print("non-bound,iter:%d i:%d, pairs changed %d" % (iter, i, alphaPairsChanged))
            iter += 1
        if entireSet:
            entireSet = False
        elif (alphaPairsChanged == 0):
            entireSet = True

    return os.b,os.alphas

参考链接:SMO算法的个人理解

  • 2
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值