Grid SearchCV(網格搜尋)與RandomizedSearchCV (隨機搜尋)

2020-08-12 01:35:53

一、引言

在機器學習模型中,需要人工選擇的參數稱爲超參數。比如隨機森林中決策樹的個數,人工神經網路模型中隱藏層層數和每層的節點個數,正則項中常數大小等等,他們都需要事先指定。超參數選擇不恰當,就會出現欠擬合或者過擬合的問題。而在選擇超參數的時候,有兩個途徑,一個是憑經驗微調,另一個就是選擇不同大小的參數,帶入模型中,挑選表現最好的參數。

微調的一種方法是手工調製超參數,直到找到一個好的超參數組合,這麼做的話會非常冗長,你也可能沒有時間探索多種組合,所以可以使用Scikit-Learn的GridSearchCV來做這項搜尋工作。

二、爲什麼叫網格搜尋(GridSearchCV)

GridSearchCV的名字其實可以拆分爲兩部分,GridSearch和CV,即網格搜尋和交叉驗證。這兩個名字都非常好理解。網格搜尋,搜尋的是參數,即在指定的參數範圍內,按步長依次調整參數,利用調整的參數訓練學習器,從所有的參數中找到在驗證集上精度最高的參數,這其實是一個訓練和比較的過程。

GridSearchCV可以保證在指定的參數範圍內找到精度最高的參數,但是這也是網格搜尋的缺陷所在,他要求遍歷所有可能參數的組合,在面對大數據集和多參數的情況下,非常耗時。

三、什麼是Grid Search網格搜尋

Grid Search:一種調參手段;窮舉搜尋:在所有候選的參數選擇中,通過回圈遍歷,嘗試每一種可能性,表現最好的參數就是最終的結果。其原理就像是在數組裏找到最大值。這種方法的主要缺點是比較耗時!

所以網格搜尋適用於三四個(或者更少)的超參數(當超參數的數量增長時,網格搜尋的計算複雜度會呈現指數增長,這時候則使用隨機搜尋),使用者列出一個較小的超參數值域,這些超參數至於的笛卡爾積(排列組合)爲一組組超參數。網格搜尋演算法使用每組超參數訓練模型並挑選驗證集誤差最小的超參數組合。

簡單直白說:

指定不同的超參數列表進行暴力窮舉搜尋,並計算評估每個參數組合對模型效能的影響,從而獲得超參數的最優組合,例如我們對rbf kernel SVM進行訓練,超參數有C與gamma,這兩個超參數有不同的list,並一一組合進行訓練及評估,最終呼叫GridSearchCV的best_params_獲得最好的超參數組合。就是參數排列組合,輸入模型得出結果,然後得出效果最好的模型

 四、用程式碼具體講解

4.1 以隨機森林爲例說明GridSearch網格搜尋

下面 下麪程式碼,我們要搜尋兩種網格,一種是n_estimators,一種是max_features。GridSearch會挑選出最適合的超參數值。

from sklearn.model_selection import GridSearchCV
param_grid = [
        {'n_estimators': [3, 10, 30], 'max_features': [2, 4, 6, 8]},
        {'bootstrap': [False], 'n_estimators': [3, 10], 'max_features': [2, 3, 4]},
]
 
forest_reg = RandomForestRegressor()
grid_search = GridSearchCV(forest_reg, param_grid, cv=5,
                          scoring='neg_mean_squared_error')
 
grid_search.fit(housing_prepared, housing_labels)

sklearn 根據param_grid的值,首先會評估3×4=12種n_estimators和max_features的組合方式,接下來在會在bootstrap=False的情況下(預設該值爲True),評估2×3=6種12種n_estimators和max_features的組合方式,所以最終會有12+6=18種不同的超參數組合方式,而每一種組合方式要在訓練集上訓練5次(因爲cv=5), 所以一共要訓練18×5=90 次,當訓練結束後,你可以通過best_params_獲得最好的組合方式。

