為了在數據集上訓練不同的模型並且選擇性能最佳的模型,有時候雖然仍有改進的余地,因為我們不會肯定地說這個特定模型最合適解決手頭的問題。因此,我們的目標是以任何可能的方式改進模型,影響這些模型性能的一個重要因素是它們的超參數,一旦我們為這些超參數找到合適的值,模型的性能就會顯著提高。在本文中,將了解學習如何使用GridSearchCV找到模型超參數的最佳值。
1.什么是GridSerchCV?
首先,讓我們了解一下什么是GridSerchCV(網格搜索)?它是執行超參數調整以確定給模型的最佳值的過程。模型的性能很大程度上卻決於超參數的值。但需注意的是,我們沒有辦法提前知道超參數的最佳值,一般有兩個方法,一種並經驗去調參,另一種是比較常見的情況,就是需要我們嘗試所有可能的值來知道最佳值。
GridSearchCV 是 Scikit-learn(或sklearn)model_selection包中的一個函數。所以這里我們需要事先在自己計算機上安裝Scikit-learn庫。此函數有助於遍歷預定義的超參數並使你的模型適合你的訓練集,所以在最后我們可以從列出的超參數中選擇最好的參數。
2.GridSerchCV是如何工作?
下面我將超參數的預定義值傳遞給GridSearchCV函數。
通過定義一個字典賦值給param_grid
變量來實現這一點,在字典中提到了一個特定的超參數以及它可以選取的值。如下例子:
param_grid = {'C': [0.1, 1, 10, 100, 1000],
'gamma': [1, 0.1, 0.01, 0.001, 0.0001],
'kernel': ['rbf',’linear’,'sigmoid']}
這里的C、gamma和Kernels是SVM模型的一些超參數,除了上面列出的超參數,其余未列出的超參數將設置為其默認值。
GridSearchCV 嘗試字典中傳遞的值的所有組合,並使用交叉驗證方法評估每個組合的模型。因此,在使用此函數后,我們可以獲得每種超參數組合的准確率/損失,我們可以選擇性能最佳的組合。
3.如何使用GridSerchCV?
首先,看看GridSearchCV 函數的各種參數是什么:
sklearn.model_selection.GridSearchCV(estimator, param_grid,scoring=None,n_jobs=None, iid='deprecated', refit=True, cv=None, verbose=0, pre_dispatch='2*n_jobs', error_score=nan, return_train_score=False)
簡要描述其中的一些參數,也可以自行到官網文檔中找到這些參數:
1.estimator:傳遞要檢查超參數的模型實例。 2.params_grid:保存要嘗試的超參數的字典對象 3.scoring:要使用的評估指標,簡單地傳遞有效的字符串/評估指標對象 4.cv:擁有的交叉驗證數嘗試每個選定的超參數集 5.verbose:可以將其設置為 1 以在將數據適合 GridSearchCV 時獲得詳細的打印輸出 6.n_jobs:希望為此任務並行運行的進程數,如果它等於-1,它將使用所有可用的處理器。
現在,看看如何使用GriGdSearchCV 來提高我們模型的准確性。在下面的例子,我將訓練模型兩次,第一次不使用GridSearchCV ,第二次將使用GridSearchCV 為例子中的數據集找到超參數的最佳值。
在這個例子中使用威斯康星州乳腺癌(診斷)數據集,直接從Scikit-learn庫導入。
- 不使用GridSearchCV的例子:
# 導入本文三個例子所需要到的相關庫包
from sklearn.datasets import load_breast_cancer
from sklearn.svm import SVC
from sklearn.model_selection import train_test_split
from sklearn.metrics import classification_report,mean_squared_error
from sklearn.ensemble import RandomForestClassifier
from sklearn.model_selection import GridSearchCV
# 加載數據集並將其拆分為訓練集和測試集
dataset = load_breast_cancer()
X = dataset.data
Y = dataset.target
X_train, X_test, y_train, y_test = train_test_split(
X,Y,test_size = 0.30, random_state = 101)
# 不使用GridSearchCV在上訓練模型
model = SVC()
model.fit(X_train, y_train)
# 訓練結果
y_pred = model.predict(X_test)
# 使用分類指標classification_report - 構建顯示主要分類指標的文本報告
report = classification_report(y_test, y_pred)
print(report)
####################################### 輸出結果如下:#######################################
"""
precision recall f1-score support
0 0.95 0.85 0.90 66
1 0.91 0.97 0.94 105
accuracy 0.92 171
macro avg 0.93 0.91 0.92 171
weighted avg 0.93 0.92 0.92 171
"""
# 輸出結果詳解:其中列名 每個標簽類的精度、召回率、F1值、樣本量
# F1分數,是統計學中用來衡量二分類模型精確度的一種指標。F1分數可以看作是模型精確率和召回率的一種調和平均,它的最大值是1,最小值是0。
# accuracy表示准確率,也即正確預測樣本量與總樣本量的比值
# marco avg表示宏平均,表示所有類別對應指標的平均值
# weighted avg表示帶權重平均,表示類別樣本占總樣本的比重與對應指標的乘積的累加和
- 使用GridSearchCV的例子(SVM)
# 定義參數范圍
param_grid = {
'C': [0.1, 1, 10, 100], # 正則化參數
'gamma': ['scale', 'auto'], # 核系數
'kernel': ['linear'], #內核函數(線性核'linear'、多項式核'poly'、高斯核'rbf'、核函數'sigmoid')
}
# 擬合網格搜索模型
grid.fit(X_train, y_train)
# 打印調整后的最佳參數
print(grid.best_params_)
grid_y_pred = grid.predict(X_test)
# 打印報告
print(classification_report(y_test, grid_y_pred))
####################################### 輸出結果如下:#######################################
"""
Fitting 5 folds for each of 8 candidates, totalling 40 fits
[CV 2/5] END ..............C=0.1, gamma=scale, kernel=linear; total time= 0.0s
[CV 1/5] END ..............C=0.1, gamma=scale, kernel=linear; total time= 0.0s
...
[CV 4/5] END ...............C=100, gamma=auto, kernel=linear; total time= 13.0s
{'C': 100, 'gamma': 'scale', 'kernel': 'linear'}
precision recall f1-score support
0 0.97 0.91 0.94 66
1 0.94 0.98 0.96 105
accuracy 0.95 171
macro avg 0.96 0.95 0.95 171
weighted avg 0.95 0.95 0.95 171
"""
- 使用GridSearchCV的例子(隨機森林分類器RandomForestClassifier)
param_grid = {
'max_depth': range(1, 10), # 樹的最大深度
'n_estimators': range(1,200,10), # 森林中的樹木數量
}
grid = GridSearchCV(RandomForestClassifier(),
param_grid,
refit=True, # 當refit=True估計器是分類器時才可用
n_jobs=-1, # n_jobs = -1 使用所有處理器
verbose=3, # 詳細程度,3最高,顯示消息最多
)
# 擬合網格搜索模型
grid.fit(X_train, y_train)
#
# 打印調整后的最佳參數
print(grid.best_params_)
grid_y_pred = grid.predict(X_test)
#
# # 打印報告
print(classification_report(y_test, grid_y_pred))
####################################### 輸出結果如下:#######################################
"""
Fitting 5 folds for each of 180 candidates, totalling 900 fits
[CV 2/5] END ....................max_depth=1, n_estimators=1; total time= 0.0s
...
[CV 5/5] END ..................max_depth=9, n_estimators=191; total time= 0.3s
{'max_depth': 6, 'n_estimators': 181}
precision recall f1-score support
0 0.94 0.94 0.94 66
1 0.96 0.96 0.96 105
accuracy 0.95 171
macro avg 0.95 0.95 0.95 171
weighted avg 0.95 0.95 0.95 171
"""
看完輸出結果,可能就會認為{'C': 100, 'gamma': 'scale', 'kernel': 'linear'}
是SVM
模型超參數的最佳值,事實上,這些超參數可能是我們正在處理的數據集的最佳值。但是對於不同的數據集,SVM
和RandomForestClassifier
模型可以有不同的超參數使其最優。
總結
經過本文這么一邊實踐一邊總結,從學習如何使用到深入了解如何找到模型的最佳超參數,從而使得模型獲得更好的性能。
出處: