sklearn中的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 。它們有一個參數來控制這個百分比。
    
  下面主要討論LinearSVC與SVC。

svm.LinearSVC

class sklearn.svm.LinearSVC(penalty='l2', loss='squared_hinge', dual=True, tol=0.0001, C=1.0, multi_class='ovr', fit_intercept=True, intercept_scaling=1, class_weight=None, verbose=0, random_state=None, max_iter=1000)

主要超參數

  • C:目標函數的懲罰系數C,用來平衡分類間隔margin和錯分樣本的,default C = 1.0; 一般來說,如果噪音點較多時,C需要小一些。
  • loss :指定損失函數 .有‘hinge’和‘squared_hinge’兩種可選,前者又稱L1損失,后者稱為L2損失,默認是是’squared_hinge’,其中hinge是SVM的標准損失,squared_hinge是hinge的平方。
  • penalty : 僅僅對線性擬合有意義,可以選擇‘l1’即L1正則化 或者 ‘l2’即L2正則化。默認是L2正則化,如果我們需要產生稀疏話的系數的時候,可以選L1正則化,這和線性回歸里面的Lasso回歸類似。
  • dual :選擇算法來解決對偶或原始優化問題。如果我們的樣本量比特征數多,此時采用對偶形式計算量較大,推薦dual設置為False,即采用原始形式優化
  • tol :(default = 1e - 3): svm結束標准的精度;
  • multi_class:如果y輸出類別包含多類,用來確定多類策略, ovr表示一對多,“crammer_singer”優化所有類別的一個共同的目標 .'crammer_singer'是一種改良版的'ovr',說是改良,但是沒有比’ovr‘好,一般在應用中都不建議使用。如果選擇“crammer_singer”,損失、懲罰和優化將會被被忽略。 'ovr'的分類原則是將待分類中的某一類當作正類,其他全部歸為負類,通過這樣求取得到每個類別作為正類時的正確率,取正確率最高的那個類別為正類;‘crammer_singer’ 是直接針對目標函數設置多個參數值,最后進行優化,得到不同類別的參數值大小。
  • class_weight :指定樣本各類別的的權重,主要是為了防止訓練集某些類別的樣本過多,導致訓練的決策過於偏向這些類別。這里可以自己指定各個樣本的權重,或者用“balanced”,如果使用“balanced”,則算法會自己計算權重,樣本量少的類別所對應的樣本權重會高。當然,如果你的樣本類別分布沒有明顯的偏倚,則可以不管這個參數,選擇默認的"None"
  • verbose:跟多線程有關

svm.SVC

class sklearn.svm.SVC(C=1.0, kernel='rbf', degree=3, gamma='auto', coef0=0.0, shrinking=True, probability=False, tol=0.001, cache_size=200, class_weight=None, verbose=False, max_iter=-1, decision_function_shape='ovr', random_state=None)

主要超參數

  • C: 同LinearSVC
  • kernel:參數選擇有RBF, Linear, Poly, Sigmoid, 默認的是”RBF”; ‘linear’即線性核函數, ‘poly’即多項式核函數, ‘rbf’即高斯核函數, ‘sigmoid’即sigmoid核函數。如果選擇了這些核函數, 對應的核函數參數在后面有單獨的參數需要調。默認是高斯核'rbf'。
  • degree:如果我們在kernel參數使用了多項式核函數 'poly',那么我們就需要對這個參數進行調參。這個參數對應 \(K(x,z)=(γx∙z+r)d\) 中的d。默認是3。一般需要通過交叉驗證選擇一組合適的γ,r,d
  • gamma:核函數的系數(‘Poly’, ‘RBF’ and ‘Sigmoid’), 默認是gamma = \(\frac{1}{特征維度}\); 如果我們在kernel參數使用了多項式核函數 'poly',高斯核函數‘rbf’, 或者sigmoid核函數,那么我們就需要對這個參數進行調參。多項式核函數中這個參數對應 \(K(x,z)=(γx∙z+r)d\) 中的γ。一般需要通過交叉驗證選擇一組合適的γ,r,d;
    高斯核函數中這個參數對應 \(K(x,z)=exp(−γ||x−z||2)\) 中的γ。一般需要通過交叉驗證選擇合適的γ
    sigmoid核函數中這個參數對應 \(K(x,z)=tanh(γx∙z+r)\) 中的γ。一般需要通過交叉驗證選擇一組合適的γ,r ;
    γ默認為'auto',即 \(\frac{1}{特征維度}\)
  • coef0:核函數中的獨立項,’RBF’ and ‘Poly’有效; coef0默認為0.如果我們在kernel參數使用了多項式核函數 'poly',或者sigmoid核函數,那么我們就需要對這個參數進行調參。
    多項式核函數中這個參數對應 \(K(x,z)=(γx∙z+r)d\) 中的r。一般需要通過交叉驗證選擇一組合適的γ,r,d;
    sigmoid核函數中這個參數對應 \(K(x,z)=tanh(γx∙z+r)\) 中的r。一般需要通過交叉驗證選擇一組合適的γ,r;
  • probablity: 可能性估計是否使用(true or false);
  • shrinking:是否進行啟發式;
  • tol(default = 1e - 3): svm結束標准的精度;
  • cache_size: 制定訓練所需要的內存(以MB為單位); 在大樣本的時候,緩存大小會影響訓練速度,因此如果機器內存大,推薦用500MB甚至1000MB。默認是200,即200MB.
  • class_weight: 同LinearSVC
  • verbose: 同LinearSVC
  • max_iter: 最大迭代次數,default = 1, if max_iter = -1, no limited;
  • decision_function_shape : ‘ovo’ 一對一, ‘ovr’ 多對多 or None 無, default=None
  • random_state :用於概率估計的數據重排時的偽隨機數生成器的種子。

調參建議

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

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

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

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

  5. degree越大,分類器越靈活。太大會出現過擬合

常見問題

  1. Q:C對線性核的SVM有多大影響?
    A:C參數告訴SVM模型,你有多希望避免對每個訓練樣本的錯誤分類。對於較大的C值,如果超平面能夠更好地獲得正確分類所有樣本點,那么該模型將選擇一個更小的間隔超平面。相反,較小的C值將導致模型尋找更大分隔的超平面,即使這個超平面錯誤地划分了很多的點。C越大,越要盡可能的考慮錯誤點(也就是說,盡量不要分錯),導致的結果是,誤分類盡可能越小,但分界距離也變小了。壞處很明顯,若干錯誤的“離群點”會對分界面的位置方向影響很大。
    在支持向量機中,你的目標是找到兩個東西:1)具有最大最小間隔的超平面;2)能夠正確分隔盡可能多實例的超平面。問題是你不可能同時得到這兩種東西。C參數決定了你對后者的期望有多大。下面畫了一個小例子來說明這一點。左邊是一個很低的C,這就得到了一個很大的最小間隔(紫色)。然而,這要求我們忽略未能正確分類的藍色圓離群值。右邊是C較高時的情況,你不會忽視離群值,最終得到一個更小的間隔。

    那么哪一個分類器是更好的呢?這取決於你預測的數據是什么樣子的,當然大多數情況下你並不知道。如果數據是這樣的:

    那么適當跳大C是更好的選擇。如果你的數據是這樣的:

    那么使用較小的C會好一些。

  2. Q:LinearSVC與使用線性核的SVC的區別
    A:sklearn把LinearSVC叫做SVM,而實際上LinearSVC的目標是最小化合頁損失的平方(一個超參),而不僅僅是合頁損失。此外,LinearSVC還引入了懲罰正則項,這是純SVM沒有的。所以不能說LinearSVC就是線性核的SVC。那么用哪一個呢?這還是得具體問題具體分析。由於沒有免費午餐定理,所以不能說哪個損失函數是最好的。

  3. Q:使用LinearSVC時,為何調整了參數C后,分類的效果沒有明顯的變化?
    A:首先明確兩個重要的事實。1)你用的是線性核;2)您的訓練數據是線性可分的,“訓練集上沒有錯誤”。
    有了這兩個事實,如果C值在合理范圍內發生變化,最優超平面會在由支持向量形成的間隔內移動。直觀上,假設訓練數據的間隔較小,且間隔內也沒有測試數據點,則在間隔內的最優超平面的偏移不會影響測試集的分類誤差。
    盡管如此,如果你設置C=0,那么SVM就會忽略這些錯誤,只嘗試最小化權值(w)的平方和,也許你會在測試集中得到不同的結果。

  4. Q:我們該使用哪種核函數?
    A:和數據相關。 可以嘗試。嘗試順序一般:先線性核,然后再看通過使用非線性核能否提高。通常,如果數據是高維的,但只有很少的訓練樣本數,非線性核會導致過擬合。
    除此之外,感興趣的還可以參考這個:https://stats.stackexchange.com/questions/18030/how-to-select-kernel-for-svm?rq=1

Reference


免責聲明!

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



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