1. 程式人生 > >機器學習之支援向量機SVM Support Vector Machine (五) scikit-learn演算法庫

機器學習之支援向量機SVM Support Vector Machine (五) scikit-learn演算法庫

一、scikit-learn SVM演算法庫概述

        scikit-learn中SVM的演算法庫分為兩類,一類是分類演算法庫,包括SVC、 NuSVC和LinearSVC三個類。另一類是迴歸演算法庫,包括SVR、NuSVR和LinearSVR三個類。相關的類都包裹在sklearn.svm模組之中。
        對於SVC、NuSVC和LinearSVC三個分類類,SVC和 NuSVC差不多,區別僅僅在於對損失的度量方式不同,而LinearSVC從名字就可以看出,是線性分類,也就是不支援各種低維到高維的核函式,僅僅支援線性核函式,對線性不可分的資料不能使用。
        同樣的,對於SVR、 NuSVR和LinearSVR三個迴歸類, SVR和NuSVR差不多,區別也僅僅在於對損失的度量方式不同。LinearSVR是線性迴歸,只能使用線性核函式。
        使用這些類的時候,如果有經驗知道資料是線性可以擬合的,那麼使用LinearSVC去分類或者LinearSVR去迴歸,它們不需要慢慢調參選擇各種核函式以及對應引數,速度快。如果對資料分佈沒有什麼經驗,一般使用SVC去分類或者SVR去迴歸,這就需要選擇核函式以及對核函式調參了。
        什麼特殊場景需要使用NuSVC分類和NuSVR迴歸呢?如果對訓練集訓練的錯誤率或者支援向量的百分比有要求時,可以選擇NuSVC和NuSVR 。它們有一個引數來控制這個百分比。

二、回顧SVM分類演算法和迴歸演算法

        先簡要回顧下SVM分類演算法和迴歸演算法,因為這裡面有些引數對應於演算法庫的引數。
        對於SVM分類演算法,其原始形式是:
        其中m為樣本個數,樣本為。w, b是分離超平面的係數,ξi為第i個樣本的鬆弛係數,C為懲罰係數。ϕ(xi)為低維到高維的對映函式。

        通過拉格朗日函式以及對偶化後的形式為:

        其中α為拉格朗日系數向量。K(xi,xj)為使用的核函式。

        對於SVM迴歸演算法,其原始形式是:

        其中m為樣本個數,我們的樣本為。w,b是迴歸超平面的係數,為第i個樣本的鬆弛係數,C為懲罰係數,ϵ為損失邊界,到超平面距離小於ϵ的訓練集的點沒有損失。ϕ(xi)為低維到高維的對映函式。
        通過拉格朗日函式以及對偶化後的形式為:
        其中和原始形式不同的為拉格朗日系數向量。K(xi,xj)為要使用的核函式。

三、SVM核函式概述

        在scikit-learn中,內建的核函式一共有4種,包括線性核函式。
        1)線性核函式(Linear Kernel)表示式為:,就是普通的內積,LinearSVC 和 LinearSVR只能使用它。
        2)  多項式核函式(Polynomial Kernel)是線性不可分SVM常用的核函式之一,表示式為:,其中,γ,r,d都需要自己調參定義,比較麻煩。
        3)高斯核函式(Gaussian Kernel)在SVM中也稱為徑向基核函式(Radial Basis Function, RBF),它是libsvm預設的核函式,當然也是scikit-learn預設的核函式。表示式為:
, 其中,γ大於0,需要自己調參定義。
        4)Sigmoid核函式(Sigmoid Kernel)也是線性不可分SVM常用的核函式之一,表示式為:, 其中,γ,r都需要自己調參定義。
        一般情況下,對非線性資料使用預設的高斯核函式會有比較好的效果,如果不是SVM調參高手的話,建議使用高斯核來做資料分析。

四、SVM分類演算法庫引數小結

        這裡對SVM分類演算法庫的重要引數做一個詳細的解釋,重點講述調參的一些注意點。

懲罰係數C

        LinearSVC、SVC:即為SVM分類模型原型形式和對偶形式中的懲罰係數C,預設為1,一般需要通過交叉驗證來選擇一個合適的C。一般來說,如果噪音點較多時,C需要小一些。

        NuSVC:沒有這個引數, 它通過另一個引數nu來控制訓練集訓練的錯誤率,等價於選擇了一個C,讓訓練集訓練後滿足一個確定的錯誤率。

nu

        LinearSVC 和SVC:沒有這個引數,LinearSVC 和SVC使用懲罰係數C來控制懲罰力度。

        NuSVC:nu代表訓練集訓練的錯誤率的上限,或者說支援向量的百分比下限,取值範圍為(0,1],預設是0.5。它和懲罰係數C類似,都可以控制懲罰的力度。

正則化引數penalty

        LinearSVC:僅僅對線性擬合有意義,可以選擇‘l1’即L1正則化或者‘l2’即L2正則化。預設是L2正則化,如果我們需要產生稀疏係數的時候,可以選L1正則化,這和線性迴歸裡面的Lasso迴歸類似。

        SVC和NuSVC沒有這個引數。

是否用對偶形式優化dual

        LinearSVC:這是一個布林變數,控制是否使用對偶形式來優化演算法,預設是True,採用第二節的分類演算法對偶形式來優化演算法。如果樣本量比特徵數多,此時採用對偶形式計算量較大,推薦dual設定為False,即採用原始形式優化。

        SVC和NuSVC沒有這個引數 。

核函式 kernel

        LinearSVC:沒有這個引數,LinearSVC限制了只能使用線性核函式。
        SVC和NuSVC:核函式有四種內建選擇,‘linear’即線性核函式, ‘poly’即多項式核函式, ‘rbf’即高斯核函式, ‘sigmoid’即sigmoid核函式。如果選擇了這些核函式, 對應的核函式引數在後面有單獨的引數需要調。預設是高斯核'rbf'。還有一種選擇為"precomputed",即我們預先計算出所有的訓練集和測試集的樣本對應的Gram矩陣,這樣K(x,z)直接在對應的Gram矩陣中找對應的位置的值。當然我們也可以自定義核函式, 由於我沒有用過自定義核函式,這裡就不多講了。

核函式引數degree

        LinearSVC:沒有這個引數,LinearSVC限制了只能使用線性核函式。

        SVC和NuSVC:如果在kernel引數使用了多項式核函式 'poly',那麼就需要對這個引數進行調參。這個引數對應中的d。預設是3。一般需要通過交叉驗證選擇一組合適的γ,r,d。

核函式引數gamma

        LinearSVC:沒有這個引數,LinearSVC限制了只能使用線性核函式。

        SVC和NuSVC:如果在kernel引數使用了多項式核函式 'poly',高斯核函式‘rbf’或者sigmoid核函式,那麼就需要對這個引數進行調參。γ預設為'auto',即1/特徵維度
                多項式核函式中這個引數對應中的γ。一般需要通過交叉驗證選擇一組合適的γ,r,d。
                高斯核函式中這個引數對應中的γ。一般需要通過交叉驗證選擇合適的γ。
                sigmoid核函式中這個引數對應中的γ。一般需要通過交叉驗證選擇一組合適的γ,r。 

核函式引數coef0

        LinearSVC:沒有這個引數,LinearSVC限制了只能使用線性核函式。
        SVC和NuSVC:如果在kernel引數使用了多項式核函式 'poly',或者sigmoid核函式,那麼就需要對這個引數進行調參。coef0預設為0。
                多項式核函式中這個引數對應中的r。一般需要通過交叉驗證選擇一組合適的γ,r,d 
                sigmoid核函式中這個引數對應中的r。一般需要通過交叉驗證選擇一組合適的γ,r

樣本權重class_weight

        指定樣本各類別的的權重,主要是為了防止訓練集某些類別的樣本過多,導致訓練的決策過於偏向這些類別。這裡可以自己指定各個樣本的權重,或者用“balanced”,如果使用“balanced”,則演算法會自己計算權重,樣本量少的類別所對應的樣本權重會高。當然,如果你的樣本類別分佈沒有明顯的偏倚,則可以不管這個引數,選擇預設的"None"

分類決策decision_function_shape

        LinearSVC:沒有這個引數,使用multi_class引數替代。

       SVC和NuSVC: 可以選擇'ovo'或者‘ovo’。目前0.18版本預設是'ovo'.0.19版本將是'ovr'
                OvR(one ve rest)的思想很簡單,無論多少元分類,都可以看做二元分類。具體做法是,對於第K類的分類決策,把所有第K類的樣本作為正例,除了第K類樣本以外的所有樣本都作為負例,然後在上面做二元分類,得到第K類的分類模型。其他類的分類模型獲得以此類推。
                OvO(one-vs-one)則是每次在所有的T類樣本里面選擇兩類樣本出來,不妨記為T1類和T2類,把所有的輸出為T1和T2的樣本放在一起,把T1作為正例,T2作為負例,進行二元分類,得到模型引數。一共需要T(T-1)/2次分類。
        從上面的描述可以看出OvR相對簡單,但分類效果相對略差(這裡指大多數樣本分佈情況,某些樣本分佈下OvR可能更好)。而OvO分類相對精確,但是分類速度沒有OvR快。一般建議使用OvO以達到較好的分類效果。

分類決策multi_class

        LinearSVC:可以選擇 ‘ovr’ 或者 ‘crammer_singer’ 。‘ovr’和SVC和nuSVC中的decision_function_shape對應的‘ovr’類似。'crammer_singer'是一種改良版的'ovr',說是改良,但是沒有比’ovr‘好,一般在應用中都不建議使用。
        SVC和nuSVC:沒有這個引數,使用decision_function_shape引數替代。 

快取大小cache_size

        LinearSVC:計算量不大,因此不需要這個引數
        SVC和nuSVC:在大樣本的時候,快取大小會影響訓練速度,因此如果機器記憶體大,推薦用500MB甚至1000MB。預設是200,即200MB

五、SVM迴歸演算法庫引數小結

        SVM迴歸演算法庫的重要引數大部分和分類演算法庫類似,因此這裡重點講述和分類演算法庫不同的部分,對於相同的部分可以參考上一節對應引數。

懲罰係數C

        LinearSVC、SVC和nuSVC:即為SVM分類模型原型形式和對偶形式中的懲罰係數C,預設為1,一般需要通過交叉驗證來選擇一個合適的C。一般來說,如果噪音點較多時,C需要小一些。可以注意到在分類模型裡面,nuSVC使用了nu這個等價的引數控制錯誤率,就沒有使用C,為什麼nuSVR仍然有這個引數呢,不是重複了嗎?這裡的原因在迴歸模型裡面,除了懲罰係數C還有還有一個距離誤差ϵ來控制損失度量,因此僅僅一個nu不能等同於C。也就是說分類錯誤率是懲罰係數C和距離誤差ϵ共同作用的結果。後面可以看到nuSVR中nu的作用。

nu

        LinearSVR 和SVR:沒有這個引數,用ϵ控制錯誤率

       nu代表訓練集訓練錯誤率的上限,或者說支援向量的百分比下限,取值範圍為(0,1],預設是0.5。通過選擇不同的錯誤率可以得到不同的距離誤差ϵ。也就是說這裡的nu的使用和LinearSVR 和SVR的ϵ引數等價。

距離誤差epsilon

        LinearSVR和SVR:即迴歸模型中的ϵ,訓練集中的樣本需滿足

        nuSVR:沒有這個引數,用nu控制錯誤率

是否用對偶形式優化dual

        LinearSVR:和SVC類似,可參考上一節的dual描述

        SVR和NuSVR:沒有這個引數

正則化引數penalty

        LinearSVR:和SVC類似,可參考上一節的penalty 描述

        SVR和NuSVR:沒有這個引數  

核函式 kernel

        LinearSVR:沒有這個引數,LinearSVR限制了只能使用線性核函式

        SVR和NuSVR:和SVC, nuSVC類似,可參考上一節的kernel描述

核函式引數degree, gamma 和coef0

        LinearSVR:沒有這些引數,LinearSVR限制了只能使用線性核函式

        SVR和NuSVR:和SVC, nuSVC類似,可參考上一節的kernel引數描述

損失函式度量loss

        LinearSVR:可以選擇為‘epsilon_insensitive’ 和 ‘squared_epsilon_insensitive’ ,如果選擇‘epsilon_insensitive’ ,則損失度量滿足,即和第二節的損失度量一樣。是預設的SVM迴歸的損失度量標準形式。如果選擇為 ‘squared_epsilon_insensitive’ , 則損失度量滿足,此時可見會少一個鬆弛係數。其優化過程我們在SVM原理系列裡沒有講,但是目標函式優化過程是完全相似的。一般用預設的‘epsilon_insensitive’就足夠了。
        SVR和NuSVR:沒有這個引數

快取大小cache_size

        LinearSVR:計算量不大,因此不需要這個引數
        SVR和NuSVR:在大樣本的時候,快取大小會影響訓練速度,因此如果機器記憶體大,和SVC、nuSVC一樣,推薦用500MB甚至1000MB。預設是200,即200MB.

六、SVM演算法庫其他調參要點

        上面已經對scikit-learn中類庫的引數做了總結,這裡對其他的調參要點做一個小結。

        1)一般推薦在做訓練之前對資料進行歸一化,當然測試集中的資料也需要歸一化。

        2)在特徵數非常多的情況下,或者樣本數遠小於特徵數的時候,使用線性核,效果已經很好,並且只需要選擇懲罰係數C即可。

        3)在選擇核函式時,如果線性擬合不好,一般推薦使用預設的高斯核'rbf'。這時我們主要需要對懲罰係數C和核函式引數γγ進行艱苦的調參,通過多輪的交叉驗證選擇合適的懲罰係數C和核函式引數γ。

        4)理論上高斯核不會比線性核差,但是這個理論卻建立在要花費更多的時間來調參上。所以實際上能用線性核解決問題我們儘量使用線性核。