grid_search.best_params_輸出結果如下:

# grid_search.best_params_輸出結果如下:

{‘max_features’: 8, ‘n_estimators’: 30}

得到最好的模型:

RandomForestRegressor(bootstrap=True, criterion=‘mse’, max_depth=None,
max_features=8, max_leaf_nodes=None, min_impurity_decrease=0.0,
min_impurity_split=None, min_samples_leaf=1,
min_samples_split=2, min_weight_fraction_leaf=0.0,
n_estimators=30, n_jobs=1, oob_score=False, random_state=None,
verbose=0, warm_start=False)

小結:

如果GridSearchCV初始化時,refit=True(預設的初始化值),在交叉驗證時,一旦發現最好的模型(estimator),將會在整個訓練集上重新訓練,這通常是一個好主意,因爲使用更多的數據集會提升模型的效能。

以上面有兩個參數的模型爲例,參數a有3中可能,參數b有4種可能,把所有可能性列出來,可以表示成一個3*4的表格,其中每個cell就是一個網格,回圈過程就像是在每個網格裡遍歷,搜尋,所以叫grid search。

4.2 以Xgboost爲例說明GridSearch網格搜尋

下面 下麪以阿裡IJCAI廣告推薦數據集與XgboostClassifier分類器爲例,用程式碼形式說明sklearn中GridSearchCV的使用方法。(此小例的程式碼是參考這裏:請點選我

import numpy as np
import pandas as pd
import xgboost as xgb
from sklearn.grid_search import GridSearchCV
  
  
#匯入訓練數據
traindata = pd.read_csv("/traindata_4_3.txt",sep = ',')
traindata = traindata.set_index('instance_id')
trainlabel = traindata['is_trade']
del traindata['is_trade']
print(traindata.shape,trainlabel.shape)
  
  
#分類器使用 xgboost
clf1 = xgb.XGBClassifier()
  
#設定網格搜尋的xgboost參數搜尋範圍,值搜尋XGBoost的主要6個參數
param_dist = {
        'n_estimators':range(80,200,4),
        'max_depth':range(2,15,1),
        'learning_rate':np.linspace(0.01,2,20),
        'subsample':np.linspace(0.7,0.9,20),
        'colsample_bytree':np.linspace(0.5,0.98,10),
        'min_child_weight':range(1,9,1)
        }
 
 
#GridSearchCV參數說明,clf1設定訓練的學習器
#param_dist字典型別,放入參數搜尋範圍
#scoring = 'neg_log_loss',精度評價方式設定爲「neg_log_loss「
#n_iter=300,訓練300次,數值越大,獲得的參數精度越大,但是搜尋時間越長
#n_jobs = -1,使用所有的CPU進行訓練,預設爲1,使用1個CPU
grid = GridSearchCV(clf1,param_dist,cv = 3,scoring = 'neg_log_loss',n_iter=300,n_jobs = -1)
  
#在訓練集上訓練
grid.fit(traindata.values,np.ravel(trainlabel.values))
#返回最優的訓練器
best_estimator = grid.best_estimator_
print(best_estimator)   #輸出最優訓練器的精度

這裏關於網格搜尋的幾個參數在說明一下,評分參數「scoring」,需要根據實際的評價標準設定,阿裡的IJCAI的標準是「neg_log_loss」,所以這裏設定爲「neg_log_loss」,sklearn中備選的評價標準如下:在一些情況下,sklearn中沒有現成的評價函數,sklearn是允許我們自定義的,但是需要注意格式。

接下來看一下我們定義的評價函數:

import numpy as np
from sklearn.metrics import make_scorer
  
def logloss(act, pred):
    epsilon = 1e-15
    pred = sp.maximum(epsilon, pred)
    pred = sp.minimum(1-epsilon, pred)
    ll = sum(act*sp.log(pred) + sp.subtract(1, act)*sp.log(sp.subtract(1, pred)))
    ll = ll * -1.0/len(act)
    return ll
  
#這裏的greater_is_better參數決定了自定義的評價指標是越大越好還是越小越好
loss  = make_scorer(logloss, greater_is_better=False)
score = make_scorer(logloss, greater_is_better=True)

定義好以後,再將其帶入GridSearchCV函數就好。

補充一下常用的整合學習演算法比較重要的需要調參的參數:

4.3 以SVR爲例說明GridSearch網格搜尋

以兩個參數的調優過程爲例:

from sklearn.datasets import load_iris
from sklearn.svm import SVC
from sklearn.model_selection import train_test_split
 
iris_data = load_iris()
X_train,X_test,y_train,y_test = train_test_split(iris_data.data,iris_data.target,random_state=0)
 
# grid search start
best_score = 0
for gamma in [0.001,0.01,1,10,100]:
    for c in [0.001,0.01,1,10,100]:
        # 對於每種參數可能的組合,進行一次訓練
        svm = SVC(gamma=gamma,C=c)
        svm.fit(X_train,y_train)
        score = svm.score(X_test,y_test)
        # 找到表現最好的參數
        if score > best_score:
            best_score = score
            best_parameters = {'gamma':gamma,"C":c}
 
print('Best socre:{:.2f}'.format(best_score))
print('Best parameters:{}'.format(best_parameters))

輸出結果

Best socre:0.97
Best parameters:{'gamma': 0.001, 'C': 100}

五、上面調參存在的問題是什麼呢?

原始數據集劃分成訓練集和測試集以後,其中測試集除了用作調整參數,也用來測量模型的好壞;這樣做導致最終的評分結果比實際效果好。(因爲測試集在調參過程中,送到了模型裡,而我們的目的是將訓練模型應用到unseen data上)。這樣做容易過擬合,所以就需要其他的方法來減少過擬合的現象。於是,看下一章。

六、解決方法是什麼呢?------cv交叉驗證

對訓練集再進行一次劃分,分爲訓練集和驗證集,這樣劃分的結果就是:原始數據劃分爲3份,分別爲:訓練集,驗證集和測試集;其中訓練集用來模型訓練,驗證集用來調整參數,而測試集用來衡量模型表現好壞

對4.3的程式碼修改如下:

from sklearn.datasets import load_iris
from sklearn.svm import SVC
from sklearn.model_selection import train_test_split
 
iris_data = load_iris()
# X_train,X_test,y_train,y_test = train_test_split(iris_data.data,iris_data.target,random_state=0)
X_trainval,X_test,y_trainval,y_test = train_test_split(iris_data.data,iris_data.target,random_state=0)
X_train ,X_val,y_train,y_val = train_test_split(X_trainval,y_trainval,random_state=1)
# grid search start
best_score = 0
for gamma in [0.001,0.01,1,10,100]:
    for c in [0.001,0.01,1,10,100]:
        # 對於每種參數可能的組合,進行一次訓練
        svm = SVC(gamma=gamma,C=c)
        svm.fit(X_train,y_train)
        score = svm.score(X_val,y_val)
        # 找到表現最好的參數
        if score > best_score:
            best_score = score
            best_parameters = {'gamma':gamma,"C":c}
 
# 使用最佳參數,構建新的模型
svm = SVC(**best_parameters)
 
# 使用訓練集和驗證集進行訓練 more data always resultd in good performance
svm.fit(X_trainval,y_trainval)
 
# evalyation 模型評估
test_score = svm.score(X_test,y_test)
 
print('Best socre:{:.2f}'.format(best_score))
print('Best parameters:{}'.format(best_parameters))
print('Best score on test set:{:.2f}'.format(test_score))

結果:

Best socre:0.97
Best parameters:{'gamma': 0.001, 'C': 100}

然而,這種簡潔的grid search方法,其最終的表現好壞與初始數據的劃分結果有很大的關係,爲了處理這種情況,我們採用交叉驗證的方式來減少偶然性。

七、交叉驗證改進SVM程式碼(Grid Search with Cross Validation)

對第五章的程式碼進行修改:

from sklearn.datasets import load_iris
from sklearn.svm import SVC
from sklearn.model_selection import train_test_split,cross_val_score
 
iris_data = load_iris()
# X_train,X_test,y_train,y_test = train_test_split(iris_data.data,iris_data.target,random_state=0)
X_trainval,X_test,y_trainval,y_test = train_test_split(iris_data.data,iris_data.target,random_state=0)
X_train ,X_val,y_train,y_val = train_test_split(X_trainval,y_trainval,random_state=1)
# grid search start
best_score = 0
for gamma in [0.001,0.01,1,10,100]:
    for c in [0.001,0.01,1,10,100]:
        # 對於每種參數可能的組合,進行一次訓練
        svm = SVC(gamma=gamma,C=c)
        # 5 折交叉驗證
        scores = cross_val_score(svm,X_trainval,y_trainval,cv=5)
        score = scores.mean()
        # 找到表現最好的參數
        if score > best_score:
            best_score = score
            best_parameters = {'gamma':gamma,"C":c}
 
# 使用最佳參數,構建新的模型
svm = SVC(**best_parameters)
 
# 使用訓練集和驗證集進行訓練 more data always resultd in good performance
svm.fit(X_trainval,y_trainval)
 
# evalyation 模型評估
test_score = svm.score(X_test,y_test)
 
print('Best socre:{:.2f}'.format(best_score))
print('Best parameters:{}'.format(best_parameters))
print('Best score on test set:{:.2f}'.format(test_score))

結果:

Best socre:0.97
Best parameters:{'gamma': 0.01, 'C': 100}
Best score on test set:0.97

小結:

交叉驗證經常與網路搜尋進行結合,作爲參數評價的一種方法,這種方法叫做grid search with cross validation。

sklearn因此設計了一個這樣的類GridSearchCV,這個類實現fit,predict,score等方法。被當做一個estimator,使用fit方法,該過程中:

  • (1) 搜尋到最佳參數
  • (2)範例化了一個最佳參數的estimator

八、另一種sklearn裡封裝好的函數 RandomizedSearchCV 

所謂的模型設定,一般統稱爲模型的超參數(Hyperparameters),比如KNN演算法中的K值,SVM中不同的核函數(Kernal)等。多數情況下,超參數等選擇是無限的。在有限的時間內,除了可以驗證人工預設幾種超參數組合以外,也可以通過啓發式的搜尋方法對超參數組合進行調優。稱這種啓發式的超參數搜尋方法爲網格搜尋。 

我們在搜尋超參數的時候,如果超參數個數較少(三四個或者更少),那麼我們可以採用網格搜尋,一種窮盡式的搜尋方法。但是當超參數個數比較多的時候,我們仍然採用網格搜尋,那麼搜尋所需時間將會指數級上升。

所以有人就提出了隨機搜尋的方法,隨機在超參數空間中搜尋幾十幾百個點,其中就有可能有比較小的值。這種做法比上面稀疏化網格的做法快,而且實驗證明,隨機搜尋法結果比稀疏網格法稍好。

RandomizedSearchCV使用方法和類GridSearchCV 很相似,但他不是嘗試所有可能的組合,而是通過選擇每一個超參數的一個隨機值的特定數量的隨機組合,這個方法有兩個優點:

  • 如果你讓隨機搜尋執行, 比如1000次,它會探索每個超參數的1000個不同的值(而不是像網格搜尋那樣,只搜尋每個超參數的幾個值)
  • 你可以方便的通過設定搜尋次數,控制超參數搜尋的計算量。

RandomizedSearchCV的使用方法其實是和GridSearchCV一致的,但它以隨機在參數空間中採樣的方式代替了GridSearchCV對於參數的網格搜尋,在對於有連續變數的參數時,RandomizedSearchCV會將其當做一個分佈進行採樣進行這是網格搜尋做不到的,它的搜尋能力取決於設定的n_iter參數,同樣的給出程式碼。

import numpy as np
import pandas as pd
import xgboost as xgb
from sklearn.grid_search import RandomizedSearchCV
 
 
#匯入訓練數據
traindata = pd.read_csv("/traindata.txt",sep = ',')
traindata = traindata.set_index('instance_id')
trainlabel = traindata['is_trade']
del traindata['is_trade']
print(traindata.shape,trainlabel.shape)
 
 
#分類器使用 xgboost
clf1 = xgb.XGBClassifier()
 
#設定搜尋的xgboost參數搜尋範圍,值搜尋XGBoost的主要6個參數
param_dist = {
        'n_estimators':range(80,200,4),
        'max_depth':range(2,15,1),
        'learning_rate':np.linspace(0.01,2,20),
        'subsample':np.linspace(0.7,0.9,20),
        'colsample_bytree':np.linspace(0.5,0.98,10),
        'min_child_weight':range(1,9,1)
        }
 
#RandomizedSearchCV參數說明,clf1設定訓練的學習器
#param_dist字典型別,放入參數搜尋範圍
#scoring = 'neg_log_loss',精度評價方式設定爲「neg_log_loss「
#n_iter=300,訓練300次,數值越大,獲得的參數精度越大,但是搜尋時間越長
#n_jobs = -1,使用所有的CPU進行訓練,預設爲1,使用1個CPU
grid = RandomizedSearchCV(clf1,param_dist,cv = 3,scoring = 'neg_log_loss',n_iter=300,n_jobs = -1)
 
#在訓練集上訓練
grid.fit(traindata.values,np.ravel(trainlabel.values))
#返回最優的訓練器
best_estimator = grid.best_estimator_
print(best_estimator)
#輸出最優訓練器的精度
print(grid.best_score_)

tips:建議使用隨機搜尋。

九、超參數搜尋——網格搜尋的並行化

既然網格搜尋的參數不能選太多,那如果選的太多,勢必會造成執行時間長,那麼問題來了,如果我們的超參數真的很多,又不想讓執行時間那麼長,怎麼辦?答案是並行化!!!

9.1 使用單執行緒對文字分類的樸素貝葉斯模型的超參數組合執行網格搜尋

程式碼如下:

from sklearn.datasets import fetch_20newsgroups
import numpy as np
news = fetch_20newsgroups(subset='all')
from sklearn.cross_validation import train_test_split
#取前3000條新聞文字進行數據分割
X_train,X_test,y_train,y_test=train_test_split(news.data[:3000],
                                            news.target[:3000],test_size=0.25,random_state=33)
 
 
from sklearn.svm import SVC
from sklearn.feature_extraction.text import TfidfVectorizer
#*************匯入pipeline*************
from sklearn.pipeline import Pipeline
#使用Pipeline簡化系統搭建流程,sklean提供的pipeline來將多個學習器組成流水線,通常流水線的形式爲:
#將數據標準化的學習器---特徵提取的學習器---執行預測的學習器
#將文字特徵與分類器模型串聯起來,[(),()]裡有兩個參數
#參數1:執行 vect = TfidfVectorizer(stop_words='english',analyzer='word')操作
#參數2:執行 svc = SVC()操作
clf = Pipeline([('vect',TfidfVectorizer(stop_words='english',analyzer='word')),('svc',SVC())])
 
#這裏需要試驗的2個超參數svc_gamma和svc_C的元素個數分別爲4、3,這樣我們一共有12種超參數對集合
#numpy.linspace用於建立等差數列,numpy.logspace用於建立等比數列
#logspace中,開始點和結束點是10的冪
#例如logspace(-2,1,4)表示起始數位爲10^-2,結尾數位爲10^1即10,元素個數爲4的等比數列
#parameters變數裏面的key都有一個字首,這個字首其實就是在Pipeline中定義的操作名。二者相結合,使我們的程式碼變得十分簡潔。
#還有注意的是,這裏對參數名是<兩條>下劃線 __
parameters = {'svc__gamma':np.logspace(-2,1,4),'svc__C':np.logspace(-1,1,3)}
 
#從sklearn.grid_search中匯入網格搜尋模組GridSearchCV
from sklearn.grid_search import GridSearchCV
#GridSearchCV參數解釋:
#1.estimator : estimator(評估) object.
#2.param_grid : dict or list of dictionaries
#3.verbose:Controls the verbosity(冗餘度): the higher, the more messages.
#4.refit:default=True, Refit(再次擬合)the best estimator with the entire dataset
#5.cv : int, cross-validation generator 此處表示3折交叉驗證
gs = GridSearchCV(clf,parameters,verbose=2,refit=True,cv=3)
 
#執行單執行緒網格搜尋
gs.fit(X_train,y_train)
 
print gs.best_params_,gs.best_score_
 
#最後輸出最佳模型在測試集上的準確性
print 'the accuracy of best model in test set is',gs.score(X_test,y_test)

小結:

1.由輸出結果可知,使用單執行緒的網格搜尋技術 對樸素貝葉斯模型在文字分類任務中的超參數組合進行調優,共有12組超參數組合*3折交叉驗證 =36項獨立執行的計算任務

2.在本機上,該過程一共執行了2.9min,尋找到最佳的超參數組合在測試集上達到的分類準確性爲82.27%

9.2 使用多執行緒對文字分類的樸素貝葉斯模型的超參數組合執行網格搜尋

關鍵程式碼:

#n_jobs=-1,表示使用該計算機的全部cpu
gs = GridSearchCV(clf,parameters,verbose=2,refit=True,cv=3,n_jobs=-1)
gs.fit(X_train,y_train)
print gs.best_params_,gs.best_score_
#輸出最佳模型在測試集上的準確性
print 'the accuracy of best model in test set is',gs.score(X_test,y_test)

小結:

總任務相同的情況下,使用並行搜尋技術進行計算的話,執行時間只花費了1.1min;

而且最終所得的的best_params_和score沒有發生變化,說明並行搜尋可以在不影響準確性的前提下,有效的利用計算機的CPU資源,大大節省了最佳超參數的搜尋時間。

十、超參數估計的隨機搜尋和網格搜尋的比較

使用的數據集是小數據集 手寫數位數據集 load_digits() 分類   數據規模 5620*64(sklearn中的小數據可以直接使用,大數據集在第一次使用的時候會自動下載)

先上結論:

比較隨機森林超參數優化的隨機搜尋和網格搜尋。所有影響學習的參數都是同時搜尋的(除了估計值的數量,它會造成時間/品質的權衡)。隨機搜尋和網格搜尋探索的是完全相同的參數空間。參數設定的結果非常相似,而隨機搜尋的執行時間要低的多。隨機搜尋的效能稍差,不過這很可能是噪聲效應,不會延續到外接測試集。

注意:在實踐中,人們不會使用網格搜尋同時搜尋這麼多不同的參數,而是隻選擇那些被認爲最重要的參數

程式碼如下:

#_*_coding:utf-8_*_
# 輸出檔案開頭註釋的內容  __doc__的作用
'''
Python有個特性叫做文件字串,即DocString ,這個特性可以讓你的程式文件更加清晰易懂
'''
print(__doc__)
import numpy as np
from time import time
from scipy.stats import randint as sp_randint
 
from sklearn.model_selection import GridSearchCV
from sklearn.model_selection import RandomizedSearchCV
from sklearn.datasets import load_digits
from sklearn.ensemble import RandomForestClassifier
 
# get some  data
digits = load_digits()
X, y = digits.data , digits.target
 
# build a classifier
clf = RandomForestClassifier(n_estimators=20)
 
# utility function to report best scores
def report(results, n_top= 3):
    for i in range(1, n_top + 1):
        candidates = np.flatnonzero(results['rank_test_score'] == i)
        for candidate in candidates:
            print("Model with rank:{0}".format(i))
            print("Mean validation score : {0:.3f} (std: {1:.3f})".
                  format(results['mean_test_score'][candidate],
                         results['std_test_score'][candidate]))
            print("Parameters: {0}".format(results['params'][candidate]))
            print("")
 
# 指定取樣的參數和分佈 specify parameters and distributions to sample from
param_dist = {"max_depth":[3,None],
              "max_features":sp_randint(1,11),
              "min_samples_split":sp_randint(2,11),
              "bootstrap":[True, False],
              "criterion":["gini","entropy"]
              }
 
# run randomized search
n_iter_search = 20
random_search = RandomizedSearchCV(clf,param_distributions=param_dist,
                                   n_iter=n_iter_search,cv =5)
start = time()
random_search.fit(X, y)
print("RandomizedSearchCV took %.2f seconds for %d candidates"
      " parameter settings." % ((time() - start), n_iter_search))
report(random_search.cv_results_)
 
# use a full grid over all parameters
param_grid = {"max_depth":[3,None],
              "max_features":[1, 3, 10],
              "min_samples_split":[2, 3, 10],
              "bootstrap":[True, False],
              "criterion":["gini","entropy"]
    }
# run grid search
grid_search = GridSearchCV(clf, param_grid=param_grid, cv =5)
start = time()
grid_search.fit(X , y)
print("GridSearchCV took %.2f seconds for %d candidate parameter settings."
      % (time() - start, len(grid_search.cv_results_['params'])))
report(grid_search.cv_results_)

執行結果:

RandomizedSearchCV took 6.20 seconds for 20 candidates parameter settings.
Model with rank:1
Mean validation score : 0.930 (std: 0.031)
Parameters: {'bootstrap': False, 'criterion': 'entropy', 'max_depth': None, 'max_features': 6, 'min_samples_split': 5}
 
Model with rank:2
Mean validation score : 0.929 (std: 0.024)
Parameters: {'bootstrap': False, 'criterion': 'entropy', 'max_depth': None, 'max_features': 6, 'min_samples_split': 9}
 
Model with rank:3
Mean validation score : 0.924 (std: 0.020)
Parameters: {'bootstrap': False, 'criterion': 'gini', 'max_depth': None, 'max_features': 3, 'min_samples_split': 6}
 
# ***********************************************************************************# 
Model with rank:1
Mean validation score : 0.932 (std: 0.023)
Parameters: {'bootstrap': False, 'criterion': 'gini', 'max_depth': None, 'max_features': 10, 'min_samples_split': 3}
 
Model with rank:2
Mean validation score : 0.931 (std: 0.014)
Parameters: {'bootstrap': False, 'criterion': 'gini', 'max_depth': None, 'max_features': 3, 'min_samples_split': 3}
 
Model with rank:3
Mean validation score : 0.929 (std: 0.021)
Parameters: {'bootstrap': False, 'criterion': 'entropy', 'max_depth': None, 'max_features': 3, 'min_samples_split': 2}

十一、scikit-learn GridSearch庫概述

sklearn的Grid Search官網地址:請點選我

11.1 GridSearchCV簡介

GridSearchCV,它存在的意義就是自動調參,只要把參數輸進去,就能給出最佳化結果和參數。但是這個方法適合於小數據集,一旦數據的量級上去了,很難得到結果。這個時候就需要動腦筋了。數據量比較大的時候可以使用一個快速調優的方法——座標下降。它其實是一種貪婪演算法:拿當前對模型影響最大的參數調參,直到最佳化;再拿下一個影響最大的參數調優,如此下去,直到所有的參數調整完畢。這個方法的缺點就是可能會跳到區域性最優而不是全域性最優,但是省時間省力,巨大的優勢面前,還是試一試,後續可以再拿bagging再優化。

通常演算法不夠好,需要偵錯參數時必不可少。比如SVM的懲罰因子C,核函數kernel,gamma參數等,對於不同的數據使用不同的參數,結果效果可能差1~5個點,sklearn爲我們專門偵錯參數的函數grid_search。

11.2 GridSearchCV參數說明

參數如下:

class sklearn.model_selection.GridSearchCV(estimator, param_grid, scoring=None,fit_params=None, n_jobs=None, iid=’warn’, refit=True, cv=’warn’, verbose=0,pre_dispatch=‘2*n_jobs’, error_score=’raise-deprecating’, return_train_score=’warn’)

說明如下:

1、estimator:選擇使用的分類器,並且傳入除需要確定最佳的參數之外的其他參數。每一個分類器都需要一個scoring參數或者score方法:如estimator = RandomForestClassifier(min_sample_split=100,min_samples_leaf = 20,max_depth = 8,max_features = 'sqrt' , random_state =10),

2、param_grid:需要最佳化的參數的取值,值爲字典或者列表,例如:param_grid = param_test1,param_test1 = {'n_estimators' : range(10,71,10)}

3、scoring = None :模型評價標準,預設爲None,這時需要使用score函數;或者如scoring = 'roc_auc',根據所選模型不同,評價準則不同,字串(函數名),或是可呼叫物件,需要其函數簽名,形如:scorer(estimator,X,y);如果是None,則使用estimator的誤差估計函數。

4、fit_params = None

5、n_jobs = 1 : n_jobs:並行數,int:個數,-1:跟CPU核數一致,1:預設值

6、iid = True:iid:預設爲True,爲True時,預設爲各個樣本fold概率分佈一致,誤差估計爲所有樣本之和,而非各個fold的平均。

7、refit = True :預設爲True,程式將會以交叉驗證訓練集得到的最佳參數,重新對所有可能的訓練集與開發集進行,作爲最終用於效能評估的最佳模型參數。即在搜尋參數結束後,用最佳參數結果再次fit一遍全部數據集。

8、cv = None:交叉驗證參數,預設None,使用三折交叉驗證。指定fold數量,預設爲3,也可以是yield訓練/測試數據的生成器。

9、verbose = 0 ,scoring = None  verbose:日誌冗長度,int:冗長度,0:不輸出訓練過程,1:偶爾輸出,>1:對每個子模型都輸出。

10、pre_dispatch = '2*n_jobs' :指定總共發的並行任務數,當n_jobs大於1時候,數據將在每個執行點進行復制,這可能導致OOM,而設定pre_dispatch參數,則可以預先劃分總共的job數量,使數據最多被複制pre_dispatch次。

11.3 進行預測的常用方法和屬性

  • grid.fit()  :執行網格搜尋
  • grid_scores_   :給出不同參數情況下的評價結果
  • best_params_  :描述了已取得最佳結果的參數的組合
  • best_score_    :提供優化過程期間觀察到的最好的評分
  • cv_results_  :具體用法模型不同參數下交叉驗證的結果

11.4 GridSearchCV屬性說明

1、cv_results_ : dict of numpy (masked) ndarrays

具有鍵作爲列標題和值作爲列的dict,可以匯入到DataFrame中。注意,「params」鍵用於儲存所有參數候選項的參數設定列表。

2、 best_estimator_ : estimator

通過搜尋選擇的估計器,即在左側數據上給出最高分數(或指定的最小損失)的估計器。如果refit = False,則不可用。

3、best_score_ :float  best_estimator的分數

4、best_parmas_ : dict  在儲存數據上給出最佳結果的參數設定

5、best_index_ : int 對應於最佳候選參數設定的索引(cv_results_陣列)

search.cv_results _ ['params'] [search.best_index_]中的dict給出了最佳模型的參數設定,給出了最高的平均分數(search.best_score_)。

6、scorer_ : function

Scorer function used on the held out data to choose the best parameters for the model.

7、n_splits_ : int

The number of cross-validation splits (folds/iterations).

 

參考文章:https://www.cnblogs.com/wj-1314/p/10422159.html 

                  https://blog.csdn.net/juezhanangle/article/details/80051256