在支持向量機(如下簡稱SVM)的核函數中,高斯核(如下簡稱RBF)是最經常使用的,從理論上講, RBF必定不比線性核函數差,可是在實際應用中,卻面臨着幾個重要的超參數的調優問題。若是調的很差,可能比線性核函數還要差。因此咱們實際應用中,能用線性核函數獲得較好效果的都會選擇線性核函數。若是線性核很差,咱們就須要使用RBF,在享受RBF對非線性數據的良好分類效果前,咱們須要對主要的超參數進行選取。本文咱們就對scikit-learn中 SVM RBF的調參作一個小結。python
若是是SVM分類模型,這兩個超參數分別是懲罰係數\(C\)和RBF核函數的係數\(\gamma\)。固然若是是nu-SVC的話,懲罰係數\(C\)代替爲分類錯誤率上限nu, 因爲懲罰係數\(C\)和分類錯誤率上限nu起的做用等價,所以本文只討論帶懲罰係數C的分類SVM。git
懲罰係數\(C\)即咱們在以前原理篇裏講到的鬆弛變量的係數。它在優化函數裏主要是平衡支持向量的複雜度和誤分類率這二者之間的關係,能夠理解爲正則化係數。當\(C\)比較大時,咱們的損失函數也會越大,這意味着咱們不肯意放棄比較遠的離羣點。這樣咱們會有更加多的支持向量,也就是說支持向量和超平面的模型也會變得越複雜,也容易過擬合。反之,當\(C\)比較小時,意味咱們不想理那些離羣點,會選擇較少的樣原本作支持向量,最終的支持向量和超平面的模型也會簡單。scikit-learn中默認值是1。github
另外一個超參數是RBF核函數的參數\(\gamma\)。回憶下RBF 核函數\(K(x, z) = exp(-\gamma||x-z||^2)\;\;\gamma>;0\),\(\gamma\)主要定義了單個樣本對整個分類超平面的影響,當\(\gamma\)比較小時,單個樣本對整個分類超平面的影響比較小,不容易被選擇爲支持向量,反之,當\(\gamma\)比較大時,單個樣本對整個分類超平面的影響比較大,更容易被選擇爲支持向量,或者說整個模型的支持向量也會多。scikit-learn中默認值是\(\frac{1}{樣本特徵數}\)數組
若是把懲罰係數\(C\)和RBF核函數的係數\(\gamma\)一塊兒看,當\(C\)比較大, \(\gamma\)比較大時,咱們會有更多的支持向量,咱們的模型會比較複雜,容易過擬合一些。若是\(C\)比較小 , \(\gamma\)比較小時,模型會變得簡單,支持向量的個數會少。微信
以上是SVM分類模型,咱們再來看看回歸模型。dom
SVM迴歸模型的RBF核比分類模型要複雜一點,由於此時咱們除了懲罰係數\(C\)和RBF核函數的係數\(\gamma\)以外,還多了一個損失距離度量\(\epsilon\)。若是是nu-SVR的話,損失距離度量\(\epsilon\)代替爲分類錯誤率上限nu,因爲損失距離度量\(\epsilon\)和分類錯誤率上限nu起的做用等價,所以本文只討論帶距離度量\(\epsilon\)的迴歸SVM。函數
對於懲罰係數\(C\)和RBF核函數的係數\(\gamma\),迴歸模型和分類模型的做用基本相同。對於損失距離度量\(\epsilon\),它決定了樣本點到超平面的距離損失,當\(\epsilon\)比較大時,損失\(|y_i - w \bullet \phi(x_i ) -b| - \epsilon\)較小,更多的點在損失距離範圍以內,而沒有損失,模型較簡單,而當\(\epsilon\)比較小時,損失函數會較大,模型也會變得複雜。scikit-learn中默認值是0.1。優化
若是把懲罰係數\(C\),RBF核函數的係數\(\gamma\)和損失距離度量\(\epsilon\)一塊兒看,當\(C\)比較大, \(\gamma\)比較大,\(\epsilon\)比較小時,咱們會有更多的支持向量,咱們的模型會比較複雜,容易過擬合一些。若是\(C\)比較小 , \(\gamma\)比較小,\(\epsilon\)比較大時,模型會變得簡單,支持向量的個數會少。spa
對於SVM的RBF核,咱們主要的調參方法都是交叉驗證。具體在scikit-learn中,主要是使用網格搜索,即GridSearchCV類。固然也可使用cross_val_score類來調參,可是我的以爲沒有GridSearchCV方便。本文咱們只討論用GridSearchCV來進行SVM的RBF核的調參。code
咱們將GridSearchCV類用於SVM RBF調參時要注意的參數有:
1) estimator :即咱們的模型,此處咱們就是帶高斯核的SVC或者SVR
2) param_grid:即咱們要調參的參數列表。 好比咱們用SVC分類模型的話,那麼param_grid能夠定義爲{"C":[0.1, 1, 10], "gamma": [0.1, 0.2, 0.3]},這樣咱們就會有9種超參數的組合來進行網格搜索,選擇一個擬合分數最好的超平面係數。
3) cv: S折交叉驗證的折數,即將訓練集分紅多少份來進行交叉驗證。默認是3,。若是樣本較多的話,能夠適度增大cv的值。
網格搜索結束後,咱們能夠獲得最好的模型estimator, param_grid中最好的參數組合,最好的模型分數。
下面我用一個具體的分類例子來觀察SVM RBF調參的過程
這裏咱們用一個實例來說解SVM RBF分類調參。推薦在ipython notebook運行下面的例子。
完整代碼參看個人github:https://github.com/nickchen121/machinelearning/blob/master/classic-machine-learning/svm_classifier.ipynb
首先咱們載入一些類的定義。
import numpy as np import matplotlib.pyplot as plt from sklearn import datasets, svm from sklearn.svm import SVC from sklearn.datasets import make_moons, make_circles, make_classification %matplotlib inline
接着咱們生成一些隨機數據來讓咱們後面去分類,爲了數據難一點,咱們加入了一些噪音。生成數據的同時把數據歸一化
X, y = make_circles(noise=0.2, factor=0.5, random_state=1); from sklearn.preprocessing import StandardScaler X = StandardScaler().fit_transform(X)
咱們先看看個人數據是什麼樣子的,這裏作一次可視化以下:
from matplotlib.colors import ListedColormap cm = plt.cm.RdBu cm_bright = ListedColormap(['#FF0000', '#0000FF']) ax = plt.subplot() ax.set_title("Input data") # Plot the training points ax.scatter(X[:, 0], X[:, 1], c=y, cmap=cm_bright) ax.set_xticks(()) ax.set_yticks(()) plt.tight_layout() plt.show()
生成的圖以下, 因爲是隨機生成的因此若是你跑這段代碼,生成的圖可能有些不一樣。
好了,如今咱們要對這個數據集進行SVM RBF分類了,分類時咱們使用了網格搜索,在C=(0.1,1,10)和gamma=(1, 0.1, 0.01)造成的9種狀況中選擇最好的超參數,咱們用了4折交叉驗證。這裏只是一個例子,實際運用中,你可能須要更多的參數組合來進行調參。
from sklearn.model_selection import GridSearchCV grid = GridSearchCV(SVC(), param_grid={"C":[0.1, 1, 10], "gamma": [1, 0.1, 0.01]}, cv=4) grid.fit(X, y) print("The best parameters are %s with a score of %0.2f" % (grid.best_params_, grid.best_score_))
最終的輸出以下:
The best parameters are {'C': 10, 'gamma': 0.1} with a score of 0.91
也就是說,經過網格搜索,在咱們給定的9組超參數中,C=10, Gamma=0.1 分數最高,這就是咱們最終的參數候選。
到這裏,咱們的調參舉例就結束了。不過咱們能夠看看咱們的普通的SVM分類後的可視化。這裏咱們把這9種組合各個訓練後,經過對網格里的點預測來標色,觀察分類的效果圖。代碼以下:
x_min, x_max = X[:, 0].min() - 1, X[:, 0].max() + 1 y_min, y_max = X[:, 1].min() - 1, X[:, 1].max() + 1 xx, yy = np.meshgrid(np.arange(x_min, x_max,0.02), np.arange(y_min, y_max, 0.02)) for i, C in enumerate((0.1, 1, 10)): for j, gamma in enumerate((1, 0.1, 0.01)): plt.subplot() clf = SVC(C=C, gamma=gamma) clf.fit(X,y) Z = clf.predict(np.c_[xx.ravel(), yy.ravel()]) # Put the result into a color plot Z = Z.reshape(xx.shape) plt.contourf(xx, yy, Z, cmap=plt.cm.coolwarm, alpha=0.8) # Plot also the training points plt.scatter(X[:, 0], X[:, 1], c=y, cmap=plt.cm.coolwarm) plt.xlim(xx.min(), xx.max()) plt.ylim(yy.min(), yy.max()) plt.xticks(()) plt.yticks(()) plt.xlabel(" gamma=" + str(gamma) + " C=" + str(C)) plt.show()
生成的9個組合的效果圖以下:
以上就是SVM RBF調參的一些總結,但願能夠幫到朋友們。
(歡迎轉載,轉載請註明出處。歡迎溝通交流: 微信:nickchen121)