【機器學習】支持向量機

點擊上方藍色字體,關注AI小白入門

跟着博主的腳步,每天進步一點點

本文介紹了支持向量機模型,首先介紹了硬間隔分類思想(最大化最小間隔),即在感知機的基礎上提出了線性可分情況下最大化所有樣本到超平面距離中的最小值。然後,在線性不可分的情況下,提出一種軟間隔線性可分方式,定義了一種hinge損失,通過拉格朗日函數和對偶函數求解參數。其次,介紹線性模型中的一種強大操作—核函數,核函數不僅提供了支持向量機的非線性表示能力, 使其在高維空間尋找超平面,同時天然的適配於支持向量機。再次,介紹SMO優化方法加速求解支持向量機,SMO建立於座標梯度上升算法之上,其思想與EM一致。最後,介紹支持向量機在迴歸問題上的應用方式,對比了幾種常用損失的區別。

作者 | 文傑

編輯 | yuquanle

支持向量機

在線性模型中,Fisher線性判別和線性感知機可以說是以上所有模型的分類依據,前者是映射到一維執其兩端進行分類,後者是在高維空間找一個線性超平面將兩類分開(兩類可擴展到多類)。支持向量機屬於後者,但主要有以下幾點改進:

1)提出硬間隔線性可分,在感知機的基礎上提出了線性可分假設(無損失),最大化最小間隔。

2)提出軟間隔線性可分,得到了hinge損失代替感知機的線性損失(後面補充一個線性模型損失對比圖)。

3)結合核函數將數據映射到高維空間,使得模型具有非線性能力。

4)具有感知機的一切解釋性,同時目標函數的對偶形式是凸二次規劃問題。

A、硬間隔(最大化最小間隔分類器)

線性感知機中由於沒有線性可分假設,所以其目標函數定義爲最小化錯分樣本的損失,而硬間隔SVM則提出了一個線性可分假設,即樣本在高維空間中線性可分,那麼使得兩類分開的超平面一定有無限個。硬間隔SVM則在這些超平面中找出最優的(即所有樣本到超平面距離加和最小化),所以有如下目標函數:


其中


爲點到平面的幾何間隔,去掉係數爲函數間隔。最大化最小間隔分類器則採用等價形式—使得最難分的樣本離超平面距離儘可能的大—最大化最小間隔分類器:

   


有:


到此,上式爲硬間隔分類器的原問題最終形式。上述問題可使用拉格朗日乘子法和對偶問題進行求解。

拉格朗日函數:


其中由Fritz John條件得出,爲互補鬆弛條件,互補鬆弛條件與支持向量有密切關係。由上述約束條件有:


將上式帶入到拉格朗日函數,得到關於表示的函數:


最大化關於的函數即爲原問題的對偶問題,如下:


解出上式目標函數後,有:


其中可以看出,w和b有樣本點與內積確定。

但是回過頭來想,線性可分假設是不現實,所以SVM在硬間隔線性可分的基礎上提出軟間隔線性可分。即允許線性不可分,但是需要進行一定的懲罰。如下圖爲軟間隔線性可分,其中在支持向量裏面的點和錯分的樣本爲線性不可分的點,虛線上的點爲支持向量。

B、軟間隔SVM

線性不可分意味着某些樣本不滿足函數間隔大於的約束條件,爲了解決這個問題,可以對每個樣本引入一個鬆弛變量,使得函數間隔加上鬆弛變量大於等於1,這樣約束條件變爲:

 

同時對於線性不可分的樣本進行懲罰,因此目標函數變爲:

 

因此最終的線性不可分SVM的目標函數如下:

   

拉格朗日函數:

        

由上述約束條件有:

    

將上式帶入到拉格朗日函數,得到目標函數關於表示的函數,同硬間隔的對偶函數一致:

 

最大化關於的函數即爲原問題的對偶問題,而對偶問題爲原問題提供一個下界,即原問題的對偶問題如下:

       

解出上式目標函數後,有:

  

可以看出,w和b由樣本點與內積確定,當表示 第i個樣本點滿足條件,該點不在支持向量內部,w與該點無關,支持向量機的參數只與支持向量以內的點有關。

對比硬間隔和軟間隔SVM發現兩者的對偶問題非常相似,唯一不同的在於,也就是說在約束條件上不能讓值太大。而不爲的意義就是該點線性不可分—在支持向量以內,不能讓太大的意義就是儘可能的不要讓樣本在支持向量太裏面。這也就是懲罰項引入後的結果。

下面根據的取值來分析樣本點的一個位置,以及樣本點對SVM參數的影響:

,則,表示樣本點在支持向量上或者以外的,以外的點對參數無價值。

,則,表示樣本點在支持向量上。

,則,如果,表示樣本在支持向量內部,但分類正確。

,則,如果,表示樣本在超平面上。

,則,如果,表示樣本分類錯誤。

C、核函數

核函數的應用主要是解決線性不可分問題,通過選擇合適的核函數將樣本從低維線性不可分映射到高維之後容易線性可分,本質上是一次空間上的非線性變換(特徵映射),核函數可以嫁接到很多線性模型上,使其具有非線性能力,只是核函數的選擇是一件難定的事。

而SVM與核函數有着天然的契合度,因爲在SVM的對偶問題中,需要計算樣本之間的內積,而核函數的引入則可以使得內積操作直接在覈函數中隱式完成。

 

在上式中有內積操作,當我們使用核技巧時,往往需要定義一個核函數進行特徵空間變換,然後在新的特徵空間中進行內積操作,這使得計算過程分兩步完成。如果我們隱式的定義核函數如下:

  

直接定義作爲核函數,而不管實際的核函數是如何將x映射到空間,然後在新的特徵空間計算內積。這樣,我們就隱式完成了內積操作,將核函數與內積操作一步完成爲。當然,核函數必須滿足核函數的性質。

一般常採用的核函數有:

線性核  

多項式核 

高斯核

拉普拉斯核

sigmoid核

然而核技巧中,最盲目的是如何選擇合適核函數,或者多核。

這裏需要解釋的是,SVM對核函數有一個自身的要求,核的大小一定是。因爲SVM在做內積時是所有點彼此做內積,所以複雜度是。這也是SVM難以適應大規模數據的場景,SVM的複雜度體現在內積上,帶核的SVM的複雜度體現在覈函數的計算上。而這不是核函數的特點,核函數中核的大小是自定義的。

D、SMO優化算法

  

SVM優化問題是一個典型的帶約束凸二次規劃,傳統的梯度方法不能直接應用於帶約束優化問題,下面先介紹一種座標上升優化算法,算法的思想是對於多個參數的優化求解問題,可以每次只考慮一個變量,而固定其他所有變量,對一個變量進行目標優化,內循環每一個變量進行優化,外循環直到迭代到收斂。其收斂性類似於EM算法。

因爲內層循環每次只改變一個變量,所以座標上升算法的搜索路徑與座標軸平行。

然而,如果每次只改變一個變量來優化SVM,那麼必然不滿足約束。所以SMO算法在座標上升算法基礎上又以下兩點改進:

1)爲了滿足約束,每次迭代優化選擇兩個變量,其中一個主動變量,另一個被動變量。

2)在選擇兩個變量進行優化時,採用啓發式搜索策略,主動變量選擇違反KKT條件最嚴重的一個變量,在選定後,被動變量選擇變化範圍最大的,在優化時使用上下剪輯來使得滿足約束。

現在來看SMO算法,固定m-2個變量不變,將目標函數轉化爲關於的函數:

   

其中

爲了求解兩個變量的二次規劃問題,首先我們分析約束條件,可以看出的可行域是盒子內的一條對角線上,其中盒子由不等式確定,對角線由等式確定,而且由於的不確定性導致存在兩種情況:

至於對角線的位置取決於當前的值。由於優化過程中,我們首先優化的是,而後由等式約束確定,所以我們分析的變化範圍:

時: 

時: 

其中L是爲了保證的變化不會讓,H是爲了保證的變化不會讓

同樣,由於我們首先優化的是,所以我們採用來表示

,代入有(省略了推導步驟):

 

求導後得到:

 

有:

 

所以:

 

回到上下剪輯,最終的更新值爲:

再由得:

 

最後更新b,由KKT條件當時,有

時:

 

同樣,當時:來確定。

如果兩者同時滿足條件時,那麼兩者確定的是一致的,如果等式取到的話,說明點在支持向量上或者以內,此時取兩者之間。

下面來看SMO的啓發式搜索策略:

1)主動變量選擇違反KKT條件最嚴重的點,即優先判斷支持向量上的點是否滿足KKT條件,其次檢驗整個訓練樣本是否滿足KKT條件

由上面對與樣本點位置的分析可得到如下關係:

 

由上面關係,可以知道哪些點在支持向量上,哪些點在支持向量外,哪些點在支持向量內,優先選擇支持向量上的點來判斷是否違反KKT條件,因爲這些點是違反KKT條件最嚴重的點,也是對超平面最有價值的點。

2)被動變量選擇在給定主動變量後,被動變量隨之變化範圍最大的點,由於前面導出所以被動變量選擇依賴於 的大小,選擇最大的,加速計算速度。

3)值得注意的是,每次迭代更新之後,需要更新

支持向量機迴歸:

支持向量機迴歸利用的就是Hinge損失來定義目標函數,同樣是線性模型,由Hinge損失定義如下目標函數:

 

其中:

 

可以看出支持向量機迴歸其實就是借用Hinge損失,而其理論解釋值得思考。

損失函數加正則項的一般理解:

機器學習模型中,絕大多數的模型可以理解損失函數加正則項的形式,本文從線性到非線模型中提到的所有模型都可以理解爲損失函數加正則項:

 

其中正則項主要包括 0範數 1範數 2範數,損失函數主要包括以下:

平方損失:   , 線性迴歸;

線性損失:  , 線性感知機;

對數損失:  , Logistic迴歸, softmax迴歸;

Hinge損失:,支持向量機;

指數損失:,Adaboost。

紅:0-1損失,藍:線性損失,綠:Hinge損失,紫虛:對數損失,青虛:指數損失

如何選擇合適的損失函數加正則項是模型選擇的一個依據,損失函數的選擇依賴於數據的分佈,而且不同的模型都有各自的特點,在選擇模型時很難說那個模型優於其他模型,需要綜合各方面因素選擇。

F、拉格讓日乘子法與對偶問題補充

拉格朗日乘子法通過引入鬆弛變量得到目標函數局部最優解的必要條件:

拉格朗日乘子法的一般形式:

 

引入鬆弛變量也稱拉格朗日乘子,朗格朗日函數如下:

 

如果是目標函數的局部最優解,那麼的一階必要條件如下:

 

其中爲互補鬆弛條件,梯度爲0條件由Frizt John條件得到。

一般來講,到拉格朗日乘子法之後我們還不能解出目標函數的局部最優解,因爲目標函數還是一個引入鬆弛變量的帶約束優化問題。不過我們可以通過分析拉格朗日函數的局部最優解來得到其對偶問題。

在給定時,對求極大值時,當不滿足所有必要條件時,那麼必然導致無最大值,當且僅當滿足所有必要條件時有極大值,且極大值爲

滿足必要條件,否則 

所以,所有約束條件的等價條件是存在極大值,所以原問題就變成了一個極小極大問題:

 

定義一個對偶問題,即定義一個用變量來表示的目標函數:

 

最大化即爲原問題的對偶問題,下面證明對偶問題爲原問題提供下界:

 

又因爲:

 

所以對偶問題爲原問題提供下界。

代碼實戰

A、支持向量機

int SVM() 
 
{
 ///加載數據文件保存到對象dtm的矩陣元素中
   ///通過矩陣對象中的load函數初始化樣本的特徵和類別矩陣x,y
 //char file[20]="data\\svm.txt";
 Matrix x;
 //x.LoadData(file);
   char file[20]="data\\svm.txt";
 x.LoadData(file);
 //x = x.transposeMatrix();
   Matrix y;
 y=x.getOneCol(x.col-1);
 x.deleteOneCol(x.col-1);
 for(int i=x.row-1;i>100;i--)
 //x.deleteOneCol(x.col-1);
 x.deleteOneRow(i);
 cout<<x.row<<"*"<<x.col<<endl;
 cout<<y.row<<"*"<<y.col<<endl;
 ///調用SMO函數求解SVM模型
 cout<<"SVM"<<endl;
 SMOP smop;
 kTup ktup;//核函數的定義,其中type元素爲0表示不適用核函數,非0分別對應不同的核函數
 ktup.type=1;
 ktup.arg=1.0;
 smop.smoP(x,y,0.6,0.001,40,ktup);//
 return 0;
 }
/** 
   SMO算法的入口函數,其主要功能是初始化SMO所有的參數到結構體OS
 確定迭代結束標誌,並在所有樣本和支持向量上循環的選擇合適alpha1,調用inner確定alpha1,
 外層循環每一次是迭代優化一對alpha,內層循環纔是正真實現迭代優化一對alpha
 最後,對smo算法的實現進行檢查,通過alpha求解出w,b,並在訓練樣本上比較其預測值與實際值的差異。
 該辦法只能檢查SMO算法實現的正確性,不能檢查SVM的性能。
 */
 
   int smoP(Matrix x,Matrix y,double C,double soft,int maxIter,kTup ktup) 
 
{
 int iter=0;
 int i;
 initOs(x,y,C,soft,ktup);///初始化OS結構體,OS結構體中定義了SMOP算法需要的大部分參數
 bool entireSet=true;//標誌用於判斷當前迭代是針對所有alpha,還是針對0-C之間的部分alpha,這裏其實第一個alpha的啓發式選擇,即選擇落在支持向量上的點
 int alphaPairsChanged=0;//該參數判斷在確定第一個參數之後,是否能選擇出符合要求的第二alpha,返回值爲1表示能,0爲不能
 for(iter=0; iter<maxIter&&(alphaPairsChanged>0||entireSet); iter++)
 {
 //循環結束標誌爲迭代次數已到預設值,或者是不能再繼續優化(對於所有的支持向量上的點都找不到第二個alpha對第一個alpha進行優化後,重新再遍歷所有的點尋找可優化的參數對)
 //還是找不到則再次遍歷支持向量上的點,這次必然也是找不到,才結束迭代
 alphaPairsChanged=0;
 if(entireSet)
 {
 for(i=0; i<os.m; i++)
 {
 alphaPairsChanged+=innerL(i);
 cout<<"iter="<<iter<<" i="<<i<<" alphachanged="<<alphaPairsChanged<<" entireSet="<<entireSet<<endl;
 }
 iter++;
 }
 else 
 {
 for(i=0; i<os.m; i++)
 {
 if(os.alphas.data[i][0]>0&&os.alphas.data[i][0]<os.C)//只選擇支持向量上的點
 continue;
 alphaPairsChanged+=innerL(i);
 cout<<"iter="<<iter<<" i="<<i<<" alphachanged="<<alphaPairsChanged<<alphaPairsChanged<<" entireSet="<<entireSet<<endl;
 }
 iter++;
 }
 if(entireSet)
 entireSet=false;
 else if(alphaPairsChanged==0)
 entireSet=true;
 }
 ///對SMO算法實現的正確性進行驗證,輸出預測值與實際值的差別,全爲0表示在訓練樣本上預測全對
 Matrix ay(os.x.row,1,0,"ss");
 for(i=0; i<os.m; i++)
 {
 ay.data[i][0]=os.alphas.data[i][0]*os.y.data[i][0];
 }
   Matrix xT = x.transposeMatrix();
   Matrix w = w.multsMatrix(xT,ay);
   Matrix label = label.multsMatrix(os.x,w);
 cout<<os.b<<" ";
 for(i=0; i<os.x.col; i++)
 {
 cout<<w.data[i][0]<<" ";
 }
 cout<<endl;
 cout<<"-----------"<<endl;
 ///驗證訓練樣本數據,驗證SVM實現的正確性
 for(i=0; i<os.m; i++)
 {
 if((label.data[i][0]+os.b)>0)
 cout<<1-os.y.data[i][0]<<" ";
 else 
 cout<<0-os.y.data[i][0]<<" ";
 }
 return 0;
 }

詳細代碼:

https://github.com/myazi/myLearn/blob/master/include/SVM.h

The End

方便交流學習,備註:暱稱-學校(公司)-方向,進入DL&NLP交流羣。

方向有很多:機器學習、深度學習,python,情感分析、意見挖掘、句法分析、機器翻譯、人機對話、知識圖譜、語音識別等

記得備註呦

往期精彩回顧

新年送福氣|您有一份NLP大禮包待領取

自然語言處理中注意力機制綜述

達觀杯文本智能處理挑戰賽冠軍解決方案

長按二維碼關注
AI小白入門

ID:StudyForAI

學習AI學習ai(愛)

期待與您的相遇~

你點的每個贊,我都認真當成了喜歡

發佈了220 篇原創文章 · 獲贊 115 · 訪問量 47萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章