機器學習(四)之參數選擇:交叉驗證、網格搜索

0 本文簡介

主要介紹了在調參時用到的交叉驗證、網格搜索。網格搜索是一種調節監督模型參數以獲得最佳泛化性能的有效方法。
相關筆記:
機器學習(一)之 2萬多字的監督學習模型總結V1.0:K近鄰、線性迴歸、嶺迴歸、樸素貝葉斯模型、決策樹、隨機森林、梯度提升迴歸樹、SVM、神經網絡
機器學習(二)之無監督學習:數據變換、聚類分析
機器學習(三)之數據表示和特徵工程:One-Hot編碼、分箱處理、交互特徵、多項式特徵、單變量非線性變換、自動化特徵選擇
機器學習(四)之參數選擇:交叉驗證、網格搜索
機器學習(五)之評價指標:二分類指標、多分類指標、混淆矩陣、不確定性、ROC曲線、AUC、迴歸指標

1 交叉驗證

1.1 思想和實現

交叉驗證(cross-validation)是一種評估泛化性能的統計學方法,它比單次劃分訓練集和測試集的方法更加穩定、全面。在交叉驗證中,數據被多次劃分,並且需要訓練多個模型。最常用的交叉驗證是k 折交叉驗證(k-fold cross-validation),其中k 是由用戶指定的數字,通常取5 或10。將數據劃分爲(大致)相等的k部分,每一部分叫作折(fold)。如下5折交叉驗證,使用第1 折作爲測試集、其他折(2~5)作爲訓練集來訓練第一個模型。對於將數據劃分爲訓練集和測試集的這5 次劃分,每一次都要計算精度。最後我們得到了5 個精度值。總結交叉驗證精度的一種常用方法是計算平均值
在這裏插入圖片描述
scikit-learn 是利用model_selection 模塊中的cross_val_score 函數來實現交叉驗證的。cross_val_score 函數的參數是我們想要評估的模型、訓練數據與真實標籤。

1.2 優缺點

1)、使用交叉驗證,每個樣例都會剛好在測試集中出現一次:每個樣例位於一個折中,而每個折都在測試集中出現一次。因此,模型需要對數據集中所有樣本的泛化能力都很好,才能讓所有的交叉驗證得分(及其平均值)都很高。

2)、對數據進行多次劃分,還可以提供我們的模型對訓練集選擇的敏感性信息。由於構建多個模型,所以它告訴我們將模型應用於新數據時在最壞情況和最好情況下的可能表現。

3)、對數據的使用更加高效,更多的數據通常可以得到更爲精確的模型。

4)、主要缺點是增加了計算成本。要訓練k 個模型而不是單個模型,所以交叉驗證的速度要比數據的單次劃分大約慢k 倍。

要注意:交叉驗證不是一種構建可應用於新數據的模型的方法。交叉驗證不會返回一個模型。在調用cross_val_score 時,內部會構建多個模型,但交叉驗證的目的只是評估給定算法在特定數據集上訓練後的泛化性能好壞

1.3 分層k折交叉驗證

如果我們的標籤是下面的形式,那麼k折交叉驗證就不適用了,可以使用分層k折交叉驗證(stratified k-fold cross-validation)。

labels:
[0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1
 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 2 2 2 2 2 2 2 2 2 2 2
 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2
 2 2]

數據的前三分之一是類別0,中間三分之一是類別1,最後三分之一是類別2。如果在這個數據集上進行3 折交叉驗證。第1 折將只包含類別0,所以在數據的第一次劃分中,測試集將只包含類別0,而訓練集只包含類別1 和2。由於在3 次劃分中訓練集和測試集中的類別都不相同,因此這個數據集上的3 折交叉驗證精度爲0

在分層交叉驗證中,我們劃分數據,使每個折中類別之間的比例與整個數據集中的比例相同,如下圖所示。
在這裏插入圖片描述解決這個問題的另一種方法是將數據打亂來代替分層,以打亂樣本按標籤的排序。可以通過將KFold 的shuffle 參數設爲True 來實現這一點。如果我們將數據打亂,那麼還需要固定random_state 以獲得可重複的打亂結果。

1.4 留一法交叉驗證

將留一法交叉驗證(leave-one-out)看作是每折只包含單個樣本的k 折交叉驗證。對於每次劃分,我們可以選擇單個數據點作爲測試集。這種方法可能非常耗時,特別是對於大型數據集來說,但在小型數據集上有時可以給出更好的估計結果。

from sklearn.model_selection import LeaveOneOut
loo = LeaveOneOut()
scores = cross_val_score(logreg, data, target, cv=loo)
print("Number of cv iterations: ", len(scores))
print("Mean accuracy: {:.2f}".format(scores.mean()))

