嚼烂SVM-SMO算法并用python进行实现

转载请注明出处: 嚼烂SVM-SMO算法并用python进行实现

本文面向的读者为掌握SVM基础前置知识如读过《统计学习方法》,并希望对SMO细节有更深入了解的人羣。因为笔者想要实现一个简易的SVM,为了搞懂这部分费了不少工夫,所以写下这一篇嚼过的文章,目的是让读者跟着顺序阅读一定能弄懂。自己的行文习惯是简单的地方不能说太复杂,复杂的地方一定会说清楚

一, 推导至SMO要解决的SVM对偶形式

对于含soft margin的支持向量机, 其primitive problem:

minw,b,ξ12w2+Ci=1Nξis.t.yi(wxi+b)1ξi,i=1,2,,Nξi0,i=1,2,,N(1)(2)(3) (1) min w , b , ξ 1 2 ‖ w ‖ 2 + C ∑ i = 1 N ξ i (2) s . t . y i ( w ⋅ x i + b ) ≥ 1 − ξ i , i = 1 , 2 , ⋯ , N (3) ξ i ≥ 0 , i = 1 , 2 , ⋯ , N

求解此原始问题:

1, 构建Lagrange Function

引入拉格朗日乘子 αi0,μi0,i=1,2,,N α i ≥ 0 , μ i ≥ 0 , i = 1 , 2 , ⋯ , N 构建Lagrange Function:

L(w,b,ξ,α,μ)=12w2+Ci=1Nξi+i=1Nαi(yi(wxi+b)+1ξi)i=1Nμiξi(4) (4) L ( w , b , ξ , α , μ ) = 1 2 ‖ w ‖ 2 + C ∑ i = 1 N ξ i + ∑ i = 1 N α i ( − y i ( w ⋅ x i + b ) + 1 − ξ i ) − ∑ i = 1 N μ i ξ i

其中,

α=(α1,α2,,αN)T α = ( α 1 , α 2 , ⋯ , α N ) T 以及

μ=(μ1,μ2,,μN)T μ = ( μ 1 , μ 2 , ⋯ , μ N ) T
lagrange multiplier , 它们的每个分量都是非负数

2,转化为Lagrange Dual Problem

具体原理与KKT条件推导可看我上一篇博文:SVM之拉格朗日对偶问题与KKT条件推导
现在dual problem:

maxα,μminw,b,ξL(w,b,ξ,α,μ)(5) (5) max α , μ min w , b , ξ L ( w , b , ξ , α , μ )

3,先求内层的min

由于把 α,μ α , μ 都看作常量, 要求最小值就直接求偏导:

wL(w,b,ξ,α,μ)=wi=1Nαiyixi=0bL(w,b,ξ,α,μ)=i=1Nαiyi=0ξiL(w,b,ξ,α,μ)=Cαiμi=0(6)(7)(8) (6) ∇ w L ( w , b , ξ , α , μ ) = w − ∑ i = 1 N α i y i x i = 0 (7) ∇ b L ( w , b , ξ , α , μ ) = − ∑ i = 1 N α i y i = 0 (8) ∇ ξ i L ( w , b , ξ , α , μ ) = C − α i − μ i = 0

得:


w=i=1Nαiyixii=1Nαiyi=0Cαiμi=0(9)(10)(11) (9) w = ∑ i = 1 N α i y i x i (10) ∑ i = 1 N α i y i = 0 (11) C − α i − μ i = 0

把(9)-(11) 代入(4)可得(这里引入了kernel function):

minw,b,ξL(w,b,ξ,α,μ)=12i=1Ni=1NαiαjyiyjK(xi,xj)+i=1Nαi(12) (12) min w , b , ξ L ( w , b , ξ , α , μ ) = − 1 2 ∑ i = 1 N ∑ i = 1 N α i α j y i y j K ( x i , x j ) + ∑ i = 1 N α i

4, 求解外层的max

对式(12)求解max:

maxα,μ12s.t.i=1Ni=1NαiαjyiyjK(xi,xj)+i=1Nαii=1Nαiyi=0Cαiμi=0αi0μi0(13)(14)(15)(16)(17) (13) max α , μ − 1 2 ∑ i = 1 N ∑ i = 1 N α i α j y i y j K ( x i , x j ) + ∑ i = 1 N α i (14) s . t . ∑ i = 1 N α i y i = 0 (15) C − α i − μ i = 0 (16) α i ≥ 0 (17) μ i ≥ 0

式(15)-(17) 可简化为:


0αiC(18) (18) 0 ≤ α i ≤ C

5,最终形式:一个凸二次规划的对偶问题

minαs.t.12i=1Nj=1NαiαjyiyjK(xi,xj)i=1Nαii=1Nαiyi=00αiC,i=1,2,,N(19)(20)(21) (19) min α 1 2 ∑ i = 1 N ∑ j = 1 N α i α j y i y j K ( x i , x j ) − ∑ i = 1 N α i (20) s . t . ∑ i = 1 N α i y i = 0 (21) 0 ≤ α i ≤ C , i = 1 , 2 , ⋯ , N

收敛的值需满足的
KKT condition(求解SMO时有用):

wL(w,b,ξ,α,μ)bL(w,b,ξ,α,μ)ξiL(w,b,ξ,α,μ)αi1ξi+yi(αi(1ξi+yiμiξiμiξi=wi=1Nαiyixi=0=i=1Nαiyi=0=Cαiμi=00wx+b)0(wx+b))=000=0(22)(23)(24)(25)(26)(27)(28)(29)(30) (22) ∇ w L ( w ∗ , b ∗ , ξ ∗ , α ∗ , μ ∗ ) = w ∗ − ∑ i = 1 N α i ∗ y i x i = 0 (23) ∇ b L ( w ∗ , b ∗ , ξ ∗ , α ∗ , μ ∗ ) = − ∑ i = 1 N α i ∗ y i = 0 (24) ∇ ξ i L ( w ∗ , b ∗ , ξ ∗ , α ∗ , μ ∗ ) = C − α i ∗ − μ i ∗ = 0 (25) α i ∗ ≥ 0 (26) 1 − ξ i ∗ + y i ( w ∗ ⋅ x ∗ + b ∗ ) ≤ 0 (27) α i ∗ ( 1 − ξ i ∗ + y i ( w ∗ ⋅ x ∗ + b ∗ ) ) = 0 (28) μ i ∗ ≥ 0 (29) ξ i ∗ ≤ 0 (30) μ i ∗ ξ i ∗ = 0

一共3个偏导为0 + 2*3个乘子与不等式约束间满足的条件 = 9个KKT 条件

二,切入正题:SMO算法完整推导

SMO算法,首先选择 α α 的两个分量来求解式(19)的子问题,思路是不断迭代求解原问题的子问题来逼近原始问题的解, 具体怎么选取这两个分量待会儿再说

1, 选取两个 α α 的分量,求解式(19)子问题,目的是获取对这两个分量进行更新的方法

minα1,α2W(α1,α2)=12α21K11+12α22K22+α1α2y1y2K12+α1y1i=3NαiyiK1i+α2y2i=3NαiyiK2iα1α2s.t.α1y1+α2y2=i=3Nyiαi=ς0αiC,i=1,2(31)(32)(33) (31) min α 1 , α 2 W ( α 1 , α 2 ) = 1 2 α 1 2 K 11 + 1 2 α 2 2 K 22 + α 1 α 2 y 1 y 2 K 12 + α 1 y 1 ∑ i = 3 N α i y i K 1 i + α 2 y 2 ∑ i = 3 N α i y i K 2 i − α 1 − α 2 (32) s . t . α 1 y 1 + α 2 y 2 = − ∑ i = 3 N y i α i = ς (33) 0 ≤ α i ≤ C , i = 1 , 2

1.1 换元

