scikit-learn 支持向量機算法庫使用小結


    之前通過一個系列對支持向量機(以下簡稱SVM)算法的原理做了一個總結,本文從實踐的角度對scikit-learn SVM算法庫的使用做一個小結。scikit-learn SVM算法庫封裝了libsvm 和 liblinear 的實現,僅僅重寫了算法了接口部分。

1. scikit-learn SVM算法庫使用概述

    scikit-learn中SVM的算法庫分為兩類,一類是分類的算法庫,包括SVC, NuSVC,和LinearSVC 3個類。另一類是回歸算法庫,包括SVR, NuSVR,和LinearSVR 3個類。相關的類都包裹在sklearn.svm模塊之中。

    對於SVC, NuSVC,和LinearSVC 3個分類的類,SVC和 NuSVC差不多,區別僅僅在於對損失的度量方式不同,而LinearSVC從名字就可以看出,他是線性分類,也就是不支持各種低維到高維的核函數,僅僅支持線性核函數,對線性不可分的數據不能使用。

    同樣的,對於SVR, NuSVR,和LinearSVR 3個回歸的類, SVR和NuSVR差不多,區別也僅僅在於對損失的度量方式不同。LinearSVR是線性回歸,只能使用線性核函數。

    我們使用這些類的時候,如果有經驗知道數據是線性可以擬合的,那么使用LinearSVC去分類 或者LinearSVR去回歸,它們不需要我們去慢慢的調參去選擇各種核函數以及對應參數, 速度也快。如果我們對數據分布沒有什么經驗,一般使用SVC去分類或者SVR去回歸,這就需要我們選擇核函數以及對核函數調參了。

    什么特殊場景需要使用NuSVC分類 和 NuSVR 回歸呢?如果我們對訓練集訓練的錯誤率或者說支持向量的百分比有要求的時候,可以選擇NuSVC分類 和 NuSVR 。它們有一個參數來控制這個百分比。

    這些類的詳細使用方法我們在下面再詳細講述。

2. 回顧SVM分類算法和回歸算法

    我們先簡要回顧下SVM分類算法和回歸算法,因為這里面有些參數對應於算法庫的參數,如果不先復習下,下面對參數的講述可能會有些難以理解。

    對於SVM分類算法,其原始形式是:$$min\;\; \frac{1}{2}||w||_2^2 +C\sum\limits_{i=1}^{m}\xi_i $$ $$ s.t.  \;\; y_i(w \bullet \phi(x_i) + b)  \geq 1 - \xi_i \;\;(i =1,2,...m)$$ $$\xi_i \geq 0 \;\;(i =1,2,...m)$$

    其中m為樣本個數,我們的樣本為$(x_1,y_1),(x_2,y_2),...,(x_m,y_m)$。$w,b$是我們的分離超平面的$w \bullet \phi(x_i) + b = 0$系數, $\xi_i $為第i個樣本的松弛系數, C為懲罰系數。$\phi(x_i)$為低維到高維的映射函數。

    通過拉格朗日函數以及對偶化后的形式為:$$ \underbrace{ min }_{\alpha}  \frac{1}{2}\sum\limits_{i=1,j=1}^{m}\alpha_i\alpha_jy_iy_jK(x_i,x_j) - \sum\limits_{i=1}^{m}\alpha_i $$ $$ s.t. \; \sum\limits_{i=1}^{m}\alpha_iy_i = 0 $$ $$0 \leq \alpha_i \leq C$$

    其中和原始形式不同的$\alpha$為拉格朗日系數向量。$K(x_i,x_j) $為我們要使用的核函數。

 

    對於SVM回歸算法,其原始形式是:$$min\;\; \frac{1}{2}||w||_2^2 + C\sum\limits_{i=1}^{m}(\xi_i^{\lor}+ \xi_i^{\land}) $$ $$s.t. \;\;\; -\epsilon - \xi_i^{\lor} \leq y_i - w \bullet \phi(x_i ) -b \leq \epsilon + \xi_i^{\land}$$ $$\xi_i^{\lor} \geq 0, \;\; \xi_i^{\land} \geq 0 \;(i = 1,2,..., m)$$

    其中m為樣本個數,我們的樣本為$(x_1,y_1),(x_2,y_2),...,(x_m,y_m)$。$w,b$是我們的回歸超平面的$w \bullet x_i + b = 0$系數, $\xi_i^{\lor}, \xi_i^{\land}$為第i個樣本的松弛系數, C為懲罰系數,$\epsilon$為損失邊界,到超平面距離小於$\epsilon$的訓練集的點沒有損失。$\phi(x_i)$為低維到高維的映射函數。

    通過拉格朗日函數以及對偶化后的形式為:$$ \underbrace{ min}_{\alpha^{\lor}, \alpha^{\land}}\; \frac{1}{2}\sum\limits_{i=1,j=1}^{m}(\alpha_i^{\land} - \alpha_i^{\lor})(\alpha_j^{\land} - \alpha_j^{\lor})K(x_i,x_j) - \sum\limits_{i=1}^{m}(\epsilon-y_i)\alpha_i^{\land}+ (\epsilon+y_i)\alpha_i^{\lor}  $$ $$ s.t. \; \sum\limits_{i=1}^{m}(\alpha_i^{\land} - \alpha_i^{\lor}) = 0 $$ $$ 0 < \alpha_i^{\lor} < C \; (i =1,2,...m)$$ $$ 0 < \alpha_i^{\land} < C \; (i =1,2,...m)$$

    其中和原始形式不同的$\alpha^{\lor}, \alpha^{\land}$為拉格朗日系數向量。$K(x_i,x_j) $為我們要使用的核函數。

