SVM -支持向量機原理詳解與實踐之四
-
SVM原理分析
-
SMO算法分析
-
SMO即Sequential minmal optimization, 是最快的二次規划的優化算法,特使對線性SVM和稀疏數據性能更優。在正式介紹SMO算法之前,首先要了解坐標上升法。
坐標上升法(Coordinate Ascent)簡單點說就是它每次通過更新函數中的一維,通過多次的迭代以達到優化函數的目的。
-
坐標上升法原理講解
為了更加通用的表示算法的求解過程,我們將算法表示成:
|
(3.13-1) |
坐標上升法的算法為:
這個算法中最為關鍵的地方就是內循環對於的求解,意思是固定除了
之外的所有a(從i=1~m),也就是說將
除外的其他變量看成是常數,並且將W看做是關於
的函數,那么直接對
求導優化得到極大值,在上面算法的版本中,內循環優化變量的順序是
但是一個更高級的版本可能選擇其它的順序,例如我可以根據我們的期望來選擇下一個變量來更新,並讓W(a)有最大的增加。
當函數W在內循環中能夠最快的達到最優,則坐標上升是一個有效的算法,下面是一個坐標上升的示意圖:
上圖中的橢圓形線代表我們需要優化問題的二次函數的等高線,變量數為2,起始坐標是(2,2),途中的直線是迭代優化的路徑,可以看到每一步都會相最優值前進一步,而且前進的路線都是平行與相應的坐標軸的,因為每次只優化一個變量。
-
C++算法編程實踐
問題:求解函數的最大值。
解:回顧我們前面分析的求取函數最大值的關鍵是,求解每一個迭代變量的導數,當求解某一變量的導數的時候,其他的變量看做是常數:
VS2013控制台工程參考代碼如下:
// Coordinate ascent.cpp : Defines the entry point for the console application.
//
#include "stdafx.h"
#include <iostream>
using namespace std;
#define f(x1,x2,x3) (-x1*x1-2*x2*x2-3*x3*x3+2*x1*x2+2*x1*x3-4*x2*x3+6)
int _tmain(int argc, _TCHAR* argv[])
{
double x1 = 1;
double x2 = 1;
double x3 = 1;
double f0 = f(x1, x2, x3);
double err = 1.0e-10;
while (true)
{
x1 = x2 + x3; //對x1求導的表達式,每次迭代后更新
x2 = 0.5*x1 - x3; //對x2求導的表達式,每次迭代后更新
x3 = 1.0 / 3 * x1 - 2.0 / 3 * x2; //對x3求導的表達式,每次迭代后更新
double ft = f(x1, x2, x3); //求函數值
if (abs(ft - f0)<err) //判斷f是否收斂
{
break; //收斂即完成求解過程
}
f0 = ft; //更新f0
}
cout << "\nmax{f(x1,x2,x3)}=" << f(x1, x2, x3) << endl;
cout << "取得最大值時的坐標:\n(x1,x2,x3)=(" << x1 << "," << x2 << "," << x3 << ")" << endl;
system("pause");
return 0;
}
運行結果如下:
-
SMO算法詳解
回到我們軟間隔與正則化章節(還有最優間隔分類器),我們的對偶問題,就是通過固定拉格朗日乘子a,得到w和b的最優化表達式(關於a的表達式),所以最后我們只需要確認a,我們就可以最終確定w和b,但是在討論SMO算法之前,我們並沒有真正求解出。這一章我們就會通過介紹SMO算法對對偶問題最后需要解決的問題:
做出一個求解,也就是在參數上求W最大值的問題,注意其中的
就是訓練樣本的輸入,x即為樣本的輸入特征,y即樣本對應的標簽(結果)。
按照前面介紹的坐標上升的思路,我們首先固定除了以外的所有參數,然后在
上求極值。現在下面先固定
以外的所有參數,看看具體的求解步驟:
-
首先由優化問題的約束條件
可知:
即可推出
|
|||
兩邊乘以: |
|
||
|
(3.13.2-1) |
因為,所以
,因此到這一步,
就由其它的
決定,如果我們固定主
,無論如何不能違背優化問題的約束
。
因此如果我們想要更新一些的對象,為了保持滿足約束條件就必須至少快速的更新它們中的兩個,這個就激發出SMO算法,那么SMO算法可以簡單的描述成:
重復大括號中的操作直到收斂{
- 選擇一對
和
來更新下一個(用啟發式的方法,也就是嘗試選取兩個允許我們朝着全局最大方向做最大前進的參數)。
- 固定所有其它的參數
,優化關於
和
的函數W(a)。
}
為了測試該算法的收斂性,我們可以檢查KKT條件:
是否滿足收斂容錯參數,典型值為0.1~0.001之間。
SMO作為一個高效的算法的關鍵原因在於計算更新和
的效率非常高。假設當前我們有一些
滿足(3.10.3-5)的約束,固定
,想要優化關於
和
的函數,用
表示
和
有:
|
由於右邊固定,我們可以直接用一個常數表示,例如用表示:
於是我可以將和
的約束畫出來:
根據約束條件:
可知上圖中表示和
的橫軸和縱軸必須限制在0到C的方框內,並且也要在直線上。並且
的縱軸也必須滿足
,否則就不能滿足約束條件。
下面用表示
,過程是:
其中,因為
,所以有:
所以目標問題W可以表示為:
其中為常數。
實際的問題中W展開后就是一個關於的二次函數
, A、B、C是固定值,這樣通過對W進行求導可得
,然而要保證
滿足
,我們使用
表示求導求出的
, 然而最后的
,需要根據下面的情況得到:
求出以后,我們可以就可以得到
。
-
支持向量機實踐
這里限於篇幅,實踐的內容將在下一篇展開…