此文轉自兩篇博文 有修改
序列最小優化算法(英語:Sequential minimal optimization, SMO)是一種用於解決支持向量機訓練過程中所產生優化問題的算法。SMO由微軟研究院的約翰·普萊特(John Platt)發明於1998年,目前被廣泛使用於SVM的訓練過程中,並在通行的SVM庫libsvm中得到實現。
1998年,SMO算法發表在SVM研究領域內引起了轟動,因為先前可用的SVM訓練方法必須使用復雜的方法,並需要昂貴的第三方二次規划工具。而SMO算法較好地避免了這一問題。
前面最后留下來一個對偶函數最后的優化問題,原式為:
-----------------這個是由拉格朗日方法 然后求偏導 列式帶入核函數得到的目標函數
SMO就是要解這個凸二次規划問題,這里的C是個很重要的參數,它從本質上說是用來折中經驗風險和置信風險的,C越大,置信風險越大,經驗風險越小;並且所有的因子都被限制在了以C為邊長的大盒子里。
算法詳述
(1)、 KKT條件
SMO是以C-SVC的KKT條件為基礎進行后續操作的,這個KKT條件是:
其中
上述條件其實就是KT互補條件,SVM學習——軟間隔優化一文,有如下結論:
從上面式子可以得到的信息是:當時,松弛變量
,此時有:
,對應樣本點就是誤分點;當
時,松弛變量
為零,此時有
,對應樣本點就是內部點,即分類正確而又遠離最大間隔分類超平面的那些樣本點;而
時,松弛變量
為零,有
,對應樣本點就是支持向量。
(2)、凸優化問題停止條件
對於凸優化問題,在實現時總需要適當的停止條件來結束優化過程,停止條件可以是:
1、監視目標函數的增長率,在它低於某個容忍值時停止訓練,這個條件是最直白和簡單的,但是效果不好;
2、監視原問題的KKT條件,對於凸優化來說它們是收斂的充要條件,但是由於KKT條件本身是比較苛刻的,所以也需要設定一個容忍值,即所有樣本在容忍值范圍內滿足KKT條件則認為訓練可以結束;
3、監視可行間隙,它是原始目標函數值和對偶目標函數值的間隙,對於凸二次優化來說這個間隙是零,以一階范數軟間隔為例:
原始目標函數與對偶目標函數
的差為:
定義比率:
,可以利用這個比率達到某個容忍值作為停止條件。
(3)、SMO思想
沿襲分解思想,固定“Chunking工作集”的大小為2,每次迭代只優化兩個點的最小子集且可直接獲得解析解,算法流程:

(4)、僅含兩個Langrange乘子解析解
為了描述方便定義如下符號:
於是目標函數就變成了:
注意第一個約束條件:,可以將
看作常數,有
(
為常數,我們不關心它的值),等式兩邊同時乘以
,得到
(
為常數,其值為
,我們不關心它,
)。將
用上式替換則得到一個只含有變量
的求極值問題:
這下問題就簡單了,對求偏導數得到:
將、
帶入上式有:
帶入、
,用
,表示誤差項(可以想象,即使分類正確,
的值也可能很大)、
(
是原始空間向特征空間的映射),這里
可以看成是一個度量兩個樣本相似性的距離,換句話說,一旦選擇核函數則意味着你已經定義了輸入空間中元素的相似性。
最后得到迭代式:
注意第二個約束條件——那個強大的盒子:,這意味着
也必須落入這個盒子中,綜合考慮兩個約束條件,下圖更直觀:
和
異號的情形
和
同號的情形
可以看到兩個乘子既要位於邊長為C的盒子里又要在相應直線上,於是對於
的界來說,有如下情況:
整理得下式:
又因為,
,消去
后得到:
(5).綜上可總結出SMO的算法框架
SMO算法是一個迭代優化算法。在每一個迭代步驟中,算法首先選取兩個待更新的向量,此后分別計算它們的誤差項,並根據上述結果計算出和
。最后再根據SVM的定義計算出偏移量
。對於誤差項而言,可以根據
、
和b的增量進行調整,而無需每次重新計算。具體的算法如下:
1. 隨機數初始化向量權重,並計算偏移b。(這一步初始化向量權重只要使
符合上述的約束條件即可,原博文的程序就是range函數)
2.初始化誤差項,其中
3.選取兩個向量作為需要調整的點(例如第一次下標為1,2兩點,第二次下標3,4...........),然后
令其中
(
是原始空間向特征空間的映射),
4.if >H 令
=H if
<L 令
=L (L,H前面已給出)
5.令
6.利用更新的和
修改
和b的值
7.如果達到終止條件,則算法停止,否則轉向3
算法補充說明:
優化向量選擇方法
可以采用啟發式的方法選擇每次迭代中需要優化的向量。第一個向量可以選取不滿足支持向量機KKT條件的向量,亦即不滿足
-
-
- 即:
-
其中
-
的向量。而第二個向量可以選擇使得最大的向量。
終止條件
SMO算法的終止條件可以為KKT條件對所有向量均滿足,或者目標函數增長率小於某個閾值,即
-
-
(根據前面的凸優化問題停止條件所說,此效果可能不佳,可選擇其他方法,見(2))
-
---------------------------------以下內容是有關可行間隙方法,乘子優化,SMO加速問題,是深化的內容------------------------------------------------
(6)、啟發式的選擇方法
根據選擇的停止條件可以確定怎么樣選擇點能對算法收斂貢獻最大,例如使用監視可行間隙的方法,一個最直白的選擇就是首先優化那些最違反KKT條件的點,所謂違反KKT條件是指:
其中KKT條件
由前面的停止條件3可知,對可行間隙貢獻最大的點是那些
其中,
取值大的點,這些點導致可行間隙變大,因此應該首先優化它們(原因見原博文:http://www.cnblogs.com/vivounicorn/archive/2011/06/01/2067496.html)
SMO的啟發式選擇有兩個策略:
啟發式選擇1:
最外層循環,首先,在所有樣本中選擇違反KKT條件的一個乘子作為最外層循環,用“啟發式選擇2”選擇另外一個乘子並進行這兩個乘子的優化,接着,從所有非邊界樣本中選擇違反KKT條件的一個乘子作為最外層循環,用“啟發式選擇2”選擇另外一個乘子並進行這兩個乘子的優化(之所以選擇非邊界樣本是為了提高找到違反KKT條件的點的機會),最后,如果上述非邊界樣本中沒有違反KKT條件的樣本,則再從整個樣本中去找,直到所有樣本中沒有需要改變的乘子或者滿足其它停止條件為止。
啟發式選擇2:
內層循環的選擇標准可以從下式看出:
要加快第二個乘子的迭代速度,就要使最大,而在
上沒什么文章可做,於是只能使
最大。
確定第二個乘子方法:
1、首先在非界乘子中尋找使得最大的樣本;
2、如果1中沒找到則從隨機位置查找非界乘子樣本;
3、如果2中也沒找到,則從隨機位置查找整個樣本(包含界上和非界乘子)。
(7)、關於兩乘子優化的說明
由式子
可知:
於是對於這個單變量二次函數而言,如果其二階導數,則二次函數開口向下,可以用上述迭代的方法更新乘子,如果
,則目標函數只能在邊界上取得極值(此時二次函數開口向上),換句話說,SMO要能處理
取任何值的情況,於是在
時有以下式子:
1、時:
2、時:
3、
分別將乘子帶入得到兩種情況下的目標函數值: 和
。顯然,哪種情況下目標函數值最大,則乘子就往哪兒移動,如果目標函數的差在某個指定精度范圍內,說明優化沒有進展。
另外發現,每一步迭代都需要計算輸出進而得到
,於是還要更新閾值
,使得新的乘子
、
滿足KKT條件,考慮
、
至少有一個在界內,則需要滿足
,於是
的迭代可以這樣得到:
1、設在界內,則:
又因為:
於是有:
等式兩邊同乘后移項得:
;
2、設在界內,則:
;
3、設、
都在界內,則:情況1和情況2的
值相等,任取一個;
4、設、
都不在界內,則:
取值為情況1和情況2之間的任意值。
(8)、提高SMO的速度
從實現上來說,對於標准的SMO能提高速度的地方有:
1、能用緩存的地方盡量用,例如,緩存核矩陣,減少重復計算,但是增加了空間復雜度;
2、如果SVM的核為線性核時候,可直接更新,畢竟每次計算
的代價較高,於是可以利用舊的乘子信息來更新
,具體如下:
,應用到這個性質的例子可以參見SVM學習——Coordinate Desent Method。
3、關注可以並行的點,用並行方法來改進,例如可以使用MPI,將樣本分為若干份,在查找最大的乘子時可以現在各個節點先找到局部最大點,然后再從中找到全局最大點;又如停止條件是監視對偶間隙,那么可以考慮在每個節點上計算出局部可行間隙,最后在master節點上將局部可行間隙累加得到全局可行間隙。