3. SVM核函數概述

    在scikit-learn中,內置的核函數一共有4種,當然如果你認為線性核函數不算核函數的話,那就只有三種。

    1)線性核函數(Linear Kernel)表達式為:$K(x, z) = x \bullet z $,就是普通的內積,LinearSVC 和 LinearSVR 只能使用它。

    2)  多項式核函數(Polynomial Kernel)是線性不可分SVM常用的核函數之一,表達式為:$K(x, z) = (\gamma x \bullet z  + r)^d$ ,其中,$\gamma, r, d$都需要自己調參定義,比較麻煩。

    3)高斯核函數(Gaussian Kernel),在SVM中也稱為徑向基核函數(Radial Basis Function,RBF),它是libsvm默認的核函數,當然也是scikit-learn默認的核函數。表達式為:$K(x, z) = exp(-\gamma||x-z||^2)$, 其中,$\gamma$大於0,需要自己調參定義。

    4)Sigmoid核函數(Sigmoid Kernel)也是線性不可分SVM常用的核函數之一,表達式為:$K(x, z) = tanh(\gamma x \bullet z  + r)$, 其中,$\gamma, r$都需要自己調參定義。

    一般情況下,對非線性數據使用默認的高斯核函數會有比較好的效果,如果你不是SVM調參高手的話,建議使用高斯核來做數據分析。  

4. SVM分類算法庫參數小結

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

參數 LinearSVC  SVC NuSVC
懲罰系數C 即為我們第二節中SVM分類模型原型形式和對偶形式中的懲罰系數C,默認為1,一般需要通過交叉驗證來選擇一個合適的C。一般來說,如果噪音點較多時,C需要小一些。 NuSVC沒有這個參數, 它通過另一個參數nu來控制訓練集訓練的錯誤率,等價於選擇了一個C,讓訓練集訓練后滿足一個確定的錯誤率
nu LinearSVC 和SVC沒有這個參數,LinearSVC 和SVC使用懲罰系數C來控制懲罰力度。  nu代表訓練集訓練的錯誤率的上限,或者說支持向量的百分比下限,取值范圍為(0,1],默認是0.5.它和懲罰系數C類似,都可以控制懲罰的力度。
核函數 kernel LinearSVC沒有這個參數,LinearSVC限制了只能使用線性核函數

