昨天講完特徵篩選,討論了共線性、替代效應的問題。
今天我們來聊聊至今都隨意做的模型超參數吧!!!(出來混種是要還的)
超參數調整是擬合機器學習算法的重要步驟。如果這個步驟不正確執行,算法可能會過度擬合,性能會很慘。機器學習的一些論文有特別提及對調整後的超參數進行交叉驗證。金融領域的交叉驗證(CV)是一個特別困難的問題,其他領域的方法可能會失敗。
網格搜索交叉驗證通過對參數的組合進行窮盡搜索,以最大化根據某個評分函數計算出的CV性能。當我們對數據的底層結構(或是產業知識)不太清楚時,這是一種合理的第一個方法。Scikit-learn已經在GridSearchCV函數中實作過,它接受CV生成器作為參數。(不得不說比起早年方便很多)。
當然,我們可以使用Scikit-learn來示範如何進行GridSearchCV的超參數網格搜索。這個例子將使用Scikit-learn的支援向量機(SVM)作為示範模型,並對超參數進行網格搜索以找到最佳參數。
首先我們做一個SVM模型,並設置要調整的超參數網格:
# 定義SVM模型
svm_model = SVC()
# 設置超參數網格
param_grid = {'C': [0.1, 1, 10],
'kernel': ['linear', 'rbf'],
'gamma': [0.1, 1, 'scale', 'auto']}
做一個GridSearchCV出來,它將在指定的超參數網格上執行交叉驗證:
# 創建GridSearchCV對象
grid_search = GridSearchCV(estimator=svm_model, param_grid=param_grid, cv=5)
# 使用訓練數據進行網格搜索
grid_search.fit(X_train, y_train)
網格搜索完成後,可以獲得最佳參數組合和對應的模型性能分數:
# 獲得最佳參數組合
best_params = grid_search.best_params_
# 獲得最佳模型
best_model = grid_search.best_estimator_
以下是需要的套件import~ 484很簡單~
from sklearn.svm import SVC
from sklearn.model_selection import GridSearchCV
網格搜索有一個巨大的缺點,就是非常消耗運算能力。我不打算在這邊測試一次,因為目前使用的數據集有200萬筆數據,針對隨機森林這類深度學習模型我們會遇到很大的算力消耗,算上幾天幾夜都可能的。因此如果有極高的算力或是很長的時間才會推薦這樣的方法。
網格搜索的好處就跟壞處對立:幾乎是最好並且過擬合較少的模型。因為參數都是經過交叉驗證定義的,所以過擬合的狀況也被大致抵銷了,並且她會輸出最終選擇的模型,因此很適合放著幾天等他自己好。
如果要使用網格搜索的方法的話建議要在特徵篩選的地方把特徵壓到盡量可以少就少,因為特徵的數量會極大的影響網格的運作效率。
對於具有大量參數的ML,網格搜索在計算上變得棘手。在這種情況下,一個具有良好統計性質的替代方法是從分佈中對每個參數進行抽樣。這有兩個好處:首先,我們可以控制我們將搜索的組合數,而不管參數維度如何(相當於先考慮計算預算)。
對於一些機器學習模型,只接受非負超參數是很常見的。某些非常流行的模型參數就是這樣,例如SVC分類器中的C和RBF核中的gamma。
我們可能會從一個在0和某個大值之間有界的均勻分佈中繪製隨機數,例如100。這意味著預計99%的值將大於1。這不一定是探索那些函數不線性響應的參數的可行性區域的最有效方法。例如那個參數0.1跟100是不一樣的概念,因為0.1可能代表變少,而100代表變多,參數的影響在各個位置並不是線性的。
因此,從均勻分佈中抽樣將是不好的(效率低、實際影響分布不均的)。因此將參數進行對數化顯得十分重要,因為可以展平參數的影響,使得參數影響變得線性。
具體的做法就是將參數範圍先取對數,而後進行隨機抽取,抽取完成後,再反運算回到原始數值。