1.5 打亂劃分交叉驗證

在打亂劃分交叉驗證(shuffle-split cross-validation)中,每次劃分爲訓練集取樣train_size 個點,爲測試集取樣test_size 個(不相交的)點。將這一劃分方法重複n_iter 次。

from sklearn.model_selection import ShuffleSplit
shuffle_split = ShuffleSplit(test_size=.5, train_size=.5, n_splits=10)
scores = cross_val_score(logreg, data, target, cv=shuffle_split)
print("Cross-validation scores:\n{}".format(scores))

train_size和test_size 設爲整數來表示這兩個集合的絕對大小,也可以設爲浮點數來表示佔整個數
據集的比例。

打亂劃分交叉驗證可以在訓練集和測試集大小之外獨立控制迭代次數,這有時是很有幫助的。它還允許在每次迭代中僅使用部分數據,這可以通過設置train_size 與test_size 之和不等於1 來實現。用這種方法對數據進行二次採樣可能對大型數據上的試驗很有用。

此外,ShuffleSplit 還有一種分層的形式,其名稱爲StratifiedShuffleSplit,它可以爲分類任務提供更可靠的結果。

1.6 分組交叉驗證

分組交叉驗證適用於數據中的分組高度相關時的情況。比如識別人臉表情時,要保證訓練集和測試集的不能有交叉的同一個人。同樣的在醫療診斷、語音識別等領域也可以使用。

可以使用GroupKFold,它以groups 數組作爲參數,可以用來說明照片中對應的是哪個人。這裏的groups 數組表示數據中的分組,在創建訓練集和測試集的時候不應該將其分開,也不應該與類別標籤弄混。

如下所示,對於每次劃分,每個分組都是整體出現在訓練集或測試集中:
在這裏插入圖片描述

2 網格搜索

找到一個模型的重要參數(提供最佳泛化性能的參數)的取值是一項棘手的任務,但對於幾乎所有模型和數據集來說都是必要的。scikit-learn 中有一些標準方法,最常用的方法就是網格搜索(grid search),它主要是指嘗試我們關心的參數的所有可能組合。

2.1 簡單網格搜索

在進行參數搜索時,我們應該將數據集分成訓練集、驗證集和測試集,其中,訓練集用於構建模型,驗證集(開發集)用於選擇模型參數,測試集用於評估所選參數性能。

利用驗證集選定最佳參數之後,我們可以利用找到的參數設置重新構建一個模型,但是要同時在訓練數據和驗證數據上進行訓練。這樣我們可以利用儘可能多的數據來構建模型
在這裏插入圖片描述

2.2 帶交叉驗證的網格搜索

雖然將數據劃分爲訓練集、驗證集和測試集的方法是可行的,也相對常用,但這種方法對數據的劃分方法相當敏感。爲了得到對泛化性能的更好估計,我們可以使用交叉驗證來評估每種參數組合的性能,而不是僅將數據單次劃分爲訓練集與驗證集。使用交叉驗證的主要缺點就是訓練所有這些模型所需花費的時間。

scikit-learn 提供了GridSearchCV 類,它以估計器(estimator)的形式實現了帶交叉驗證的網格搜索。其過程概述如下所示:
在這裏插入圖片描述
在使用GridSearchCV 類時,我們需要建立字典。字典的鍵是我們要調節的參數名稱,字典的值是我們想要嘗試的參數設置。雖然GridSearchCV 使用了交叉驗證,但是,我們仍需要將數據劃分爲訓練集和測試集,以避免參數過擬合。這樣我們分離出來的訓練集X_train就可以作爲GridSearchCV 的搜索數據了。擬合GridSearchCV 對象不僅會搜索最佳參數,還會利用得到最佳交叉驗證性能的參數在整個訓練數據集上自動擬合一個新模型

我們還可以分析交叉驗證的結果,這有助於理解模型泛化能力對所搜索參數的依賴關係。此外在非網格的空間中搜索時,我們可以創建字典組成的列表(a list ofdictionaries)。列表中的每個字典可擴展爲一個獨立的網格。還可以使用不同的交叉驗證策略進行網格搜索,比如嵌套交叉驗證(計算量大)、交叉驗證與網格搜索並行。

索時,我們可以創建字典組成的列表(a list ofdictionaries)。列表中的每個字典可擴展爲一個獨立的網格。還可以使用不同的交叉驗證策略進行網格搜索,比如嵌套交叉驗證(計算量大)、交叉驗證與網格搜索並行。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章