核函數有四種內置選擇,第三節已經講到:‘linear’即線性核函數, ‘poly’即多項式核函數, ‘rbf’即高斯核函數, ‘sigmoid’即sigmoid核函數。如果選擇了這些核函數, 對應的核函數參數在后面有單獨的參數需要調。默認是高斯核'rbf'。

還有一種選擇為"precomputed",即我們預先計算出所有的訓練集和測試集的樣本對應的Gram矩陣,這樣$K(x,z)$直接在對應的Gram矩陣中找對應的位置的值。

當然我們也可以自定義核函數, 由於我沒有用過自定義核函數,這里就不多講了。

正則化參數penalty  僅僅對線性擬合有意義,可以選擇‘l1’即L1正則化 或者 ‘l2’即L2正則化。默認是L2正則化,如果我們需要產生稀疏話的系數的時候,可以選L1正則化,這和線性回歸里面的Lasso回歸類似。 SVC和NuSVC沒有這個參數
是否用對偶形式優化dual  這是一個布爾變量,控制是否使用對偶形式來優化算法,默認是True,即采用上面第二節的分類算法對偶形式來優化算法。如果我們的樣本量比特征數多,此時采用對偶形式計算量較大,推薦dual設置為False,即采用原始形式優化 SVC和NuSVC沒有這個參數  
核函數參數degree  LinearSVC沒有這個參數,LinearSVC限制了只能使用線性核函數 如果我們在kernel參數使用了多項式核函數 'poly',那么我們就需要對這個參數進行調參。這個參數對應$K(x, z) = (\gamma x \bullet z  + r)^d$中的$d$。默認是3。一般需要通過交叉驗證選擇一組合適的$\gamma, r, d$
核函數參數gamma    LinearSVC沒有這個參數,LinearSVC限制了只能使用線性核函數

如果我們在kernel參數使用了多項式核函數 'poly',高斯核函數‘rbf’, 或者sigmoid核函數,那么我們就需要對這個參數進行調參。

多項式核函數中這個參數對應$K(x, z) = (\gamma x \bullet z  + r)^d$中的$\gamma$。一般需要通過交叉驗證選擇一組合適的$\gamma, r, d$ 

高斯核函數中這個參數對應$K(x, z) = exp(-\gamma||x-z||^2)$中的$\gamma$。一般需要通過交叉驗證選擇合適的$\gamma$

sigmoid核函數中這個參數對應$K(x, z) = tanh(\gamma x \bullet z  + r)$中的$\gamma$。一般需要通過交叉驗證選擇一組合適的$\gamma, r$ 

$\gamma$默認為'auto',即$\frac{1}{特征維度}$

 核函數參數coef0  LinearSVC沒有這個參數,LinearSVC限制了只能使用線性核函數  

如果我們在kernel參數使用了多項式核函數 'poly',或者sigmoid核函數,那么我們就需要對這個參數進行調參。

多項式核函數中這個參數對應$K(x, z) = (\gamma x \bullet z  + r)^d$中的$r$。一般需要通過交叉驗證選擇一組合適的$\gamma, r, d$ 

sigmoid核函數中這個參數對應$K(x, z) = tanh(\gamma x \bullet z  + r)$中的$r$。一般需要通過交叉驗證選擇一組合適的$\gamma, r$ 

coef0默認為0

 
 樣本權重class_weight  指定樣本各類別的的權重,主要是為了防止訓練集某些類別的樣本過多,導致訓練的決策過於偏向這些類別。這里可以自己指定各個樣本的權重,或者用“balanced”,如果使用“balanced”,則算法會自己計算權重,樣本量少的類別所對應的樣本權重會高。當然,如果你的樣本類別分布沒有明顯的偏倚,則可以不管這個參數,選擇默認的"None"
分類決策decision_function_shape  LinearSVC沒有這個參數,使用multi_class參數替代。 可以選擇'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

可以選擇 ‘ovr’ 或者 ‘crammer_singer’ 

‘ovr’和SVC和nuSVC中的decision_function_shape對應的‘ovr’類似。

