机器学习——SVM之交叉验证对参数(C,gamma)进行优化以及选择
目錄
一、(C,gamma)簡介
二、交叉驗證
1、什么是交叉驗證?
2、參數(shù)優(yōu)化方法
3、python實現(xiàn)交叉驗證cross_val_score(網(wǎng)格搜索算法GridSearchCV)
1)關(guān)鍵代碼
2)sklearn中的cross_val_score()函數(shù)參數(shù)
3)AX3D三維繪圖
4)ravel函數(shù)
5)完整代碼
?
?
前面寫了一篇關(guān)于參數(shù)(C,gamma)的文章,但是只是從感性上去說明了一下參數(shù)對模型和結(jié)果的影響,但沒有說明如何對參數(shù)(C,gamma)進(jìn)行選擇。因此寫下這篇。
一、(C,gamma)簡介
對于SVM模型,最主要的參數(shù)就是C和gamma,C被稱為懲罰因子,越大說明對錯誤的容忍度越小,可能發(fā)生過擬合(overfitting),C太小可能會導(dǎo)致容錯率過高,這樣的模型就沒有意義了。
對于C和gamma參數(shù)的確定,一般是通過交叉驗證的方法來進(jìn)行確定的,大概思路就是將C和gamma參數(shù)在一定地取值范圍內(nèi)按照一定的步長(默認(rèn)為1)進(jìn)行取值組合,在不同(C,gamma)的組合下,將訓(xùn)練集樣本均分成k組,一組作為驗證的數(shù)據(jù)樣本,其余k-1組則用來作為訓(xùn)練的數(shù)據(jù),每一組數(shù)據(jù)都輪流著作為驗證數(shù)據(jù)樣本,這樣在一組(C,gamma)組合下,就需要進(jìn)行K次計算,把這K次計算的模型測試準(zhǔn)確率score的均值作為這組(C,gamma)下模型的得分。這樣的話就能夠得到不同(C,gamma)組合下模型的得分,取得分最高的那組(C,gamma)即可,如果碰到有相同分的,一般考慮參數(shù)C,取C小的,因為在保證模型的準(zhǔn)確率的情況下,C越小模型容錯率大,可以避免過擬合,若C也相同,則取先出現(xiàn)的那一組gamma
?
二、交叉驗證
1、什么是交叉驗證?
主要使用k-fold Cross Validation(記為k-CV)
就是將訓(xùn)練樣本集進(jìn)行均分,比如將訓(xùn)練樣本集均分為k組,稱為k折,每次k-1折進(jìn)行訓(xùn)練,另一折用于驗證,每一組數(shù)據(jù)輪換作為驗證數(shù)據(jù)。這里驗證的是模型的識別率(accuracy)。在每一組(C,gamma)下對每一折數(shù)據(jù)進(jìn)行輪換驗證,這就是交叉驗證,一般折數(shù)越多,越精確,但是計算的時間就會增加,需要在效率和精度之間進(jìn)行權(quán)衡。
將C和gamma參數(shù)在一定地取值范圍內(nèi)按照一定的步長(默認(rèn)為1)進(jìn)行取值組合,在不同(C,gamma)的組合下,將訓(xùn)練集樣本均分成k組,一組作為驗證的數(shù)據(jù)樣本,其余k-1組則用來作為訓(xùn)練的數(shù)據(jù),每一組數(shù)據(jù)都輪流著作為驗證數(shù)據(jù)樣本,這樣在一組(C,gamma)組合下,就需要進(jìn)行K次計算,把這K次計算的模型測試準(zhǔn)確率score的均值作為這組(C,gamma)下模型的得分。這樣的話就能夠得到不同(C,gamma)組合下模型的得分,取得分最高的那組(C,gamma)即可,如果碰到有相同分的,一般考慮參數(shù)C,取C小的,因為在保證模型的準(zhǔn)確率的情況下,C越小模型容錯率大,可以避免過擬合,若C也相同,則取先出現(xiàn)的那一組gamma
2、參數(shù)優(yōu)化方法
可能很多人會有點懵,難道交叉驗證不是一個方法嗎?其實交叉驗證只是一種方案,而要去完成這個方案還需要方法,完成一個方案的方法有很多,不同的方法完成的效果也不一樣。同樣的道理參數(shù)的優(yōu)化來說,優(yōu)化算法有很多,如網(wǎng)格搜索算法、遺傳算法、粒子群算法、蟻群算法等,
對于交叉驗證來說,我們采取的是網(wǎng)格搜索算法,即在參數(shù)的一定的范圍內(nèi),按照指定的步長對不同的參數(shù)進(jìn)行排列組合,將每一組參數(shù)組合進(jìn)行測試,取性能指標(biāo)最優(yōu)的那一組參數(shù)作為最終參數(shù)的值。如本例中(C,gamma)組成了一個二維網(wǎng)格,再與性能指標(biāo)識別率組成三維模型,這樣一來就可以實現(xiàn)參數(shù)的最優(yōu)選擇啦!!!
《幾種常用交叉驗證(cross validation)方式的比較》
?
3、python實現(xiàn)交叉驗證cross_val_score(網(wǎng)格搜索算法GridSearchCV)
本例是一個兩特征三分類的問題,這里只涉及交叉驗證,沒有使用到網(wǎng)絡(luò)搜索算法,有興趣可以上網(wǎng)搜一下GridSearchCV
1)關(guān)鍵代碼
for C in range(1,10,1):for gamma in range(1,11,1):#獲得不同組合下的識別率,作為模型優(yōu)劣評價的性能指標(biāo),這里需要注意的是,性能指標(biāo)roc_auc,在本例中行不通,因為是多類問題,需要另外設(shè)置#獲得的識別率是交叉驗證后的平均值accuracy = cross_val_score(SVC(C=C/10,kernel='rbf',gamma=gamma/10),x,y.ravel(),cv=5,scoring='accuracy').mean()X.append(C/10)Y.append(gamma/10)Z.append(accuracy)M.append((C/10, gamma/10, accuracy))2)sklearn中的cross_val_score()函數(shù)參數(shù)
參考:《【Python】sklearn中的cross_val_score()函數(shù)參數(shù)》
sklearn 中的cross_val_score函數(shù)可以用來進(jìn)行交叉驗證,因此十分常用,這里介紹這個函數(shù)的參數(shù)含義
sklearn.cross_validation.cross_val_score(estimator, X, y=None, scoring=None, cv=None, n_jobs=1, verbose=0, fit_params=None, pre_dispatch=‘2*n_jobs’)?
estimator:估計方法對象(分類器) X:數(shù)據(jù)特征(Features) y:數(shù)據(jù)標(biāo)簽(Labels) soring:調(diào)用方法(包括accuracy、roc_auc、mean_squared_error等等) cv:幾折交叉驗證 n_jobs:同時工作的cpu個數(shù)(-1代表全部)3)AX3D三維繪圖
參考:《plot_surface(Axes3D)方法:繪制3D圖形》
3D 圖形需要的數(shù)據(jù)與等高線圖基本相同:X、Y 數(shù)據(jù)決定坐標(biāo)點,Z 軸數(shù)據(jù)決定 X、Y 坐標(biāo)點對應(yīng)的高度。與等高線圖使用等高線來代表高度不同,3D 圖形將會以更直觀的形式來表示高度。
為了繪制 3D 圖形,需要調(diào)用 Axes3D 對象的 plot_surface() 方法來完成。
下面程序?qū)⑹褂门c前面等高線圖相同的數(shù)據(jù)來繪制 3D 圖形,此時將看到程序會以更直觀的形式來顯示高度。
.................. fig = plt.figure() ax = Axes3D(fig) .................. # 繪制3D圖形 ax.plot_surface(X, Y, Z,rstride=1, # rstride(row)指定行的跨度cstride=1, # cstride(column)指定列的跨度cmap=plt.get_cmap('rainbow')) # 設(shè)置顏色映射 # 設(shè)置Z軸范圍 ax.set_zlim(-2, 2) # 設(shè)置標(biāo)題 plt.title("3D圖") plt.show()#一定不要忘記這行 .................... import matplotlib.pyplot as plt import numpy as np from mpl_toolkits.mplot3d import Axes3D fig = plt.figure(figsize=(12, 8)) ax = Axes3D(fig) delta = 0.125 # 生成代表X軸數(shù)據(jù)的列表 x = np.arange(-3.0, 3.0, delta) # 生成代表Y軸數(shù)據(jù)的列表 y = np.arange(-2.0, 2.0, delta) # 對x、y數(shù)據(jù)執(zhí)行網(wǎng)格化 X, Y = np.meshgrid(x, y) Z1 = np.exp(-X**2 - Y**2) Z2 = np.exp(-(X - 1)**2 - (Y - 1)**2) # 計算Z軸數(shù)據(jù)(高度數(shù)據(jù)) Z = (Z1 - Z2) * 2 # 繪制3D圖形 ax.plot_surface(X, Y, Z,rstride=1, # rstride(row)指定行的跨度cstride=1, # cstride(column)指定列的跨度cmap=plt.get_cmap('rainbow')) # 設(shè)置顏色映射 # 設(shè)置Z軸范圍 ax.set_zlim(-2, 2) # 設(shè)置標(biāo)題 plt.title("3D圖") plt.show()?
4)ravel函數(shù)
將多維數(shù)組轉(zhuǎn)換成一維數(shù)組
可參考:《numpy——ravel()和flatten()》
column-vector y was passed when a 1d array was expected. Please change the shape of y to (n_samples, ), for example using ravel().return f(**kwargs) import numpy as np arr = np.array([[1, 2],[3, 4]]) arr.ravel() #降維默認(rèn)行序優(yōu)先,傳入?yún)?shù)‘F’表示列序優(yōu)先 arr.ravel('F')##arr.ravel()=%s [1 2 3 4] ##arr.ravel('F')=%s [1 3 2 4]?
5)完整代碼
from sklearn.svm import SVC import numpy as np import sklearn import matplotlib.pyplot as plt from sklearn import preprocessing from sklearn.model_selection import cross_val_score from mpl_toolkits.mplot3d import Axes3D from sklearn.model_selection import GridSearchCV#define converts(字典) def Iris_label(s):it={b'Iris-setosa':0, b'Iris-versicolor':1, b'Iris-virginica':2 }return it[s]#1.讀取數(shù)據(jù)集 path='E:\PYTHON\machine_learning/Iris.data' data=np.loadtxt(path, dtype=float, delimiter=',', converters={4:Iris_label} ) #converters={4:Iris_label}中“4”指的是第5列:將第5列的str轉(zhuǎn)化為label(number)#2.劃分?jǐn)?shù)據(jù)與標(biāo)簽 x,y=np.split(data,indices_or_sections=(4,),axis=1) #x為數(shù)據(jù),y為標(biāo)簽,axis是分割的方向,1表示橫向,0表示縱向,默認(rèn)為0 x=x[:,0:2] #為便于后邊畫圖顯示,只選取前兩維度。若不用畫圖,可選取前四列x[:,0:4]# x = preprocessing.scale(x)#預(yù)處理數(shù)據(jù)樣本X = [] Y = [] Z = [] M = []#定義列表,分別用于接受不同組合的C,gamma以及性能指標(biāo)值 for C in range(1,10,1):for gamma in range(1,11,1):#獲得不同組合下的識別率,作為模型優(yōu)劣評價的性能指標(biāo),這里需要注意的是,性能指標(biāo)roc_auc,在本例中行不通,因為是多類問題,需要另外設(shè)置#獲得的識別率是交叉驗證后的平均值accuracy = cross_val_score(SVC(C=C/10,kernel='rbf',gamma=gamma/10),x,y.ravel(),cv=5,scoring='accuracy').mean()X.append(C/10)Y.append(gamma/10)Z.append(accuracy)M.append((C/10, gamma/10, accuracy)) print(M)#5、以C,gamma,auc作為三個坐標(biāo)變量繪圖#將列表轉(zhuǎn)換成數(shù)組 X = np.array(X).reshape(9,10) Y = np.array(Y).reshape(9,10) Z = np.array(Z).reshape(9,10)#繪制三維圖形 fig = plt.figure() ax = Axes3D(fig) ax.plot_surface(X,Y,Z,rstride=1,cstride=1,cmap=plt.get_cmap('rainbow')) # ax.scatter(Y,X,Z,c='r') plt.xlabel('Gamma') plt.ylabel('C') plt.title('gamma_C_auc') plt.show()繪制圖像如下,圖中紅色部分則為識別率最高的地方,取該處的(C,gamma)作為參數(shù)進(jìn)行模型訓(xùn)練。
至于具體怎么去得到最優(yōu)的參數(shù),我們可以在內(nèi)層循環(huán)中再嵌入一個判斷語句,大概思路為:先假設(shè)k = 0,m=0,n=0,將每次循環(huán)得到的accuracy與k做比較,若accuracy大于k,則將accuracy的值賦給k,同時將C賦值給m,將gamma賦值給n,最后就能夠得到最大的accuracy時的參數(shù),當(dāng)然也有可能出現(xiàn)accuracy相同時的情況,這時候就判斷C的大小,取C小的那組,同理gamma也是如此!!!這樣我們就找到了最優(yōu)參數(shù)C,gamma啦
?
總結(jié)
以上是生活随笔為你收集整理的机器学习——SVM之交叉验证对参数(C,gamma)进行优化以及选择的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: GAN 的推导、证明与实现。
- 下一篇: 用python计算工程量_基于Pytho