转载请注明出处: 嚼烂SVM-SMO算法并用python进行实现
本文面向的读者为掌握SVM基础前置知识如读过《统计学习方法》,并希望对SMO细节有更深入了解的人羣。因为笔者想要实现一个简易的SVM,为了搞懂这部分费了不少工夫,所以写下这一篇嚼过的文章,目的是让读者跟着顺序阅读一定能弄懂。自己的行文习惯是简单的地方不能说太复杂,复杂的地方一定会说清楚
一, 推导至SMO要解决的SVM对偶形式
对于含soft margin的支持向量机, 其primitive problem:
minw,b,ξ12∥w∥2+C∑i=1Nξis.t.yi(w⋅xi+b)≥1−ξi,i=1,2,⋯,Nξi≥0,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
引入拉格朗日乘子 αi≥0,μi≥0,i=1,2,⋯,N α i ≥ 0 , μ i ≥ 0 , i = 1 , 2 , ⋯ , N 构建Lagrange Function:
L(w,b,ξ,α,μ)=12∥w∥2+C∑i=1Nξi+∑i=1Nαi(−yi(w⋅xi+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,ξ,α,μ)=w−∑i=1Nαiyixi=0∇bL(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αiyixi∑i=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,ξ,α,μ)=−12∑i=1N∑i=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=1N∑i=1NαiαjyiyjK(xi,xj)+∑i=1Nαi∑i=1Nαiyi=0C−αi−μi=0αi≥0μi≥0(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≤αi≤C(18) (18) 0 ≤ α i ≤ C
5,最终形式:一个凸二次规划的对偶问题
minαs.t.12∑i=1N∑j=1NαiαjyiyjK(xi,xj)−∑i=1Nαi∑i=1Nαiyi=00≤αi≤C,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=w∗−∑i=1Nα∗iyixi=0=−∑i=1Nα∗iyi=0=C−α∗i−μ∗i=0≥0w∗⋅x∗+b∗)≤0(w∗⋅x∗+b∗))=0≥0≤0=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+α1y1∑i=3NαiyiK1i+α2y2∑i=3NαiyiK2i−α1−α2s.t.α1y1+α2y2=−∑i=3Nyiαi=ς0≤αi≤C,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+α2y2∑i=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+ςy2K12−2K12α2−y2∑i=3NαiyiK1i+y2∑i=3NαiyiK2i+y1y2−1=(K11+K22−2K12)α2+y2(−ςK11+ςK12−∑i=3NαiyiK1i+∑i=3NαiyiK2i+y1−y2)(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αjyjKij−b,i=1,2=Ei+yi−∑j=12αjyjKij−b,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+K22−2K12)αnew,unc2=y2(ςK11−ςK12+∑i=3NαiyiK1i−∑i=3NαiyiK2i−y1+y2)=y2(∑i=12αiyiK11−∑i=12αiyiK12+v1−v2−y1+y2)=y2(∑i=12αiyiK11−∑i=12αiyiK12+E1+y1−∑i=12αiyiK1i−b−E2−y2+∑i=12αiyiK2i+b−y1+y2)=y2(E1−E2+α2y2K11−2α2y2K12+α2y2K22)=(K11−2K12+K22)α2+y2(E1−E2)(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(E1−E2)K11−2K12+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≤α2≤C≤k−α2≤C⇒{0≤α2≤Ck−C≤α2≤k⇒{0≤α2≤Cαold1+αold2−C≤α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+αold2−C)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 ) - y1≠y2 y 1 ≠ y 2
根据式(32),设 α1−α2=k α 1 − α 2 = k
根据式(33),可得:
{00≤α2≤C≤α2+k≤C⇒{0−k≤α2≤C≤α2≤C−k⇒{0αold2−αold1≤α2≤C≤α2≤C+α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,unc2≤Cα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=yi−∑j=1NαjyjKij(54) (54) b = y i − ∑ j = 1 N α j y j K i j
如果
α1 α 1 满足此条件,则
bnew1=y1−∑i=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+bold−y1(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αjyjKij−yi(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−α∗i−u∗i=0 C − α i ∗ − u i ∗ = 0 可得 u∗i=C>0 u i ∗ = C > 0
(2), 根据 u∗iξ∗i=0 u i ∗ ξ i ∗ = 0 可得 ξ∗i=0 ξ i ∗ = 0
(3), 根据 yi(w∗xi+b∗)≥1−ξ∗i y i ( w ∗ x i + b ∗ ) ≥ 1 − ξ i ∗ 可得 yi(w∗xi+b∗)≥1 y i ( w ∗ x i + b ∗ ) ≥ 1
(4), 综上, αi=0⇔yig(xi)≥1(60) (60) α i = 0 ⇔ y i g ( x i ) ≥ 10<αi<C 0 < α i < C
(1), 根据 C−α∗i−u∗i=0 C − α i ∗ − u i ∗ = 0 可得 u∗i>0 u i ∗ > 0
(2), 根据 u∗iξ∗i=0 u i ∗ ξ i ∗ = 0 可得 ξ∗i=0 ξ i ∗ = 0
(3), 根据 α∗i(yi(w∗xi+b∗)−1+ξ∗)=0 α i ∗ ( y i ( w ∗ x i + b ∗ ) − 1 + ξ ∗ ) = 0 及上面一条可得 yi(w∗xi+b∗)−1=0 y i ( w ∗ x i + b ∗ ) − 1 = 0
(4), 综上, 0<αi<C⇔yig(xi)=1(61) (61) 0 < α i < C ⇔ y i g ( x i ) = 1αi=C α i = C
(1). 根据 C−α∗i−u∗i=0 C − α i ∗ − u i ∗ = 0 可得 u∗i=0 u i ∗ = 0
(2). 根据 u∗i=0 u i ∗ = 0 及 u∗iξ∗i=0 u i ∗ ξ i ∗ = 0 , ξ∗i≥0 ξ i ∗ ≥ 0 可得 ξ∗i≥0 ξ i ∗ ≥ 0
(3). 根据 α∗i(yi(w∗xi+b∗)−1+ξ∗i)=0 α i ∗ ( y i ( w ∗ x i + b ∗ ) − 1 + ξ i ∗ ) = 0 及 αi=C>0 α i = C > 0 可得
yi(w∗xi+b∗)−1+ξ∗i=0 y i ( w ∗ x i + b ∗ ) − 1 + ξ i ∗ = 0
(4). 根据推论(2)及推论(3)可得: yi(w∗xi+b∗)≤1 y i ( w ∗ x i + b ∗ ) ≤ 1
(5). 综上, αi=C⇔yig(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 与 E1−E2 E 1 − E 2 呈线性关系,所以对 α2 α 2 的选取策略:
遍历找到使 |E1−E2| | 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的三重境界》
《机器学习》