上篇博客证明了关于“违反对”拉格朗日乘子选择问题,其实问题还没有结束,因为剩下如何计算G[]和G_bar[]两个数组,以及每次迭代拉格朗日乘子问题并没有解决,只是解决了关于乘子的选择问题。这篇博客就是着重解决上述问题。如果不清楚问题的话可参考(http://blog.csdn.net/zhuyue3938199/article/details/7469868)。
乘子选择问题变成以下优化问题:
优化问题进一步推导可得到如下变形:
![](https://img-my.csdn.net/uploads/201205/27/1338080794_3183.jpg)
可求得取得极值点是
为了推导方便将进行如下定义:
![](https://img-my.csdn.net/uploads/201205/27/1338081003_1878.jpg)
并且由于将(3)式代入:
那么我们就可以得到迭代后的拉格朗日的值了。
接下来对两种情况进行讨论
(1)如果则根据(3)和(6)可得
在LibSVM中,在后面的源码解释可以看到:
(2)如果,则根据(3)和(6)可得
同理,因此可以得到:
在这里基本已经推导出了LibSVM中每一次拉格朗日乘子的迭代过程。但是还有一些细节没有完全解决。如果记得优化问题的对偶问题的限制条件中有,
![](https://img-my.csdn.net/uploads/201205/27/1338082660_1246.jpg)
为了保证这个约束条件的成立,因此还要进行进一步的深入讨论。其实有两种情况的,(1)(2)
我们这里就只讨论
这种情况。
对偶问题中的另一个约束条件是我们每次只取里面两个乘子来进行优化,因此有:
注意:这里的这里的constant’和constant并不一样哦!!!
由上述(12)和(11)可得,![](https://img-my.csdn.net/uploads/201205/27/1338082924_8329.jpg)
在LibSVM的技术文档中,给出了这样一幅图:
![](https://img-my.csdn.net/uploads/201205/27/1338083007_1365.png)
在上图中,的取值只能上述四个区域,而不可能取到右下角和左上角的值。证明如下:
(1)位于左上角,那么有:
明显可以看出(13)与(14)式子是矛盾的,因此不可能取到上述的取值。同理
(2)位于左上角,那么有:
![](https://img-my.csdn.net/uploads/201205/27/1338083154_3951.jpg)
也可以看出(15)与(13)式子是矛盾的。因此不可能位于NA区域。因此
必然位于上述四个区域之一或在四方形的内部。如果位于四方形的内部,则不需进行进一步的讨论,如果是位于四个区域之一,则必须对
的取值进行纠正,保证满足式子(11)。
(1)在局域1有:
满足![](https://img-my.csdn.net/uploads/201205/27/1338084280_8381.jpg)
(2)在局域2有:
满足![](https://img-my.csdn.net/uploads/201205/27/1338084356_2681.jpg)
(3)在区域3有:
满足![](https://img-my.csdn.net/uploads/201205/27/1338084417_2329.jpg)
![](https://img-my.csdn.net/uploads/201205/27/1338084450_2762.jpg)
(4)在区域4有:
满足![](https://img-my.csdn.net/uploads/201205/27/1338084483_9419.jpg)
至此,我们已经讨论了时,拉格朗日乘子迭代的全过程。同样道理,
的情况也是类似的。这里就不再详细讨论了。接下来就看下Solve函数源代码。
if(y[i]!=y[j])//
{
double quad_coef =QD[i]+QD[j]+2*Q_i[j];//这里计算上述的(4)中的
if (quad_coef<= 0)
quad_coef = TAU;//如果,则用很小的正数代替
double delta = (-G[i]-G[j])/quad_coef;//计算delta
double diff = alpha[i] -alpha[j];//计算
alpha[i] +=delta;//迭代计算
alpha[j] +=delta; //迭代计算
if(diff > 0)
{
if(alpha[j] < 0)//在区域3,按(18)进行更新
{
alpha[j] = 0;
alpha[i] =diff;
}
}
else
{
if(alpha[i] < 0)//在区域4,按(19)进行更新
{
alpha[i] = 0;
alpha[j] = -diff;
}
}
if(diff >C_i - C_j)
{
if(alpha[i] >C_i)//在区域1,按(16)进行更新
{
alpha[i] =C_i;
alpha[j] =C_i - diff;
}
}
else
{
if(alpha[j] >C_j)//在区域2,按(17)进行更新。
{
alpha[j] =C_j;
alpha[i] =C_j + diff;
}
}
}
else
{
double quad_coef =QD[i]+QD[j]-2*Q_i[j];
if (quad_coef<= 0)
quad_coef = TAU;
double delta = (G[i]-G[j])/quad_coef;
double sum = alpha[i] +alpha[j];
alpha[i] -=delta;
alpha[j] +=delta;
if(sum >C_i)
{
if(alpha[i] >C_i)
{
alpha[i] =C_i;
alpha[j] =sum - C_i;
}
}
else
{
if(alpha[j] < 0)
{
alpha[j] = 0;
alpha[i] =sum;
}
}
if(sum >C_j)
{
if(alpha[j] >C_j)
{
alpha[j] =C_j;
alpha[i] =sum - C_j;
}
}
else
{
if(alpha[i] < 0)
{
alpha[i] = 0;
alpha[j] =sum;
}
}
}