簡介
支持向量機(support vector machines)是一種二分類模型,它的目的是尋找一個超平面來對樣本進行分割,分割的原則是間隔最大化,最終轉化為一個凸二次規划問題來求解。由簡至繁的模型包括:
當訓練樣本線性可分時,通過硬間隔最大化,學習一個線性可分支持向量機;
當訓練樣本近似線性可分時,通過軟間隔最大化,學習一個線性支持向量機;
當訓練樣本線性不可分時,通過核技巧和軟間隔最大化,學習一個非線性支持向量機;
支持向量機的優勢在於:
1)在高維空間中非常高效.
2)即使在數據維度比樣本數量大的情況下仍然有效.
3)在決策函數(稱為支持向量)中使用訓練集的子集,因此它也是高效利用內存的.
4)通用性: 不同的核函數, 核函數與特定的決策函數一一對應.常見的 kernel 已經提供,也可以指定定制的內核.
支持向量機的缺點包括:
1)如果特征數量比樣本數量大得多,在選擇核函數時要避免過擬合,而且正則化項是非常重要的.
2)支持向量機不直接提供概率估計,這些都是使用昂貴的五次交叉驗算計算的.
線性可分支持向量
1、間隔最大化和支持向量
如果一個線性函數能夠將樣本分開,稱這些數據樣本是線性可分的。那么什么是線性函數呢?其實很簡單,在二維空間中就是一條直線,在三維空間中就是一個平面,以此類推,如果不考慮空間維數,這樣的線性函數統稱為超平面。我們看一個簡單的二維空間的例子,O代表正類,X代表負類,樣本是線性可分的,但是很顯然不只有這一條直線可以將樣本分開,而是有無數條,我們所說的線性可分支持向量機就對應着能將數據正確划分並且間隔最大的直線。

那么我們考慮第一個問題,為什么要間隔最大呢?一般來說,一個點距離分離超平面的遠近可以表示分類預測的確信度,如圖中的A B兩個樣本點,B點被預測為正類的確信度要大於A點,所以SVM的目標是尋找一個超平面,使得離超平面較近的異類點之間能有更大的間隔,即不必考慮所有樣本點,只需讓求得的超平面使得離它近的點間隔最大。
接下來考慮第二個問題,怎么計算間隔?只有計算出了間隔,才能使得間隔最大化。在樣本空間中,划分超平面可通過如下線性方程來描述:

其中w為法向量,決定了超平面的方向,b為位移量,決定了超平面與原點的距離。假設超平面能將訓練樣本正確地分類,即對於訓練樣本(xi,yi),滿足以下公式:

公式(2)稱為最大間隔假設,yi=+1 表示樣本為正樣本,yi=−1表示樣本為負樣本,式子前面選擇大於等於+1,小於等於-1只是為了計算方便,原則上可以是任意常數,但無論是多少,都可以通過對 w 的變換使其為 +1 和 -1 ,此時將公式(2)左右都乘以 yi,得到如下:

實際上等價於:

訓練集中的所有樣本都應滿足公式(3)。如下圖所示,距離超平面最近的這幾個樣本點滿足 yi(wTxi+b)=1,它們被稱為“支持向量”。虛線稱為邊界,兩條虛線間的距離稱為間隔(margin)。

下面我們開始計算間隔,其實間隔就等於兩個異類支持向量的差在 w 上的投影,即:

其中 x⃗ +和 x⃗ −分別表示兩個正負支持向量,因為 x⃗ + 和 x⃗ −滿足yi(wTxi+b)=1,即:

推出:

代入公式(4)中可以得到:

至此,我們求得了間隔,SVM的思想是使得間隔最大化,也就是:

顯然,最大化 相當於最小化 ||w||,為了計算方便,將公式(6)轉化成如下:

公式(7)即為支持向量機的基本型。
2、對偶問題
公式(7)本身是一個凸二次規划問題,可以使用現有的優化計算包來計算,但我們選擇更為高效的方法。對公式(7)使用拉格朗日乘子法得到其對偶問題,該問題的拉格朗日函數可以寫為:

公式(8)分別對 w 和 b求偏導:

令其分別為0,可以得到:

將公式(9)(10)代入公式(8),可得:

此時,原問題就轉化為以下僅關於 α的問題:

解出 αα 之后,根據公式(9)可以求得 w , 進而求得 b,可以得到模型:

上述過程的KKT條件為:

我們分析一下,對於任意的訓練樣本 (xi,yi)(xi,yi),
(1)若 αi=0,則其不會在公式(13)中的求和項中出現,也就是說,它不影響模型的訓練;
(2)若 αi>0,則 yif(xi)−1=0,也就是yif(xi)=1,即該樣本一定在邊界上,是一個支持向量。
這里顯示出了支持向量機的重要特征:當訓練完成后,大部分樣本都不需要保留,最終模型只與支持向量有關。
非線性支持向量機和核函數
對於非線性問題,線性可分支持向量機並不能有效解決,要使用非線性模型才能很好地分類。先看一個例子,如下圖,很顯然使用直線並不能將兩類樣本分開,但是可以使用一條橢圓曲線(非線性模型)將它們分開。非線性問題往往不好求解,所以希望能用解線性分類問題的方法求解,因此可以采用非線性變換,將非線性問題變換成線性問題。

對於這樣的問題,可以將訓練樣本從原始空間映射到一個更高維的空間,使得樣本在這個空間中線性可分,如果原始空間維數是有限的,即屬性是有限的,那么一定存在一個高維特征空間是樣本可分。令ϕ(x)表示將 x 映射后的特征向量,於是在特征空間中,划分超平面所對應的的模型可表示為:

於是有最小化函數:

其對偶問題為:

若要對公式(16)求解,會涉及到計算 ϕ(xi)Tϕ(xj),這是樣本 xi和 xj映射到特征空間之后的內積,由於特征空間的維數可能很高,甚至是無窮維,因此直接計算 ϕ(xi)Tϕ(xj)通常是困難的,於是想到這樣一個函數:

即 xi和 xj在特征空間中的內積等於他們在原始樣本空間中通過函數 κ(xi,xj) 計算的函數值,於是公式(16)寫成如下:

求解后得到:

這里的函數 κ(xi,xj)就是核函數,在實際應用中,通常人們會從一些常用的核函數里選擇(根據樣本數據的不同,選擇不同的參數,實際上就得到了不同的核函數),下面給出常用的核函數:
線性核:

多項式核(d是多項式的次數,d=1是退化為線性核):

高斯核(σ>0σ>0):

拉普拉斯核(σ>0):

sigmiod核(β>0,θ>0):

線性支持向量機(軟間隔支持向量機)與松弛變量
1、線性支持向量機
在前面的討論中,我們假設訓練樣本在樣本空間或者特征空間中是線性可分的,但在現實任務中往往很難確定合適的核函數使訓練集在特征空間中線性可分,退一步說,即使瞧好找到了這樣的核函數使得樣本在特征空間中線性可分,也很難判斷是不是由於過擬合造成。
線性不可分意味着某些樣本點 (xi,yi) 不能滿足間隔大於等於1的條件,樣本點落在超平面與邊界之間。為解決這一問題,可以對每個樣本點引入一個松弛變量 ξi≥0,使得間隔加上松弛變量大於等於1,這樣約束條件變為:

同時,對於每一個松弛變量 ξi≥0,支付一個代價 ξi≥0,目標函數變為:

其中 C>0為懲罰參數,C值大時對誤分類的懲罰增大, C值小時對誤分類的懲罰減小,公式(21)包含兩層含義:使 ||w||2 盡量小即間隔盡量大,同時使誤分類點的個數盡量小,C是調和兩者的系數。
有了公式(21),可以和線性可分支持向量機一樣考慮線性支持向量機的學習過程,此時,線性支持向量機的學習問題變成如下凸二次規划問題的求解(原始問題):

2、對偶問題
與線性可分支持向量機的對偶問題解法一致,公式(22)的拉格朗日函數為:

其中 αi≥0,μi≥0 是拉格朗日乘子。
令 L(w,b,α,ξ,μ)對 w,b,ξ的偏導數為0可得如下:

將公式(24)(25)(26)代入公式(23)得對偶問題:

解出 α之后,根據公式(9)可以求得 w , 進而求得 b,可以得到模型:

上述過程的KKT條件為:

我們分析一下,對於任意的訓練樣本 (xi,yi),總有 αi=0 或者 yif(xi)−1+ξi=0。
若 αi=0 ,則該樣本不出現在公式(13)中,不影響模型。
若 αi>0,必有 yif(xi)−1+ξi=0 ,即yif(xi)=1−ξi ,此時該樣本為支持向量。
由於 C=αi+μi (公式26)
若 αi<C,則必有μi>0,根據公式(28)知 ξi=0,即該樣本恰好落在最大間隔的邊界上;
若 αi=C,則 μi=0,此時若 ξi≤1則該樣本在最大間隔內部,若 ξi>1則樣本分類錯誤。
總結
至此,關於SVM的三類問題:線性可分支持向量機與硬間隔最大化,非線性支持向量機與核函數,線性支持向量機與軟間隔最大化一一介紹完畢:
我們所面對的所有的機器學算法,都是有適用范圍的,或者說,我們所有的機器學習算法都是有約束的優化問題。而這些約束,就是我們在推導算法之前所做的假設。
比如:Logistics Regression,在Logistics Regression中,假設后驗概率為Logistics 分布;再比如:LDA假設fk(x)是均值不同,方差相同的高斯分布;這些都是我們在推導算法之前所做的假設,也就是算法對數據分布的要求。
而對於SVM而言,它並沒有對原始數據的分布做任何的假設,這就是SVM和LDA、Logistics Regression區別最大的地方。這表明SVM模型對數據分布的要求低,那么其適用性自然就會更廣一些。如果我們事先對數據的分布沒有任何的先驗信息,即,不知道是什么分布,那么SVM無疑是比較好的選擇。
但是,如果我們已經知道數據滿足或者近似滿足高斯分布,那么選擇LDA得到的結果就會更准確。如果我們已經知道數據滿足或者近似滿足Logistics 分布,那么選擇Logistics Regression就會有更好的效果。
sklearn使用
SVC()和NuSVC()
# 分類器的訓練,預測
clf = svm.SVC()或者clf = svm.NuSVC()
clf.fit(X, y)
# 獲得支持向量
>>> clf.support_vectors_
array([[ 0., 0.],
[ 1., 1.]])
# 獲得支持向量的索引get indices of support vectors
>>> clf.support_
array([0, 1]...)
# 為每一個類別獲得支持向量的數量
>>> clf.n_support_
array([1, 1]...)
SVC 和 NuSVC 為多元分類實現了 “one-against-one” 的方法 ,如果 n_class 是類別的數量, 那么 n_class * (n_class - 1) / 2 分類器被重構, 而且每一個從兩個類別中訓練數據.
clf = svm.SVC(decision_function_shape='ovo')
clf.fit(X, Y) #假設分類數是4
dec = clf.decision_function([[1]])
dec.shape[1] # 4 classes: 4*3/2 = 6
>>>6
LinearSVC()
LinearSVC 實現 “one-vs-the-rest” 多類別策略, 對於n分類問題,從而訓練 n 類別的模型. 但是如果只有兩類, 只訓練一個模型。
clf = svm.LinearSVC()
clf.fit(X, Y)
dec = lin_clf.decision_function([[1]])
dec.shape[1]
>>>4
非均衡問題
這個問題期望給予某一類或某個別樣例能使用的關鍵詞 class_weight 和 sample_weight 提高權重(importance).
SVC (而不是 NuSVC) 在 fit 方法中生成了一個關鍵詞 class_weight. 它是形如 {class_label : value} 的字典, value 是浮點數大於 0 的值, 把類 class_label 的參數 C 設置為 C * value.
SVC, NuSVC, SVR, NuSVR 和 OneClassSVM 在 fit 方法中通過關鍵詞 sample_weight 為單一樣例實現權重weights.與 class_weight 相似, 這些把第i個樣例的參數 C 換成 C * sample_weight[i].