有两个变量,那先通过式(32)的变形式 α1=(ςα2y2)y1 α 1 = ( ς − α 2 y 2 ) y 1 代入式(31)换为只包含 α2 α 2 的式子:

minα2W(α2)=12(ςα2y2)2K11+12α22K22+(ςα2y2)α2y2K12+(ςα2y2)i=3NαiyiK1i+α2y2i=3NαiyiK2i(ςα2y2)y1α2(34) (34) min α 2 W ( α 2 ) = 1 2 ( ς − α 2 y 2 ) 2 K 11 + 1 2 α 2 2 K 22 + ( ς − α 2 y 2 ) α 2 y 2 K 12 + ( ς − α 2 y 2 ) ∑ i = 3 N α i y i K 1 i + α 2 y 2 ∑ i = 3 N α i y i K 2 i − ( ς − α 2 y 2 ) y 1 − α 2

1.2 求极值点

明显地,对 α2 α 2 求偏导并令其为0:

Wα2=ςy2K11+K11α2+K22α2+ςy2K122K12α2y2i=3NαiyiK1i+y2i=3NαiyiK2i+y1y21=(K11+K222K12)α2+y2(ςK11+ςK12i=3NαiyiK1i+i=3NαiyiK2i+y1y2)(35)(36) (35) ∂ W α 2 = − ς y 2 K 11 + K 11 α 2 + K 22 α 2 + ς y 2 K 12 − 2 K 12 α 2 − y 2 ∑ i = 3 N α i y i K 1 i + y 2 ∑ i = 3 N α i y i K 2 i + y 1 y 2 − 1 (36) = ( K 11 + K 22 − 2 K 12 ) α 2 + y 2 ( − ς K 11 + ς K 12 − ∑ i = 3 N α i y i K 1 i + ∑ i = 3 N α i y i K 2 i + y 1 − y 2 )

这里要设置一些方便的符号:

1, 模型对

x x 的预测值


g(x)=i=1NαiyiK(xi,x)+b(37) (37) g ( x ) = ∑ i = 1 N α i y i K ( x i , x ) + b

2, 预测值减去真实值


Ei=g(xi)yi=(j=1NαjyjK(xj,xi)+b)yi,i=1,2(38) (38) E i = g ( x i ) − y i = ( ∑ j = 1 N α j y j K ( x j , x i ) + b ) − y i , i = 1 , 2

3,式(36)中比较难处理的那一坨


vi=j=3NαjyjKij=g(xi)j=12αjyjKijb,i=1,2=Ei+yij=12αjyjKijb,i=1,2(39)(40) (39) v i = ∑ j = 3 N α j y j K i j = g ( x i ) − ∑ j = 1 2 α j y j K i j − b , i = 1 , 2 (40) = E i + y i − ∑ j = 1 2 α j y j K i j − b , i = 1 , 2

还要注意

α1y1+α2y2=2i=1αiyi=ς α 1 y 1 + α 2 y 2 = ∑ i = 1 2 α i y i = ς

令式(36)为0, 并代入上面的符号:


(K11+K222K12)αnew,unc2=y2(ςK11ςK12+i=3NαiyiK1ii=3NαiyiK2iy1+y2)=y2(i=12αiyiK11i=12αiyiK12+v1v2y1+y2)=y2(i=12αiyiK11i=12αiyiK12+E1+y1i=12αiyiK1ibE2y2+i=12αiyiK2i+by1+y2)=y2(E1E2+α2y2K112α2y2K12+α2y2K22)=(K112K12+K22)α2+y2(E1E2)(41)(42)(43)(44)(45) (41) ( K 11 + K 22 − 2 K 12 ) α 2 n e w , u n c = y 2 ( ς K 11 − ς K 12 + ∑ i = 3 N α i y i K 1 i − ∑ i = 3 N α i y i K 2 i − y 1 + y 2 ) (42) = y 2 ( ∑ i = 1 2 α i y i K 11 − ∑ i = 1 2 α i y i K 12 + v 1 − v 2 − y 1 + y 2 ) (43) = y 2 ( ∑ i = 1 2 α i y i K 11 − ∑ i = 1 2 α i y i K 12 + E 1 + y 1 − ∑ i = 1 2 α i y i K 1 i − b − E 2 − y 2 + ∑ i = 1 2 α i y i K 2 i + b − y 1 + y 2 ) (44) = y 2 ( E 1 − E 2 + α 2 y 2 K 11 − 2 α 2 y 2 K 12 + α 2 y 2 K 22 ) (45) = ( K 11 − 2 K 12 + K 22 ) α 2 + y 2 ( E 1 − E 2 )

