以前經過一個系列對支持向量機(如下簡稱SVM)算法的原理作了一個總結,本文從實踐的角度對scikit-learn SVM算法庫的使用作一個小結。scikit-learn SVM算法庫封裝了libsvm 和 liblinear 的實現,僅僅重寫了算法了接口部分。javascript
1、1. scikit-learn SVM算法庫使用概述
scikit-learn中SVM的算法庫分爲兩類,一類是分類的算法庫,包括SVC, NuSVC,和LinearSVC 3個類。另外一類是迴歸算法庫,包括SVR, NuSVR,和LinearSVR 3個類。相關的類都包裹在sklearn.svm模塊之中。css
對於SVC, NuSVC,和LinearSVC 3個分類的類,SVC和 NuSVC差很少,區別僅僅在於對損失的度量方式不一樣,而LinearSVC從名字就能夠看出,他是線性分類,也就是不支持各類低維到高維的核函數,僅僅支持線性核函數,對線性不可分的數據不能使用。html
一樣的,對於SVR, NuSVR,和LinearSVR 3個迴歸的類, SVR和NuSVR差很少,區別也僅僅在於對損失的度量方式不一樣。LinearSVR是線性迴歸,只能使用線性核函數。java
咱們使用這些類的時候,若是有經驗知道數據是線性能夠擬合的,那麼使用LinearSVC去分類 或者LinearSVR去迴歸,它們不須要咱們去慢慢的調參去選擇各類核函數以及對應參數, 速度也快。若是咱們對數據分佈沒有什麼經驗,通常使用SVC去分類或者SVR去迴歸,這就須要咱們選擇核函數以及對核函數調參了。python
什麼特殊場景須要使用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) \]markdown
\[ \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、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、6. SVM算法庫其餘調參要點 上面已經對scikit-learn中類庫的參數作了總結,這裏對其餘的調參要點作一個小結。 1)通常推薦在作訓練以前對數據進行歸一化,固然測試集中的數據也須要歸一化。。 2)在特徵數很是多的狀況下,或者樣本數遠小於特徵數的時候,使用線性核,效果已經很好,而且只須要選擇懲罰係數C便可。 3)在選擇核函數時,若是線性擬合很差,通常推薦使用默認的高斯核'rbf'。這時咱們主要須要對懲罰係數C和核函數參數\(\gamma\)進行艱苦的調參,經過多輪的交叉驗證選擇合適的懲罰係數C和核函數參數\(\gamma\)。 4)理論上高斯核不會比線性核差,可是這個理論卻創建在要花費更多的時間來調參上。因此實際上能用線性核解決問題咱們儘可能使用線性核。 (歡迎轉載,轉載請註明出處。歡迎溝通交流: 微信:nickchen121)
posted @
2019-07-19 17:51
十七歲的有德 閱讀(
...) 評論(
)
編輯
收藏
|
|