SVM-支援向量機演算法概述 ---一篇非常深入淺出介紹SVM的文章
(一)SVM的背景簡介
支援向量機(Support Vector Machine)是Cortes和Vapnik於1995年首先提出的,它在解決小樣本、非線性及高維模式識別中表現出許多特有的優勢,並能夠推廣應用到函式擬合等其他機器學習問題中[10]。
支援向量機方法是建立在統計學習理論的VC 維理論和結構風險最小原理基礎上的,根據有限的樣本資訊在模型的複雜性(即對特定訓練樣本的學習精度,Accuracy)和學習能力(即無錯誤地識別任意樣本的能力)之間尋求最佳折衷,以期獲得最好的推廣能力[14](或稱泛化能力)。
以上是經常被有關SVM 的學術文獻引用的介紹,有點八股,我來逐一分解並解釋一下。
Vapnik是統計機器學習的大牛,這想必都不用說,他出版的《Statistical Learning Theory》是一本完整闡述統計機器學習思想的名著。在該書中詳細的論證了統計機器學習之所以區別於傳統機器學習的本質,就在於統計機器學習能夠精確的給出學習效果,能夠解答需要的樣本數等等一系列問題。與統計機器學習的精密思維相比,傳統的機器學習基本上屬於摸著石頭過河,用傳統的機器學習方法構造分類系統完全成了一種技巧,一個人做的結果可能很好,另一個人差不多的方法做出來卻很差,缺乏指導和原則。
所謂VC維是對函式類的一種度量,可以簡單的理解為問題的複雜程度,VC維越高,一個問題就越複雜。正是因為SVM關注的是VC維,後面我們可以看到,SVM解決問題的時候,和樣本的維數是無關的(甚至樣本是上萬維的都可以,這使得SVM很適合用來解決文字分類的問題,當然,有這樣的能力也因為引入了核函式)。
結構風險最小聽上去文縐縐,其實說的也無非是下面這回事。
機器學習本質上就是一種對問題真實模型的逼近(我們選擇一個我們認為比較好的近似模型,這個近似模型就叫做一個假設),但毫無疑問,真實模型一定是不知道的(如果知道了,我們幹嗎還要機器學習?直接用真實模型解決問題不就可以了?對吧,哈哈)既然真實模型不知道,那麼我們選擇的假設與問題真實解之間究竟有多大差距,我們就沒法得知。比如說我們認為宇宙誕生於150億年前的一場大爆炸,這個假設能夠描述很多我們觀察到的現象,但它與真實的宇宙模型之間還相差多少?誰也說不清,因為我們壓根就不知道真實的宇宙模型到底是什麼。
這個與問題真實解之間的誤差,就叫做風險(更嚴格的說,誤差的累積叫做風險)。我們選擇了一個假設之後(更直觀點說,我們得到了一個分類器以後),真實誤差無從得知,但我們可以用某些可以掌握的量來逼近它。最直觀的想法就是使用分類器在樣本資料上的分類的結果與真實結果(因為樣本是已經標註過的資料,是準確的資料)之間的差值來表示。這個差值叫做經驗風險Remp(w)。以前的機器學習方法都把經驗風險最小化作為努力的目標,但後來發現很多分類函式能夠在樣本集上輕易達到100%的正確率,在真實分類時卻一塌糊塗(即所謂的推廣能力差,或泛化能力差)。此時的情況便是選擇了一個足夠複雜的分類函式(它的VC維很高),能夠精確的記住每一個樣本,但對樣本之外的資料一律分類錯誤。回頭看看經驗風險最小化原則我們就會發現,此原則適用的大前提是經驗風險要確實能夠逼近真實風險才行(行話叫一致),但實際上能逼近麼?答案是不能,因為樣本數相對於現實世界要分類的文字數來說簡直九牛一毛,經驗風險最小化原則只在這佔很小比例的樣本上做到沒有誤差,當然不能保證在更大比例的真實文字上也沒有誤差。
統計學習因此而引入了泛化誤差界的概念,就是指真實風險應該由兩部分內容刻畫,一是經驗風險,代表了分類器在給定樣本上的誤差;二是置信風險,代表了我們在多大程度上可以信任分類器在未知文字上分類的結果。很顯然,第二部分是沒有辦法精確計算的,因此只能給出一個估計的區間,也使得整個誤差只能計算上界,而無法計算準確的值(所以叫做泛化誤差界,而不叫泛化誤差)。
置信風險與兩個量有關,一是樣本數量,顯然給定的樣本數量越大,我們的學習結果越有可能正確,此時置信風險越小;二是分類函式的VC維,顯然VC維越大,推廣能力越差,置信風險會變大。
泛化誤差界的公式為:
R(w)≤Remp(w)+Ф(n/h)
公式中R(w)就是真實風險,Remp(w)就是經驗風險,Ф(n/h)就是置信風險。統計學習的目標從經驗風險最小化變為了尋求經驗風險與置信風險的和最小,即結構風險最小。
SVM正是這樣一種努力最小化結構風險的演算法。
SVM其他的特點就比較容易理解了。
小樣本,並不是說樣本的絕對數量少(實際上,對任何演算法來說,更多的樣本幾乎總是能帶來更好的效果),而是說與問題的複雜度比起來,SVM演算法要求的樣本數是相對比較少的。
非線性,是指SVM擅長應付樣本資料線性不可分的情況,主要通過鬆弛變數(也有人叫懲罰變數)和核函式技術來實現,這一部分是SVM的精髓,以後會詳細討論。多說一句,關於文字分類這個問題究竟是不是線性可分的,尚沒有定論,因此不能簡單的認為它是線性可分的而作簡化處理,在水落石出之前,只好先當它是線性不可分的(反正線性可分也不過是線性不可分的一種特例而已,我們向來不怕方法過於通用)。
高維模式識別是指樣本維數很高,例如文字的向量表示,如果沒有經過另一系列文章(《文字分類入門》)中提到過的降維處理,出現幾萬維的情況很正常,其他演算法基本就沒有能力應付了,SVM卻可以,主要是因為SVM 產生的分類器很簡潔,用到的樣本資訊很少(僅僅用到那些稱之為“支援向量”的樣本,此為後話),使得即使樣本維數很高,也不會給儲存和計算帶來大麻煩(相對照而言,kNN演算法在分類時就要用到所有樣本,樣本數巨大,每個樣本維數再一高,這日子就沒法過了……)。
下一節開始正式討論SVM。別嫌我說得太詳細哦。
SVM入門(二)線性分類器Part 1
線性分類器(一定意義上,也可以叫做感知機) 是最簡單也很有效的分類器形式.在一個線性分類器中,可以看到SVM形成的思路,並接觸很多SVM的核心概念.
用一個二維空間裡僅有兩類樣本的分類問題來舉個小例子。如圖所示
C1和C2是要區分的兩個類別,在二維平面中它們的樣本如上圖所示。中間的直線就是一個分類函式,它可以將兩類樣本完全分開。一般的,如果一個線性函式能夠將樣本完全正確的分開,就稱這些資料是線性可分的,否則稱為非線性可分的。
什麼叫線性函式呢?在一維空間裡就是一個點,在二維空間裡就是一條直線,三維空間裡就是一個平面,可以如此想象下去,如果不關注空間的維數,這種線性函式還有一個統一的名稱——超平面(Hyper Plane)!
實際上,一個線性函式是一個實值函式(即函式的值是連續的實數),而我們的分類問題(例如這裡的二元分類問題——回答一個樣本屬於還是不屬於一個類別的問題)需要離散的輸出值,例如用1表示某個樣本屬於類別C1,而用0表示不屬於(不屬於C1也就意味著屬於C2),這時候只需要簡單的在實值函式的基礎上附加一個閾值即可,通過分類函式執行時得到的值大於還是小於這個閾值來確定類別歸屬。 例如我們有一個線性函式
g(x)=wx+b
我們可以取閾值為0,這樣當有一個樣本xi需要判別的時候,我們就看g(xi)的值。若g(xi)>0,就判別為類別C1,若g(xi)<0,則判別為類別C2(等於的時候我們就拒絕判斷,呵呵)。此時也等價於給函式g(x)附加一個符號函式sgn(),即f(x)=sgn [g(x)]是我們真正的判別函式。
關於g(x)=wx+b這個表示式要注意三點:一,式中的x不是二維座標系中的橫軸,而是樣本的向量表示,例如一個樣本點的座標是(3,8),則xT=(3,8) ,而不是x=3(一般說向量都是說列向量,因此以行向量形式來表示時,就加上轉置)。二,這個形式並不侷限於二維的情況,在n維空間中仍然可以使用這個表示式,只是式中的w成為了n維向量(在二維的這個例子中,w是二維向量,為了表示起來方便簡潔,以下均不區別列向量和它的轉置,聰明的讀者一看便知);三,g(x)不是中間那條直線的表示式,中間那條直線的表示式是g(x)=0,即wx+b=0,我們也把這個函式叫做分類面。
實際上很容易看出來,中間那條分界線並不是唯一的,我們把它稍微旋轉一下,只要不把兩類資料分錯,仍然可以達到上面說的效果,稍微平移一下,也可以。此時就牽涉到一個問題,對同一個問題存在多個分類函式的時候,哪一個函式更好呢?顯然必須要先找一個指標來量化“好”的程度,通常使用的都是叫做“分類間隔”的指標。下一節我們就仔細說說分類間隔,也補一補相關的數學知識。
SVM入門(三)線性分類器Part 2
上回說到對於文字分類這樣的不適定問題(有一個以上解的問題稱為不適定問題),需要有一個指標來衡量解決方案(即我們通過訓練建立的分類模型)的好壞,而分類間隔是一個比較好的指標。
在進行文字分類的時候,我們可以讓計算機這樣來看待我們提供給它的訓練樣本,每一個樣本由一個向量(就是那些文字特徵所組成的向量)和一個標記(標示出這個樣本屬於哪個類別)組成。如下:
Di=(xi,yi)
xi就是文字向量(維數很高),yi就是分類標記。
在二元的線性分類中,這個表示分類的標記只有兩個值,1和-1(用來表示屬於還是不屬於這個類)。有了這種表示法,我們就可以定義一個樣本點到某個超平面的間隔:
δi=yi(wxi+b)
這個公式乍一看沒什麼神祕的,也說不出什麼道理,只是個定義而已,但我們做做變換,就能看出一些有意思的東西。
首先注意到如果某個樣本屬於該類別的話,那麼wxi+b>0(記得麼?這是因為我們所選的g(x)=wx+b就通過大於0還是小於0來判斷分類),而yi也大於0;若不屬於該類別的話,那麼wxi+b<0,而yi也小於0,這意味著yi(wxi+b)總是大於0的,而且它的值就等於|wxi+b|!(也就是|g(xi)|)
現在把w和b進行一下歸一化,即用w/||w||和b/||w||分別代替原來的w和b,那麼間隔就可以寫成
這個公式是不是看上去有點眼熟?沒錯,這不就是解析幾何中點xi到直線g(x)=0的距離公式嘛!(推廣一下,是到超平面g(x)=0的距離, g(x)=0就是上節中提到的分類超平面)
小Tips:||w||是什麼符號?||w||叫做向量w的範數,範數是對向量長度的一種度量。我們常說的向量長度其實指的是它的2-範數,範數最一般的表示形式為p-範數,可以寫成如下表達式
向量w=(w1, w2, w3,…… wn)
它的p-範數為
看看把p換成2的時候,不就是傳統的向量長度麼?當我們不指明p的時候,就像||w||這樣使用時,就意味著我們不關心p的值,用幾範數都可以;或者上文已經提到了p的值,為了敘述方便不再重複指明。
當用歸一化的w和b代替原值之後的間隔有一個專門的名稱,叫做幾何間隔,幾何間隔所表示的正是點到超平面的歐氏距離,我們下面就簡稱幾何間隔為“距離”。以上是單個點到某個超平面的距離(就是間隔,後面不再區別這兩個詞)定義,同樣可以定義一個點的集合(就是一組樣本)到某個超平面的距離為此集合中離超平面最近的點的距離。下面這張圖更加直觀的展示出了幾何間隔的現實含義:
H是分類面,而H1和H2是平行於H,且過離H最近的兩類樣本的直線,H1與H,H2與H之間的距離就是幾何間隔。
之所以如此關心幾何間隔這個東西,是因為幾何間隔與樣本的誤分次數間存在關係:
其中的δ是樣本集合到分類面的間隔,R=max ||xi|| i=1,...,n,即R是所有樣本中(xi是以向量表示的第i個樣本)向量長度最長的值(也就是說代表樣本的分佈有多麼廣)。先不必追究誤分次數的具體定義和推導過程,只要記得這個誤分次數一定程度上代表分類器的誤差。而從上式可以看出,誤分次數的上界由幾何間隔決定!(當然,是樣本已知的時候)
至此我們就明白為何要選擇幾何間隔來作為評價一個解優劣的指標了,原來幾何間隔越大的解,它的誤差上界越小。因此最大化幾何間隔成了我們訓練階段的目標,而且,與二把刀作者所寫的不同,最大化分類間隔並不是SVM的專利,而是早線上性分類時期就已有的思想。
SVM-支援向量機(二)
上節說到我們有了一個線性分類函式,也有了判斷解優劣的標準——即有了優化的目標,這個目標就是最大化幾何間隔,但是看過一些關於SVM的論文的人一定記得什麼優化的目標是要最小化||w||這樣的說法,這是怎麼回事呢?回頭再看看我們對間隔和幾何間隔的定義:
間隔:δ=y(wx+b)=|g(x)|
可以看出δ=||w||δ幾何。注意到幾何間隔與||w||是成反比的,因此最大化幾何間隔與最小化||w||完全是一回事。而我們常用的方法並不是固定||w||的大小而尋求最大幾何間隔,而是固定間隔(例如固定為1),尋找最小的||w||。
而凡是求一個函式的最小值(或最大值)的問題都可以稱為尋優問題(也叫作一個規劃問題),又由於找最大值的問題總可以通過加一個負號變為找最小值的問題,因此我們下面討論的時候都針對找最小值的過程來進行。一個尋優問題最重要的部分是目標函式,顧名思義,就是指尋優的目標。例如我們想尋找最小的||w||這件事,就可以用下面的式子表示:
但實際上對於這個目標,我們常常使用另一個完全等價的目標函式來代替,那就是:
不難看出當||w||2達到最小時,||w||也達到最小,反之亦然(前提當然是||w||描述的是向量的長度,因而是非負的)。之所以採用這種形式,是因為後面的求解過程會對目標函式作一系列變換,而式(1)的形式會使變換後的形式更為簡潔(正如聰明的讀者所料,新增的係數二分之一和平方,皆是為求導數所需)。
接下來我們自然會問的就是,這個式子是否就描述了我們的問題呢?(回想一下,我們的問題是有一堆點,可以被分成兩類,我們要找出最好的分類面)
如果直接來解這個求最小值問題,很容易看出當||w||=0的時候就得到了目標函式的最小值。但是你也會發現,無論你給什麼樣的資料,都是這個解!反映在圖中,就是H1與H2兩條直線間的距離無限大,這個時候,所有的樣本點(無論正樣本還是負樣本)都跑到了H1和H2中間,而我們原本的意圖是,H1右側的被分為正類,H2 左側的被分為負類,位於兩類中間的樣本則拒絕分類(拒絕分類的另一種理解是分給哪一類都有道理,因而分給哪一類也都沒有道理)。這下可好,所有樣本點都進入了無法分類的灰色地帶。
|
造成這種結果的原因是在描述問題的時候只考慮了目標,而沒有加入約束條件,約束條件就是在求解過程中必須滿足的條件,體現在我們的問題中就是樣本點必須在H1或H2的某一側(或者至少在H1和H2上),而不能跑到兩者中間。我們前文提到過把間隔固定為1,這是指把所有樣本點中間隔最小的那一點的間隔定為1(這也是集合的間隔的定義,有點繞嘴),也就意味著集合中的其他點間隔都不會小於1,按照間隔的定義,滿足這些條件就相當於讓下面的式子總是成立:
yi[(w·xi)+b]≥1 (i=1,2,…,l) (l是總的樣本數)
但我們常常習慣讓式子的值和0比較,因而經常用變換過的形式:
yi[(w·xi)+b]-1≥0 (i=1,2,…,l) (l是總的樣本數)
因此我們的兩類分類問題也被我們轉化成了它的數學形式,一個帶約束的最小值的問題:
從最一般的定義上說,一個求最小值的問題就是一個優化問題(也叫尋優問題,更文縐縐的叫法是規劃——Programming),它同樣由兩部分組成,目標函式和約束條件,可以用下面的式子表示:
約束條件用函式c來表示,就是constrain的意思啦。你可以看出一共有p+q個約束條件,其中p個是不等式約束,q個等式約束。
關於這個式子可以這樣來理解:式中的x是自變數,但不限定它的維數必須為1(視乎你解決的問題空間維數,對我們的文字分類來說,那可是成千上萬啊)。要求f(x)在哪一點上取得最小值(反倒不太關心這個最小值到底是多少,關鍵是哪一點),但不是在整個空間裡找,而是在約束條件所劃定的一個有限的空間裡找,這個有限的空間就是優化理論裡所說的可行域。注意可行域中的每一個點都要求滿足所有p+q個條件,而不是滿足其中一條或幾條就可以(切記,要滿足每個約束),同時可行域邊界上的點有一個額外好的特性,它們可以使不等式約束取得等號!而邊界內的點不行。
關於可行域還有個概念不得不提,那就是凸集,凸集是指有這麼一個點的集合,其中任取兩個點連一條直線,這條線上的點仍然在這個集合內部,因此說“凸”是很形象的(一個反例是,二維平面上,一個月牙形的區域就不是凸集,你隨便就可以找到兩個點違反了剛才的規定)。
回頭再來看我們線性分類器問題的描述,可以看出更多的東西。
在這個問題中,自變數就是w,而目標函式是w的二次函式,所有的約束條件都是w的線性函式(哎,千萬不要把xi當成變數,它代表樣本,是已知的),這種規劃問題有個很有名氣的稱呼——二次規劃(Quadratic Programming,QP),而且可以更進一步的說,由於它的可行域是一個凸集,因此它是一個凸二次規劃。
一下子提了這麼多術語,實在不是為了讓大家以後能向別人炫耀學識的淵博,這其實是我們繼續下去的一個重要前提,因為在動手求一個問題的解之前(好吧,我承認,是動計算機求……),我們必須先問自己:這個問題是不是有解?如果有解,是否能找到?
對於一般意義上的規劃問題,兩個問題的答案都是不一定,但凸二次規劃讓人喜歡的地方就在於,它有解(教科書裡面為了嚴謹,常常加限定成分,說它有全域性最優解,由於我們想找的本來就是全域性最優的解,所以不加也罷),而且可以找到!(當然,依據你使用的演算法不同,找到這個解的速度,行話叫收斂速度,會有所不同)
對比(式2)和(式1)還可以發現,我們的線性分類器問題只有不等式約束,因此形式上看似乎比一般意義上的規劃問題要簡單,但解起來卻並非如此。
因為我們實際上並不知道該怎麼解一個帶約束的優化問題。如果你仔細回憶一下高等數學的知識,會記得我們可以輕鬆的解一個不帶任何約束的優化問題(實際上就是當年背得爛熟的函式求極值嘛,求導再找0點唄,誰不會啊?笑),我們甚至還會解一個只帶等式約束的優化問題,也是背得爛熟的,求條件極值,記得麼,通過新增拉格朗日乘子,構造拉格朗日函式,來把這個問題轉化為無約束的優化問題云云(如果你一時沒想通,我提醒一下,構造出的拉格朗日函式就是轉化之後的問題形式,它顯然沒有帶任何條件)。
讓我再一次比較完整的重複一下我們要解決的問題:我們有屬於兩個類別的樣本點(並不限定這些點在二維空間中)若干,如圖,
圓形的樣本點定為正樣本(連帶著,我們可以把正樣本所屬的類叫做正類),方形的點定為負例。我們想求得這樣一個線性函式(在n維空間中的線性函式):
g(x)=wx+b
使得所有屬於正類的點x+代入以後有g(x+)≥1,而所有屬於負類的點x-代入後有g(x-)≤-1(之所以總跟1比較,無論正一還是負一,都是因為我們固定了間隔為1,注意間隔和幾何間隔的區別)。代入g(x)後的值如果在1和-1之間,我們就拒絕判斷。
求這樣的g(x)的過程就是求w(一個n維向量)和b(一個實數)兩個引數的過程(但實際上只需要求w,求得以後找某些樣本點代入就可以求得b)。因此在求g(x)的時候,w才是變數。
你肯定能看出來,一旦求出了w(也就求出了b),那麼中間的直線H就知道了(因為它就是wx+b=0嘛,哈哈),那麼H1和H2也就知道了(因為三者是平行的,而且相隔的距離還是||w||決定的)。那麼w是誰決定的?顯然是你給的樣本決定的,一旦你在空間中給出了那些個樣本點,三條直線的位置實際上就唯一確定了(因為我們求的是最優的那三條,當然是唯一的),我們解優化問題的過程也只不過是把這個確定了的東西算出來而已。
樣本確定了w,用數學的語言描述,就是w可以表示為樣本的某種組合:
w=α1x1+α2x2+…+αnxn
式子中的αi是一個一個的數(在嚴格的證明過程中,這些α被稱為拉格朗日乘子),而xi是樣本點,因而是向量,n就是總樣本點的個數。為了方便描述,以下開始嚴格區別數字與向量的乘積和向量間的乘積,我會用α1x1表示數字和向量的乘積,而用<x1,x2>表示向量x1,x2的內積(也叫點積,注意與向量叉積的區別)。因此g(x)的表示式嚴格的形式應該是:
g(x)=<w,x>+b
但是上面的式子還不夠好,你回頭看看圖中正樣本和負樣本的位置,想像一下,我不動所有點的位置,而只是把其中一個正樣本點定為負樣本點(也就是把一個點的形狀從圓形變為方形),結果怎麼樣?三條直線都必須移動(因為對這三條直線的要求是必須把方形和圓形的點正確分開)!這說明w不僅跟樣本點的位置有關,還跟樣本的類別有關(也就是和樣本的“標籤”有關)。因此用下面這個式子表示才算完整:
w=α1y1x1+α2y2x2+…+αnynxn(式1)
其中的yi就是第i個樣本的標籤,它等於1或者-1。其實以上式子的那一堆拉格朗日乘子中,只有很少的一部分不等於0(不等於0才對w起決定作用),這部分不等於0的拉格朗日乘子後面所乘的樣本點,其實都落在H1和H2上,也正是這部分樣本(而不需要全部樣本)唯一的確定了分類函式,當然,更嚴格的說,這些樣本的一部分就可以確定,因為例如確定一條直線,只需要兩個點就可以,即便有三五個都落在上面,我們也不是全都需要。這部分我們真正需要的樣本點,就叫做支援(撐)向量!(名字還挺形象吧,他們“撐”起了分界線)
式子也可以用求和符號簡寫一下:
因此原來的g(x)表示式可以寫為:
注意式子中x才是變數,也就是你要分類哪篇文件,就把該文件的向量表示代入到 x的位置,而所有的xi統統都是已知的樣本。還注意到式子中只有xi和x是向量,因此一部分可以從內積符號中拿出來,得到g(x)的式子為:
發現了什麼?w不見啦!從求w變成了求α。
但肯定有人會說,這並沒有把原問題簡化呀。嘿嘿,其實簡化了,只不過在你看不見的地方,以這樣的形式描述問題以後,我們的優化問題少了很大一部分不等式約束(記得這是我們解不了極值問題的萬惡之源)。但是接下來先跳過線性分類器求解的部分,來看看 SVM線上性分類器上所做的重大改進——核函式。
SVM-支援向量機詳解(三)
之前一直在討論的線性分類器,器如其名,只能對線性可分的樣本做處理。如果提供的樣本線性不可分,結果很簡單,線性分類器的求解程式會無限迴圈,永遠也解不出來。這必然使得它的適用範圍大大縮小,而它的很多優點我們實在不原意放棄,怎麼辦呢?是否有某種方法,讓線性不可分的資料變得線性可分呢?
有!其思想說來也簡單,來用一個二維平面中的分類問題作例子,你一看就會明白。事先宣告,下面這個例子是網路早就有的,我一時找不到原作者的正確資訊,在此借用,並加進了我自己的解說而已。
例子是下面這張圖:
我們把橫軸上端點a和b之間紅色部分裡的所有點定為正類,兩邊的黑色部分裡的點定為負類。試問能找到一個線性函式把兩類正確分開麼?不能,因為二維空間裡的線性函式就是指直線,顯然找不到符合條件的直線。
但我們可以找到一條曲線,例如下面這一條:
顯然通過點在這條曲線的上方還是下方就可以判斷點所屬的類別(你在橫軸上隨便找一點,算算這一點的函式值,會發現負類的點函式值一定比0大,而正類的一定比0小)。這條曲線就是我們熟知的二次曲線,它的函式表示式可以寫為:
問題只是它不是一個線性函式,但是,下面要注意看了,新建一個向量y和a:
這樣g(x)就可以轉化為f(y)=<a,y>,你可以把y和a分別迴帶一下,看看等不等於原來的g(x)。用內積的形式寫你可能看不太清楚,實際上f(y)的形式就是:
g(x)=f(y)=ay
在任意維度的空間中,這種形式的函式都是一個線性函式(只不過其中的a和y都是多維向量罷了),因為自變數y的次數不大於1。
看出妙在哪了麼?原來在二維空間中一個線性不可分的問題,對映到四維空間後,變成了線性可分的!因此這也形成了我們最初想解決線性不可分問題的基本思路——向高維空間轉化,使其變得線性可分。
而轉化最關鍵的部分就在於找到x到y的對映方法。遺憾的是,如何找到這個對映,沒有系統性的方法(也就是說,純靠猜和湊)。具體到我們的文字分類問題,文字被表示為上千維的向量,即使維數已經如此之高,也常常是線性不可分的,還要向更高的空間轉化。其中的難度可想而知。
小Tips:為什麼說f(y)=ay是四維空間裡的函式?
大家可能一時沒看明白。回想一下我們二維空間裡的函式定義
g(x)=ax+b
變數x是一維的,為什麼說它是二維空間裡的函式呢?因為還有一個變數我們沒寫出來,它的完整形式其實是
y=g(x)=ax+b
即
y=ax+b
看看,有幾個變數?兩個。那是幾維空間的函式?(作者五歲的弟弟答:五維的。作者:……)
再看看
f(y)=ay
裡面的y是三維的變數,那f(y)是幾維空間裡的函式?(作者五歲的弟弟答:還是五維的。作者:……)
用一個具體文字分類的例子來看看這種向高維空間對映從而分類的方法如何運作,想象一下,我們文字分類問題的原始空間是1000維的(即每個要被分類的文件被表示為一個1000維的向量),在這個維度上問題是線性不可分的。現在我們有一個2000維空間裡的線性函式
f(x’)=<w’,x’>+b
注意向量的右上角有個 ’哦。它能夠將原問題變得可分。式中的 w’和x’都是2000維的向量,只不過w’是定值,而x’是變數(好吧,嚴格說來這個函式是2001維的,哈哈),現在我們的輸入呢,是一個1000維的向量x,分類的過程是先把x變換為2000維的向量x’,然後求這個變換後的向量x’與向量w’的內積,再把這個內積的值和b相加,就得到了結果,看結果大於閾值還是小於閾值就得到了分類結果。
你發現了什麼?我們其實只關心那個高維空間裡內積的值,那個值算出來了,分類結果就算出來了。而從理論上說, x’是經由x變換來的,因此廣義上可以把它叫做x的函式(有一個x,就確定了一個x’,對吧,確定不出第二個),而w’是常量,它是一個低維空間裡的常量w經過變換得到的,所以給了一個w 和x的值,就有一個確定的f(x’)值與其對應。這讓我們幻想,是否能有這樣一種函式K(w,x),他接受低維空間的輸入值,卻能算出高維空間的內積值<w’,x’>?
如果有這樣的函式,那麼當給了一個低維空間的輸入x以後,
g(x)=K(w,x)+b
f(x’)=<w’,x’>+b
這兩個函式的計算結果就完全一樣,我們也就用不著費力找那個對映關係,直接拿低維的輸入往g(x)裡面代就可以了(再次提醒,這回的g(x)就不是線性函式啦,因為你不能保證K(w,x)這個表示式裡的x次數不高於1哦)。
萬幸的是,這樣的K(w,x)確實存在(發現凡是我們人類能解決的問題,大都是巧得不能再巧,特殊得不能再特殊的問題,總是恰好有些能投機取巧的地方才能解決,由此感到人類的渺小),它被稱作核函式(核,kernel),而且還不止一個,事實上,只要是滿足了Mercer條件的函式,都可以作為核函式。核函式的基本作用就是接受兩個低維空間裡的向量,能夠計算出經過某個變換後在高維空間裡的向量內積值。幾個比較常用的核函式,俄,教課書裡都列過,我就不敲了(懶!)。
回想我們上節說的求一個線性分類器,它的形式應該是:
現在這個就是高維空間裡的線性函式(為了區別低維和高維空間裡的函式和向量,我改了函式的名字,並且給w和x都加上了 ’),我們就可以用一個低維空間裡的函式(再一次的,這個低維空間裡的函式就不再是線性的啦)來代替,
又發現什麼了?f(x’) 和g(x)裡的α,y,b全都是一樣一樣的!這就是說,儘管給的問題是線性不可分的,但是我們就硬當它是線性問題來求解,只不過求解過程中,凡是要求內積的時候就用你選定的核函式來算。這樣求出來的α再和你選定的核函式一組合,就得到分類器啦!
明白了以上這些,會自然的問接下來兩個問題:
1. 既然有很多的核函式,針對具體問題該怎麼選擇?
2. 如果使用核函式向高維空間對映後,問題仍然是線性不可分的,那怎麼辦?
第一個問題現在就可以回答你:對核函式的選擇,現在還缺乏指導原則!各種實驗的觀察結果(不光是文字分類)的確表明,某些問題用某些核函式效果很好,用另一些就很差,但是一般來講,徑向基核函式是不會出太大偏差的一種,首選。(我做文字分類系統的時候,使用徑向基核函式,沒有引數調優的情況下,絕大部分類別的準確和召回都在85%以上,可見。雖然libSVM的作者林智仁認為文字分類用線性核函式效果更佳,待考證)
現在我們已經把一個本來線性不可分的文字分類問題,通過對映到高維空間而變成了線性可分的。就像下圖這樣:
圓形和方形的點各有成千上萬個(畢竟,這就是我們訓練集中文件的數量嘛,當然很大了)。現在想象我們有另一個訓練集,只比原先這個訓練集多了一篇文章,對映到高維空間以後(當然,也使用了相同的核函式),也就多了一個樣本點,但是這個樣本的位置是這樣的:
就是圖中黃色那個點,它是方形的,因而它是負類的一個樣本,這單獨的一個樣本,使得原本線性可分的問題變成了線性不可分的。這樣類似的問題(僅有少數點線性不可分)叫做“近似線性可分”的問題。
以我們人類的常識來判斷,說有一萬個點都符合某種規律(因而線性可分),有一個點不符合,那這一個點是否就代表了分類規則中我們沒有考慮到的方面呢(因而規則應該為它而做出修改)?
其實我們會覺得,更有可能的是,這個樣本點壓根就是錯誤,是噪聲,是提供訓練集的同學人工分類時一打瞌睡錯放進去的。所以我們會簡單的忽略這個樣本點,仍然使用原來的分類器,其效果絲毫不受影響。
但這種對噪聲的容錯性是人的思維帶來的,我們的程式可沒有。由於我們原本的優化問題的表示式中,確實要考慮所有的樣本點(不能忽略某一個,因為程式它怎麼知道該忽略哪一個呢?),在此基礎上尋找正負類之間的最大幾何間隔,而幾何間隔本身代表的是距離,是非負的,像上面這種有噪聲的情況會使得整個問題無解。這種解法其實也叫做“硬間隔”分類法,因為他硬性的要求所有樣本點都滿足和分類平面間的距離必須大於某個值。
因此由上面的例子中也可以看出,硬間隔的分類法其結果容易受少數點的控制,這是很危險的(儘管有句話說真理總是掌握在少數人手中,但那不過是那一小撮人聊以自慰的詞句罷了,咱還是得民主)。
但解決方法也很明顯,就是仿照人的思路,允許一些點到分類平面的距離不滿足原先的要求。由於不同的訓練集各點的間距尺度不太一樣,因此用間隔(而不是幾何間隔)來衡量有利於我們表達形式的簡潔。我們原先對樣本點的要求是:
意思是說離分類面最近的樣本點函式間隔也要比1大。如果要引入容錯性,就給1這個硬性的閾值加一個鬆弛變數,即允許
因為鬆弛變數是非負的,因此最終的結果是要求間隔可以比1小。但是當某些點出現這種間隔比1小的情況時(這些點也叫離群點),意味著我們放棄了對這些點的精確分類,而這對我們的分類器來說是種損失。但是放棄這些點也帶來了好處,那就是使分類面不必向這些點的方向移動,因而可以得到更大的幾何間隔(在低維空間看來,分類邊界也更平滑)。顯然我們必須權衡這種損失和好處。好處很明顯,我們得到的分類間隔越大,好處就越多。回顧我們原始的硬間隔分類對應的優化問題:
||w||2就是我們的目標函式(當然係數可有可無),希望它越小越好,因而損失就必然是一個能使之變大的量(能使它變小就不叫損失了,我們本來就希望目標函式值越小越好)。那如何來衡量損失,有兩種常用的方式,有人喜歡用
而有人喜歡用
其中l都是樣本的數目。兩種方法沒有大的區別。如果選擇了第一種,得到的方法的就叫做二階軟間隔分類器,第二種就叫做一階軟間隔分類器。把損失加入到目標函式裡的時候,就需要一個懲罰因子(cost,也就是libSVM的諸多引數中的C),原來的優化問題就變成了下面這樣:
這個式子有這麼幾點要注意:
一是並非所有的樣本點都有一個鬆弛變數與其對應。實際上只有“離群點”才有,或者也可以這麼看,所有沒離群的點鬆弛變數都等於0(對負類來說,離群點就是在前面圖中,跑到H2右側的那些負樣本點,對正類來說,就是跑到H1左側的那些正樣本點)。
二是鬆弛變數的值實際上標示出了對應的點到底離群有多遠,值越大,點就越遠。
三是懲罰因子C決定了你有多重視離群點帶來的損失,顯然當所有離群點的鬆弛變數的和一定時,你定的C越大,對目標函式的損失也越大,此時就暗示著你非常不願意放棄這些離群點,最極端的情況是你把C定為無限大,這樣只要稍有一個點離群,目標函式的值馬上變成無限大,馬上讓問題變成無解,這就退化成了硬間隔問題。
四是懲罰因子C不是一個變數,整個優化問題在解的時候,C是一個你必須事先指定的值,指定這個值以後,解一下,得到一個分類器,然後用測試資料看看結果怎麼樣,如果不夠好,換一個C的值,再解一次優化問題,得到另一個分類器,再看看效果,如此就是一個引數尋優的過程,但這和優化問題本身決不是一回事,優化問題在解的過程中,C一直是定值,要記住。
五是儘管加了鬆弛變數這麼一說,但這個優化問題仍然是一個優化問題(汗,這不廢話麼),解它的過程比起原始的硬間隔問題來說,沒有任何更加特殊的地方。
從大的方面說優化問題解的過程,就是先試著確定一下w,也就是確定了前面圖中的三條直線,這時看看間隔有多大,又有多少點離群,把目標函式的值算一算,再換一組三條直線(你可以看到,分類的直線位置如果移動了,有些原來離群的點會變得不再離群,而有的本來不離群的點會變成離群點),再把目標函式的值算一算,如此往復(迭代),直到最終找到目標函式最小時的w。
囉嗦了這麼多,讀者一定可以馬上自己總結出來,鬆弛變數也就是個解決線性不可分問題的方法罷了,但是回想一下,核函式的引入不也是為了解決線性不可分的問題麼?為什麼要為了一個問題使用兩種方法呢?
其實兩者還有微妙的不同。一般的過程應該是這樣,還以文字分類為例。在原始的低維空間中,樣本相當的不可分,無論你怎麼找分類平面,總會有大量的離群點,此時用核函式向高維空間對映一下,雖然結果仍然是不可分的,但比原始空間裡的要更加接近線性可分的狀態(就是達到了近似線性可分的狀態),此時再用鬆弛變數處理那些少數“冥頑不化”的離群點,就簡單有效得多啦。
本節中的(式1)也確實是支援向量機最最常用的形式。至此一個比較完整的支援向量機框架就有了,簡單說來,支援向量機就是使用了核函式的軟間隔線性分類法。
接下來要說的東西其實不是鬆弛變數本身,但由於是為了使用鬆弛變數才引入的,因此放在這裡也算合適,那就是懲罰因子C。回頭看一眼引入了鬆弛變數以後的優化問題:
注意其中C的位置,也可以回想一下C所起的作用(表徵你有多麼重視離群點,C越大越重視,越不想丟掉它們)。這個式子是以前做SVM的人寫的,大家也就這麼用,但沒有任何規定說必須對所有的鬆弛變數都使用同一個懲罰因子,我們完全可以給每一個離群點都使用不同的C,這時就意味著你對每個樣本的重視程度都不一樣,有些樣本丟了也就丟了,錯了也就錯了,這些就給一個比較小的C;而有些樣本很重要,決不能分類錯誤(比如中央下達的檔案啥的,笑),就給一個很大的C。
當然實際使用的時候並沒有這麼極端,但一種很常用的變形可以用來解決分類問題中樣本的“偏斜”問題。
先來說說樣本的偏斜問題,也叫資料集偏斜(unbalanced),它指的是參與分類的兩個類別(也可以指多個類別)樣本數量差異很大。比如說正類有10,000個樣本,而負類只給了100個,這會引起的問題顯而易見,可以看看下面的圖:
方形的點是負類。H,H1,H2是根據給的樣本算出來的分類面,由於負類的樣本很少很少,所以有一些本來是負類的樣本點沒有提供,比如圖中兩個灰色的方形點,如果這兩個點有提供的話,那算出來的分類面應該是H’,H2’和H1,他們顯然和之前的結果有出入,實際上負類給的樣本點越多,就越容易出現在灰色點附近的點,我們算出的結果也就越接近於真實的分類面。但現在由於偏斜的現象存在,使得數量多的正類可以把分類面向負類的方向“推”,因而影響了結果的準確性。
對付資料集偏斜問題的方法之一就是在懲罰因子上作文章,想必大家也猜到了,那就是給樣本數量少的負類更大的懲罰因子,表示我們重視這部分樣本(本來數量就少,再拋棄一些,那人家負類還活不活了),因此我們的目標函式中因鬆弛變數而損失的部分就變成了:
其中i=1…p都是正樣本,j=p+1…p+q都是負樣本。libSVM這個演算法包在解決偏斜問題的時候用的就是這種方法。
那C+和C-怎麼確定呢?它們的大小是試出來的(引數調優),但是他們的比例可以有些方法來確定。咱們先假定說C+是5這麼大,那確定C-的一個很直觀的方法就是使用兩類樣本數的比來算,對應到剛才舉的例子,C-就可以定為500這麼大(因為10,000:100=100:1嘛)。
但是這樣並不夠好,回看剛才的圖,你會發現正類之所以可以“欺負”負類,其實並不是因為負類樣本少,真實的原因是負類的樣本分佈的不夠廣(沒擴充到負類本應該有的區域)。說一個具體點的例子,現在想給政治類和體育類的文章做分類,政治類文章很多,而體育類只提供了幾篇關於