1. 程式人生 > >skiti-learn 支援向量機類庫(SVM)

skiti-learn 支援向量機類庫(SVM)

SVM演算法庫分為兩類,一類是分類演算法庫,SVC,NuSVC,LinearSVC;另一類是迴歸演算法庫,SVR,NuSVR,LinearSVR。
分類演算法庫中,SVC,NuSVC差不多,區別在於損失的度量方式不同;LinearSVC是線性分類,不支援從低維到高維的核函式,僅僅支援線性核函式,對線性不可分資料不能使用。同樣,SVR,NuSVR和LinearSVR與分類演算法庫類似,不過是用作迴歸。
如果有經驗知道資料是線性可以擬合的,那麼使用LinearSVC去分類 或者LinearSVR去迴歸,它們不需要我們去慢慢的調參去選擇各種核函式以及對應引數, 速度也快。如果我們對資料分佈沒有什麼經驗,一般使用SVC去分類或者SVR去迴歸,這就需要我們選擇核函式以及對核函式調參了。如果我們對訓練集訓練的錯誤率或者說支援向量的百分比有要求的時候,可以選擇NuSVC分類 和 NuSVR 。它們有一個引數來控制這個百分比。

  1. SVM分類和迴歸演算法
    SVM分類演算法最原始形式:
    在這裡插入圖片描述
    其中m為樣本個數,我們的樣本為(x1,y1),(x2,y2),…,(xm,ym)。w,b是我們的分離超平面的w∙ϕ(xi)+b=0係數, ξi為第i個樣本的鬆弛係數, C為懲罰係數。ϕ(xi)為低維到高維的對映函式。
    經過拉格朗日和對偶化的形式:
    在這裡插入圖片描述
    和原始形式不同的α為拉格朗日系數向量。K(xi,xj)為我們要使用的核函式
    SVM迴歸演算法原始形式:
    在這裡插入圖片描述
     其中m為樣本個數,我們的樣本為(x1,y1),(x2,y2),…,(xm,ym)。w,b是我們的迴歸超平面的w∙xi+b=0係數, ξ∨i,ξ∧i為第i個樣本的鬆弛係數, C為懲罰係數,ϵ為損失邊界,到超平面距離小於ϵ的訓練集的點沒有損失。ϕ(xi)為低維到高維的對映函式。
     通過拉格朗日和對偶化後:
     在這裡插入圖片描述

  2. SVM核函式
    skiti-learn內建的核函式一共有四種:
    1).線性核函式(Linear Kernel):K(x,z)=x∙z ,就是普通的內積,LinearSVC 和 LinearSVR 只能使用它。
    2).多項式核函式(Polynomial Kernel):是線性不可分SVM核函式之一,K(x,z)=(γx∙z+r)d,其中,γ,r,d都需要自己調參定義。
    3).高斯核函式(Gaussian Kernel):稱為徑向基核函式,也是libsvm預設的核函式,同樣也是skiti-learn預設的核函式,K(x,z)=exp(−γ||x−z||²),其中γ大於0,需要自己調參定義。
    4).Sigmoid核函式(Sigmoid Kernel):也是線性不可分SVM核函式之一,K(x,z)=tanh(γx∙z+r),其中γ,r都需要自己調參定義。
    一般情況下,對非線性資料使用預設的高斯核函式會有比較好的效果。

  3. SVM分類演算法庫引數
    1)懲罰係數C:
    LinearSVC 和SVC即為模型原型形式和對偶形式中的懲罰係數C,預設為1,一般通過交叉驗證來選擇一個合適的C,一般的噪音點較多時,C需要小一些。NuSVC沒有這個引數,是通過nu引數來控制訓練集的錯誤率,等價於選擇了一個C,讓訓練集訓練後滿足一個確定的錯誤率。
    2)nu:
    LinearSVC,SVC沒有這個引數,而採用C來控制懲罰力度;對於NuSVC ,nu代表了訓練集訓練的錯誤率上限,或者說支援向量的百分比下限,取值範圍為(0,1],預設為0.5,與懲罰係數C類似,控制懲罰力度。
    3)核函式Kernel:
    LinearSVC沒有這個引數,只能使用線性核;對於SVC,NuSVC的核函式有四種選擇,’Linear‘線性核,’poly‘多項式核函式,‘rbf’高斯核,‘sigmoid’ sigmoid核函式,如果選擇了核函式,對應的核函式後面有單獨的引數需要調,預設的是高斯核‘rbf’;還有一種選擇“precomputed",即我們預先計算出所有訓練集和測試集的樣本對應的Grem矩陣,這樣K(x,z)直接在對應Grem矩陣中找到對應的位置的值。另外還有自定義核函式。
    4)正則化引數penalty:
    僅LinearSVC有這個引數,可以選擇’l1‘ L1正則化或’l2’L2正則化。預設為L2
    正則化,如果需要選擇稀疏化的係數,可以選擇L1正則化,這和線性迴歸裡面的Lasso迴歸類似。
    5)是否用對偶形式優化dual:
    僅LinearSVC有這個引數,一個布林變數,選擇是否採用對偶形式來優化演算法,預設為True,如果我們樣本量比特徵數多,此時採用對偶形式計算量較大,推薦設定為Flase,即採用原始形式。
    6)核函式引數degree:
    如果 SVC和NuSVC在Kernel引數使用了多項式核‘poly’,那我們就需要對這個引數進行調參,這個引數對應K(x,z)=(γx∙z+r)d中的d。預設為3,一般需要用交叉驗證選擇合適的γ,r,d。
    7)核函式引數gamma:
    如果在SVC或NuSVC中選擇Kernel引數中的高斯核函式‘rbf’,多項式核函式‘poly’,sigmod核函式,就需要進行調參。
    多項式核函式中這個引數對應K(x,z)=(γx∙z+r)d中的γ。一般需要通過交叉驗證選擇一組合適的γ,r,d;高斯核函式中這個引數對應K(x,z)=exp(−γ||x−z||²)中的γ,一般需要通過交叉驗證選擇合適的γ;sigmoid核函式中這個引數對應K(x,z)=tanh(γx∙z+r)中的γ。一般需要通過交叉驗證選擇一組合適的γ,r,γ預設為’auto’,即1特徵維度。
    8)核函式引數coef0:
    如果SVC或者NuSVC選擇Kernel引數‘poly’或者‘sigmoid’,需要對這個引數調參。多項式核函式中這個引數對應K(x,z)=(γx∙z+r)d中的r。一般需要通過交叉驗證選擇一組合適的γ,r,d;sigmoid核函式中這個引數對應K(x,z)=tanh(γx∙z+r)中的r。一般需要通過交叉驗證選擇一組合適的γ,r ;coef0預設為0。
    9)樣本權重class_weight:
    指定樣本各類別的權重,主要是為了防止訓練集某些類別的樣本過多,導致訓練的決策過於偏向這些類別。這裡可以自己指定各個樣本的權重,或者用“balanced”,如果使用“balanced”,則演算法會自己計算權重,樣本量少的類別所對應的樣本權重會高。如果你的樣本類別分佈沒有明顯的偏倚,則可以不管這個引數,選擇預設的"None"。
    10)分類決策decision_function_shape:
    LinearSVC沒有這個引數,使用multi_class引數替代。SVC和nuSVC可以選擇’ovo’或者‘ovr’。OvR(one ve rest)的思想很簡單,無論你是多少元分類,我們都可以看做二元分類。OvO(one-vs-one)則是每次每次在所有的T類樣本里面選擇兩類樣本出來,不妨記為T1類和T2類,把所有的輸出為T1和T2的樣本放在一起,把T1作為正例,T2作為負例,進行二元分類,得到模型引數。我們一共需要T(T-1)/2次分類。OvR相對簡單,但分類效果相對略差。而OvO分類相對精確,但是分類速度沒有OvR快。一般建議使用OvO以達到較好的分類效果。
    11)分類決策multi_class:
    可以選擇 ‘ovr’ 或者 ‘crammer_singer’ 。‘ovr’和SVC和nuSVC中的decision_function_shape對應的‘ovr’類似。‘crammer_singer’是一種改良版的’ovr’,但是沒有比’ovr‘好,一般在應用中都不建議使用。SVC和nuSVC沒有這個引數,使用decision_function_shape引數替代。
    12)快取大小cache_size:
    LinearSVC計算量不大,因此不需要這個引數。SVC和nuSVC在大樣本的時候,快取大小會影響訓練速度,因此如果機器記憶體大,推薦用500MB甚至1000MB。預設是200,即200MB。

  4. SVM迴歸演算法庫
    迴歸演算法庫的主要引數與分類類似,主要有:懲罰係數C,nu,距離誤差epsilon,是否用對偶形式優化dual ,正則化引數penalty ,核函式 kernel,核函式引數degree, gamma 和coef0,損失函式度量loss,快取大小cache_size。其中是否用對偶形式優化dual ,正則化引數penalty ,核函式 kernel,核函式引數degree, gamma 和coef0,快取大小cache_size與分類演算法引數類似。區別:
    1)懲罰係數C:
    預設為1,一般需要通過交叉驗證來選擇一個合適的C。一般來說,如果噪音點較多時,C需要小一些。大家可能注意到在分類模型裡面,nuSVC使用了nu這個等價的引數控制錯誤率,就沒有使用C,為什麼我們nuSVR仍然有這個引數呢,不是重複了嗎?這裡的原因在迴歸模型裡面,我們除了懲罰係數C還有還有一個距離誤差ϵ來控制損失度量,因此僅僅一個nu不能等同於C.也就是說迴歸錯誤率是懲罰係數C和距離誤差ϵ共同作用的結果。
    2)nu:
    LinearSVR 和SVR沒有這個引數,用ϵ控制錯誤率;對於SVR和NuSVR,nu代表訓練集訓練的錯誤率的上限,或者說支援向量的百分比下限,取值範圍為(0,1],預設是0.5.通過選擇不同的錯誤率可以得到不同的距離誤差ϵ。也就是說這裡的nu的使用和LinearSVR 和SVR的ϵ引數等價。
    3)距離誤差epsilon:
    對於LinearSVR和SVR,即我們第二節迴歸模型中的ϵ,訓練集中的樣本需滿足
    −ϵ− ξ∨i ≤yi−w∙ϕ(xi)−b≤ ϵ+ ξ∧i 。nuSVR沒有這個引數,用nu控制錯誤率。
    4)損失函式度量loss:
    對於LinearSVC,可以選擇為‘epsilon_insensitive’ 和 ‘squared_epsilon_insensitive’ ,如果選擇‘epsilon_insensitive’ ,則損失度量滿足−ϵ− ξ∨i ≤yi−w∙ϕ(xi)−b≤ϵ+ξ∧i即和第二節的損失度量一樣。是預設的SVM迴歸的損失度量標準形式。如果選擇為 ‘squared_epsilon_insensitive’ , 則損失度量滿足(yi−w∙ϕ(xi)−b)2≤ϵ+ξi,此時可見會少一個鬆弛係數。其優化過程我們在SVM原理系列裡沒有講,但是目標函式優化過程是完全相似的。一般用預設的‘epsilon_insensitive’就足夠了。

  5. SVM演算法庫其他調參
    1)一般推薦在做訓練之前對資料進行歸一化,當然測試集中的資料也需要歸一化。
    2)在特徵數非常多的情況下,或者樣本數遠小於特徵數的時候,使用線性核,效果已經很好,並且只需要選擇懲罰係數C即可。
    3)在選擇核函式時,如果線性擬合不好,一般推薦使用預設的高斯核’rbf’。這時我們主要需要對懲罰係數C和核函式引數γ,·進行艱苦的調參,通過多輪的交叉驗證選擇合適的懲罰係數C和核函式引數γ。
    4)理論上高斯核不會比線性核差,但是這個理論卻建立在要花費更多的時間來調參上。所以實際上能用線性核解決問題我們儘量使用線性核。