標籤:arch 資料結構 支援 ref bubuko 核心 images hive 過程
一. SMO演算法基礎
支援向量就是離分隔超平面最近的那些點。分隔超平面是將資料集分開來的決策邊界。
支援向量機將向量映射到一個更高維的空間裡,在這個空間裡建立有一個最大間隔超平面。在分開資料的超平面的兩邊建有兩個互相平行的超平面。建立方向合適的分隔超平面使兩個與之平行的超平面間的距離最大化。其假定為,平行超平面間的距離或差距越大,分類器的總誤差越小。
我們希望找到離分隔超平面最近的點,確保他們離分隔面的距離儘可能遠,誤差儘可能小。
與logistics不同的是支援向量機採用的類別標籤是-1和+1,因為-1和+1隻相差一個符號,方便數學上的處理。
分隔超平面的形式可以寫成,一個點到到分隔超平面的的法線或垂線的長度為成,我們的目標是找出間隔最大化時的w和b,間隔通過來計算,即目標式可寫作:
其中||w||為二階範數,也就是各項目平方和的平方根:
但對乘積最佳化是特別麻煩的,所以我們可以將超平面寫成資料點的形式:
約束條件為:
可得w與b:
但是大部分情況下資料都不會是100%線性可分的,因此我們加入鬆弛變數,約束條件變為:
其中求解過程是比較複雜的,如果像我一樣接觸這類電腦語言不久,可以不用太糾結於演算法的計算過程,清楚原理也可以讀懂程式。接下來就是完整SMO演算法程式實現。
二.程式實現
先用testSet.txt中的資料簡單瞭解一下支援向量機演算法。
部分testSet.txt中的資料
對於testSet.txt資料集,先輔助函數loadDataSet()函數開啟檔案並對其進行逐行解析,從而得到每行的類標籤和整個資料矩陣。selectJrand()中參數i是第一個alpha的下標,m是所有alpha的數目。clipAlpha()用於調整大於H或小於L的alpha值。
然後需要構建一個僅包含init方法的optStructure類來實現其成員變數的填充。calcEK()計算E值並返回。selectJ()用於選擇內迴圈的alpha值。cpdateEK()計算在對alpha值進行最佳化時會用到的誤差值。
再匯入innerL()函數,使用它自己的資料結構在參數os中傳遞。smoP()函數建立一個資料結構來容納所有的資料,然後對控制函數退出的變數進行初始化。CalcWs()中的for迴圈遍曆資料集中的所有資料,捨棄支援向量之外的其他資料點。
最後,利用matplotlib畫出圖形。
三.手寫辨識問題
資料:存放在trainingDigits和testDigits兩個檔案夾中的手寫辨識資料。
SMO演算法程式與前面相同,接下來用img2vector()函數將32x32的二進位映像轉換為1x1024向量及loadImages()函數載入圖片。
四.測試結果與方法
用testDigits()函數測試支援向量個數、訓練集錯誤率及測試集錯誤率。
經過4次迭代以後得到:
五.核函數
核函數是SMV的核心演算法,對於原本線性不可分的樣本,可以通過將原始輸入空間映射到更高維度特徵空間這一操作使其在新的核空間內變為線性可分。僅需要調整核函數就可以將特徵進行低維到高維的變換,在低維上進行計算,實質結果表現在高維上。
此圖來自74418365
比較流行的一個核函數是徑向基核函數:
由於本人對核函數還不是很懂,這裡使用的資料集比較簡單,沒有使用核函數,就不再具體介紹了,想深入瞭解具體演算法實現過程可參考http://www.cnblogs.com/jerrylead/archive/2011/03/18/1988406.html
六.總結
支援向量機具有良好的學習能力,結果有很好的推廣性。且完整演算法在很大程度上提高了最佳化的速度。但對參數調節和核函數的選擇敏感,若要處理二分類以外的問題需要對原始分離器加以修改。適用於數值型和標稱型資料。
機器學習-支援向量機演算法實現與執行個體程式