'crammer_singer'是一種改良版的'ovr',說是改良,但是沒有比’ovr‘好,一般在應用中都不建議使用。

SVC和nuSVC沒有這個參數,使用decision_function_shape參數替代。 
緩存大小cache_size

LinearSVC計算量不大,因此不需要這個參數

在大樣本的時候,緩存大小會影響訓練速度,因此如果機器內存大,推薦用500MB甚至1000MB。默認是200,即200MB.

 5. SVM回歸算法庫參數小結

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

參數 LinearSVR SVR nuSVR
懲罰系數C 即為我們第二節中SVM分類模型原型形式和對偶形式中的懲罰系數C,默認為1,一般需要通過交叉驗證來選擇一個合適的C。一般來說,如果噪音點較多時,C需要小一些。大家可能注意到在分類模型里面,nuSVC使用了nu這個等價的參數控制錯誤率,就沒有使用C,為什么我們nuSVR仍然有這個參數呢,不是重復了嗎?這里的原因在回歸模型里面,我們除了懲罰系數C還有還有一個距離誤差$\epsilon$來控制損失度量,因此僅僅一個nu不能等同於C.也就是說回歸錯誤率是懲罰系數C和距離誤差$\epsilon$共同作用的結果。后面我們可以看到nuSVR中nu的作用。
nu LinearSVR 和SVR沒有這個參數,用$\epsilon$控制錯誤率 nu代表訓練集訓練的錯誤率的上限,或者說支持向量的百分比下限,取值范圍為(0,1],默認是0.5.通過選擇不同的錯誤率可以得到不同的距離誤差$\epsilon$。也就是說這里的nu的使用和LinearSVR 和SVR的$\epsilon$參數等價。
距離誤差epsilon 即我們第二節回歸模型中的$\epsilon$,訓練集中的樣本需滿足$-\epsilon - \xi_i^{\lor} \leq y_i - w \bullet \phi(x_i ) -b \leq \epsilon + \xi_i^{\land}$ nuSVR沒有這個參數,用nu控制錯誤率
是否用對偶形式優化dual   和SVC類似,可參考上一節的dual描述 SVR和NuSVR沒有這個參數
正則化參數penalty   和SVC類似,可參考上一節的penalty 描述 SVR和NuSVR沒有這個參數  
核函數 kernel LinearSVR沒有這個參數,LinearSVR限制了只能使用線性核函數 和SVC, nuSVC類似,可參考上一節的kernel描述
核函數參數degree, gamma 和coef0 LinearSVR沒有這些參數,LinearSVR限制了只能使用線性核函數 和SVC, nuSVC類似,可參考上一節的kernel參數描述
損失函數度量loss

可以選擇為‘epsilon_insensitive’ 和 ‘squared_epsilon_insensitive’ ,如果選擇‘epsilon_insensitive’ ,則損失度量滿足$-\epsilon - \xi_i^{\lor} \leq y_i - w \bullet \phi(x_i ) -b \leq \epsilon + \xi_i^{\land}$,即和第二節的損失度量一樣。是默認的SVM回歸的損失度量標准形式。

如果選擇為 ‘squared_epsilon_insensitive’ , 則損失度量滿足$ (y_i - w \bullet \phi(x_i ) -b)^2 \leq \epsilon + \xi_i$,此時可見會少一個松弛系數。其優化過程我們在SVM原理系列里沒有講,但是目標函數優化過程是完全相似的。

一般用默認的‘epsilon_insensitive’就足夠了。

SVR和NuSVR沒有這個參數
緩存大小cache_size

LinearSVC計算量不大,因此不需要這個參數

在大樣本的時候,緩存大小會影響訓練速度,因此如果機器內存大,和SVC,nuSVC一樣,推薦用500MB甚至1000MB。默認是200,即200MB.

6. SVM算法庫其他調參要點

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

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

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

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

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

    

(歡迎轉載,轉載請注明出處。歡迎溝通交流: liujianping-ok@163.com)   


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM