引入拉格朗日乘子法
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
要实现这样的转化,需要满足两个条件:
显然我们以及满足了第一个条件,而要满足第二个条件,即要求:
{ ∂ 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算法
对于对偶问题
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 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}
最后得到 λ 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)
原因是这两个值都等于固定的其他值
因为 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}
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}
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)
其实只需要最后的公式,就足够写出代码了
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)
结果:
SMO算法部分参考https://zhuanlan.zhihu.com/p/29212107
对偶原理部分参考:https://www.bilibili.com/video/BV1aE411o7qd?from=search&seid=7374859475814254502&spm_id_from=333.337.0.0
以上仅为我的理解,新人自学,自知才疏学浅,如有纰漏谬误恳请指出
如有问题,欢迎评论留言,或者联系我的邮箱:
[email protected]