1.3 获取 αnew,unc2 α 2 n e w , u n c 的迭代方式

由式(45)可得:

αnew,unc2=αold2+y2(E1E2)K112K12+K22(46) (46) α 2 n e w , u n c = α 2 o l d + y 2 ( E 1 − E 2 ) K 11 − 2 K 12 + K 22

1.4 根据 α2 α 2 的定义域裁剪得到 αnew2 α 2 n e w

上式左边有unc, 意味着没有进行cut,现在我们讨论下 α2 α 2 的取值范围:
关于 α1,α2 α 1 , α 2 的约束条件一共就式(32),(33)两个式子
那么我们根据 y1,y2 y 1 , y 2 进行分类讨论:

  • y1=y2 y 1 = y 2
    根据式(32),设 α1+α2=k α 1 + α 2 = k
    根据式(33),可得:
    {00α2Ckα2C{0α2CkCα2k{0α2Cαold1+αold2Cα2αold1+αold2 { 0 ≤ α 2 ≤ C 0 ≤ k − α 2 ≤ C ⇒ { 0 ≤ α 2 ≤ C k − C ≤ α 2 ≤ k ⇒ { 0 ≤ α 2 ≤ C α 1 o l d + α 2 o l d − C ≤ α 2 ≤ α 1 o l d + α 2 o l d
    α2 α 2 上界为 H H ,下界为 L L , 则有:
    L=max(0,αold1+αold2C)H=min(C,αold1+αold2)(47)(48) (47) L = max ( 0 , α 1 o l d + α 2 o l d − C ) (48) H = min ( C , α 1 o l d + α 2 o l d )
  • y1y2 y 1 ≠ y 2
    根据式(32),设 α1α2=k α 1 − α 2 = k
    根据式(33),可得:
    {00α2Cα2+kC{0kα2Cα2Ck{0αold2αold1α2Cα2C+αold2αold1 { 0 ≤ α 2 ≤ C 0 ≤ α 2 + k ≤ C ⇒ { 0 ≤ α 2 ≤ C − k ≤ α 2 ≤ C − k ⇒ { 0 ≤ α 2 ≤ C α 2 o l d − α 1 o l d ≤ α 2 ≤ C + α 2 o l d − α 1 o l d
    可得新的上下界:
    L=max(0,αold2αold1)H=min(C,C+αold2αold1)(49)(50) (49) L = max ( 0 , α 2 o l d − α 1 o l d ) (50) H = min ( C , C + α 2 o l d − α 1 o l d )

裁剪方法:

αnew2=H,αnew,unc2,L,αnew,unc2>HLαnew,unc2Cαnew,unc2<L α 2 n e w = { H , α 2 n e w , u n c > H α 2 n e w , u n c , L ≤ α 2 n e w , u n c ≤ C L , α 2 n e w , u n c < L

1.5 根据约束条件得到 αnew1 α 1 n e w

根据式(32)可得:

αold1y1+αold2y2=αnew1y1+αnew2y2(51) (51) α 1 o l d y 1 + α 2 o l d y 2 = α 1 n e w y 1 + α 2 n e w y 2

根据上式,有:


αnew1==(αold1y1+αold2y2αnew2y2)y1αold1+(αold2αnew2)y1y2(52)(53) (52) α 1 n e w = ( α 1 o l d y 1 + α 2 o l d y 2 − α 2 n e w y 2 ) y 1 (53) = α 1 o l d + ( α 2 o l d − α 2 n e w ) y 1 y 2

2, 通过对这两个 α α 分量的更新,获取其它变量的更新

2.1 计算阈值b

原理,通过支持向量,即正好在间隔边界的点来进行计算(此时 0<αi<C,yig(xi)=1 0 < α i < C , y i g ( x i ) = 1 ):

b=yij=1NαjyjKij(54) (54) b = y i − ∑ j = 1 N α j y j K i j

如果

α1 α 1 满足此条件,则


bnew1=y1i=3NαiyiK1iαnew1y1K11αnew2y2K12(55) (55) b 1 n e w = y 1 − ∑ i = 3 N α i y i K 1 i − α 1 n e w y 1 K 11 − α 2 n e w y 2 K 12

上面的公式有一部分可以用

E1 E 1 进行替换:


E1=g(x1)y1=i=3NαiyiK1i+αold1y1K11+αold2y2K21+boldy1(56) (56) E 1 = g ( x 1 ) − y 1 = ∑ i = 3 N α i y i K 1 i + α 1 o l d y 1 K 11 + α 2 o l d y 2 K 21 + b o l d − y 1

结合式(55)与式(56),将

E1 E 1 引入式(55)可得:


bnew1=E1+y1K11(αold1αnew1)+y2K12(αold2αnew2)+bold(57) (57) b 1 n e w = − E 1 + y 1 K 11 ( α 1 o l d − α 1 n e w ) + y 2 K 12 ( α 2 o l d − α 2 n e w ) + b o l d

每次计算的时候,存下

Ei E i 可以极大的方便计算

同理,如果

0<αnew2<C 0 < α 2 n e w < C , 则:


bnew2=E2+y1K12(αold1αnew1)+y2K22(αold2αnew2)+bold(58) (58) b 2 n e w = − E 2 + y 1 K 12 ( α 1 o l d − α 1 n e w ) + y 2 K 22 ( α 2 o l d − α 2 n e w ) + b o l d

下面讨论

bnew b n e w 的最终取值:

  • 0<α1<C 0 < α 1 < C , 0<α2<C 0 < α 2 < C :
    bnew=bnew1=bnew2 b n e w = b 1 n e w = b 2 n e w (此时 x1 x 1 x2 x 2 都在间隔边界上)

  • 若只有一个 0<αi<C,i{1,2} 0 < α i < C , i ∈ { 1 , 2 }
    bnew=bnewi b n e w = b i n e w

  • α1,α2{0,C} α 1 , α 2 ∈ { 0 , C }
    bnew=12(bnew1+bnew2) b n e w = 1 2 ( b 1 n e w + b 2 n e w ) , (若 αi=0 α i = 0 说明 xi x i 不是支持向量, yig(xi)1 y i g ( x i ) ≥ 1 , xi x i 在正确分类的间隔一侧, αi=C α i = C 说明 yig(xi)1 y i g ( x i ) ≤ 1 , 这些都可以从式(22)-式(30)的KKT条件推出,下面还会推导)

2.2 更新 Ei E i ,方便下一次的 b b 计算

Ei=sαjyjKijyi(59) (59) E i = ∑ s α j y j K i j − y i

其中

s s 是所有>0的

αj α j , 即所有支持向量

3 α α 选取策略

3.1 通过满足KKT条件与否选择 α1 α 1

因为收敛后的最优解是满足KKT条件的,所以第一次选择最不满足KKT条件的 α α :
从式(22)-(30)可得:

  • αi=0 α i = 0
    (1), 根据 Cαiui=0 C − α i ∗ − u i ∗ = 0 可得 ui=C>0 u i ∗ = C > 0
    (2), 根据 uiξi=0 u i ∗ ξ i ∗ = 0 可得 ξi=0 ξ i ∗ = 0
    (3), 根据 yi(wxi+b)1ξi y i ( w ∗ x i + b ∗ ) ≥ 1 − ξ i ∗ 可得 yi(wxi+b)1 y i ( w ∗ x i + b ∗ ) ≥ 1
    (4), 综上, αi=0yig(xi)1(60) (60) α i = 0 ⇔ y i g ( x i ) ≥ 1

  • 0<αi<C 0 < α i < C
    (1), 根据 Cαiui=0 C − α i ∗ − u i ∗ = 0 可得 ui>0 u i ∗ > 0
    (2), 根据 uiξi=0 u i ∗ ξ i ∗ = 0 可得 ξi=0 ξ i ∗ = 0
    (3), 根据 αi(yi(wxi+b)1+ξ)=0 α i ∗ ( y i ( w ∗ x i + b ∗ ) − 1 + ξ ∗ ) = 0 及上面一条可得 yi(wxi+b)1=0 y i ( w ∗ x i + b ∗ ) − 1 = 0
    (4), 综上, 0<αi<Cyig(xi)=1(61) (61) 0 < α i < C ⇔ y i g ( x i ) = 1

  • αi=C α i = C
    (1). 根据 Cαiui=0 C − α i ∗ − u i ∗ = 0 可得 ui=0 u i ∗ = 0
    (2). 根据 ui=0 u i ∗ = 0 uiξi=0 u i ∗ ξ i ∗ = 0 , ξi0 ξ i ∗ ≥ 0 可得 ξi0 ξ i ∗ ≥ 0
    (3). 根据 αi(yi(wxi+b)1+ξi)=0 α i ∗ ( y i ( w ∗ x i + b ∗ ) − 1 + ξ i ∗ ) = 0 αi=C>0 α i = C > 0 可得

    yi(wxi+b)1+ξi=0 y i ( w ∗ x i + b ∗ ) − 1 + ξ i ∗ = 0
    (4). 根据推论(2)及推论(3)可得: yi(wxi+b)1 y i ( w ∗ x i + b ∗ ) ≤ 1
    (5). 综上, αi=Cyig(xi)1(62) (62) α i = C ⇔ y i g ( x i ) ≤ 1

这里要说明一下,计算机里常有浮点数精度的问题,直接用”==”往往会得出错误的结果,上面的KKT条件检查全部都应该在 ϵ ϵ 的精度下进行
选择算法:首先选取 0<αi<C 0 < α i < C 的支持向量样本点,检查是否满足式(61)
如果不满足,则选择它
如果都满足,遍历整个训练集查看它们是否满足KKT条件, 如果都满足则满足停机条件

3.2 根据极大化 α1 α 1 的变化来寻找 α2 α 2

根据式(46), α1 α 1 E1E2 E 1 − E 2 呈线性关系,所以对 α2 α 2 的选取策略:
遍历找到使 |E1E2| | E 1 − E 2 | 最大的 E2 E 2 ,其对应的 α α 分量即为 α2 α 2
这里可以看出, E E 在更新 α2 α 2 , 阈值 b b 与寻找 α2 α 2 的过程中发挥了极大的作用

可是这个简单策略有时会找不到令目标函数式(19)有足够下降的点,怎么办呢?只能依次遍历在间隔边界上的点,看它们中是否有点能使目标函数有足够下降

如果还是找不到呢?那只能放弃 αi α i 重新选择了

所以到这里我发现SMO算法有回溯的情况

4 简单总结整个SMO算法的流程

1, 根据是否满足KKT条件寻找一个 α α 的分量作为 α1 α 1 , 满足停机条件则算法结束
2, 根据极大化 α1 α 1 的变化寻找 α2 α 2 , 这里可能会有回溯情况,重回第1步
3, 根据 E1,E2 E 1 , E 2 等,即式(46)得到 αnew,unc2 α 2 n e w , u n c
4, 对 αnew,unc2 α 2 n e w , u n c 进行定义域剪切得到 αnew2 α 2 n e w
5, 紧接着根据式(53)得到 αnew1 α 1 n e w
6, 根据(57),(58) 通过 Ei E i 获取 bnew1,bnew2 b 1 n e w , b 2 n e w
7, 根据 α1,α2 α 1 , α 2 0 0 C C 的大小关系获取 bnew b n e w
8, 更新 E1,E2 E 1 , E 2 ,为下一轮计算做准备

循环以上步骤直到达到指定的轮次数或满足停机条件

三. 用python实现核心步骤并进行代码片段讲解

大致讲解流程根据上面的算法流程来

1. 检查是否满足KKT条件

# check if the alpha[i] satisfy the KKT condition:
def _satisfy_KKT_(self, i):
    tmp = self.Y[i]*self._g_(i)
    # 式(60)
    if abs(self.alpha[i]) < self.epsilon: # epsilon is the precision for checking if two var equal
        return tmp >= 1
    # 式(62)
    elif abs(self.alpha[i] - self.C) < self.epsilon:
        return tmp <= 1
    # 式(61)
    else:
        return abs(tmp - 1) < self.epsilon

2. 寻找 α2 α 2

imax = (0, 0)# store |E1-E2|, index of alpha2
E1 = self.E[i]
alpha_1_index.remove(i)
# 寻找使|E1 - E2|最大的alpha_2
for j in alpha_1_index:
    E2 = self.E[j]
    if abs(E1 - E2) > imax[0]:
        imax = (abs(E1 - E2), j)

return i, imax[1]

3. 获取 αnew,unc2 α 2 n e w , u n c 并进行剪切获得 αnew2 α 2 n e w , 再获取 αnew1 α 1 n e w

E1, E2 = self.E[i1], self.E[i2]
# eta即式(46)的分母
eta = self._K_(i1, i1) + self._K_(i2, i2) - 2*self._K_(i1, i2) # 7.107
# 式(46)
alpha2_new_unc = self.alpha[i2] + self.Y[i2] * (E1-E2) / eta # 7.106
# 剪切
if self.Y[i1] == self.Y[i2]:
    L = max(0, self.alpha[i2] + self.alpha[i1] - self.C)
    H = min(self.C, self.alpha[i2] + self.alpha[i1])
else:
    L = max(0, self.alpha[i2] - self.alpha[i1])
    H = min(self.C, self.C + self.alpha[i2] - self.alpha[i1])

alpha2_new = H if alpha2_new_unc > H else L if alpha2_new_unc < L else alpha2_new_unc # 7.108
# 式(53)
alpha1_new = self.alpha[i1] + self.Y[i1]*self.Y[i2]*(self.alpha[i2] - alpha2_new)

4.获取新的阈值 bnew b n e w

# 式(57)
b1_new = -E1 - self.Y[i1]*self._K_(i1,i1)*(alpha1_new - self.alpha[i1]) \
         - self.Y[i2]*self._K_(i2,i1)*(alpha2_new - self.alpha[i2]) + self.b
# 式(58)
b2_new = -E2 - self.Y[i1]*self._K_(i1,i2)*(alpha1_new - self.alpha[i1]) \
         - self.Y[i2]*self._K_(i2,i2)*(alpha2_new - self.alpha[i2]) + self.b

# 式(58)-式(59)之间对b的取值讨论
if alpha1_new > 0 and alpha1_new < self.C:
    self.b = b1_new
elif alpha2_new > 0 and alpha2_new < self.C:
    self.b = b2_new
else:
    self.b = (b1_new + b2_new) / 2

5. 更新 E1,E2 E 1 , E 2

# 式(37), 对x_i的预测值
def _g_(self, i):
    K = np.array([self._K_(j, i) for j in range(self.m)])
    return np.dot(self.alpha * self.Y, K) + self.b
# 式(38), 对x_i的预测值与y_i的差值
def _E_(self, i):
    return self._g_(i) - self.Y[i]

# 更新alpha_1, alpha_2对应的E_1, E_2
self.E[i1] = self._E_(i1)
self.E[i2] = self._E_(i2)

以上完整代码在我的github

自问才疏学浅,不当之处请大家指出

参考:

《统计学习方法》
《理解SVM的三重境界》
《机器学习》

点赞