調整超參數:決定模型是“金子”還是“垃圾”!

數據清洗以後,你也許會困惑應該從哪裏開始建模。一般情況下它的下一步應該是特徵選擇,但特徵工程和模型訓練是相互影響的。好的特徵選擇可以使模型得到好的效果,而不同的模型又對數據有不同的要求。

因此,特徵工程和模型訓練是兩個不可分割的部分。由於模型的選擇會對特徵的選擇造成影響,因此,在特徵工程開始前,至少應該嘗試訓練一些可能的模型,查看當前的特徵是否適合可能的模型。如下圖是建模流程的循環,特徵工程和訓練模型是兩個動態過程。

通過特徵工程,選擇可能的重要特徵。通過參數調整,嘗試訓練可能的模型,從中選擇最佳的模型並調試參數。

除了特徵工程以外,超參數的選擇也十分重要,它決定你的模型是“金子”還是“垃圾”,以及模型是否處於最優的表現並得到好的結果。本文着重介紹三種超參數調節的方法,分別爲:手動調節(manual tuning),網格搜索(grid search),隨機搜索(randomized search),貝葉斯搜索(Bayesian Search)。 詳見鏈接。

圖片來源:https://towardsdatascience.com/what-is-the-best-starter-model-in-table-data-ml-lessons-from-a-high-rank-kagglers-new-book-f08b821db797

在開始介紹超參數前,首先要明確參數與超參數的區別:

參數:是模型內部的配置變量,在機器學習中生成的。

超參數:超參數是在機器學習前由用戶基於以往的經驗填入的實體,它不能通過機器學習自動生成,而必須由外部進行指定。

例如邏輯迴歸,假設y=ax+b,其中x是輸入數據,sigmoid函數是$f(x) = {1 \over {1 + e^{-(ax+b)}}}$,模型的輸出值爲0或1。 對於任意給定的數據X,模型都會返回一個a和b與之匹配,其中的a和b就是模型的參數。由於模型的輸出值是0或1,因此,決定模型何時輸出爲1,何時輸出爲0,需要外部設置一個閾值,這個閾值(threshold)即爲模型的超參數。 對於模型的參數,是通過在訓練模型或者機器學習中生成的,而超參數是需要外部設置,可以用過學習曲線或者網格搜索等方法進行調節,以使模型表現最佳。

1. 超參數的調整概述

在scikit-learn中提供很多不同的機器學習模型,並且提供了各模型超參數的初始值設置,這些初始值的搭配僅是針對解決某些問題的可能的最優搭配,並不是針對解決所有問題的最優搭配,因此,當使用scikit-learn中的模型進行建模時,調整超參數仍是必要的。

1.1 伴隨特徵工程的三個調參過程

比較常見的步驟可以如下:

  • 初始階段:以基準參數和基準特徵工程爲開始,
  • 重要參數調節階段:通過選擇一些參數候選和特徵工程,手動調參或者網格搜索一些重要特徵 ,
  • 剩餘參數調節階段:對於其它參數和最後的特徵工程,使用隨機搜索。

1.2 瞭解模型超參數

數據科學家的工作之一就是找到模型的最佳超參數。由於每個模型的超參數都不盡相同,很難對所有模型的超參數進行概括性總結。因此,在調節超參數前,應對可能用到的模型及其超參數設置有一個全面概括的瞭解。下面爲幾個關於不同集成算法的各參數總結網站,可以收藏,以備不時之需。

(1)介紹xgboost和lightGBM超參數的網站。

(2)在Analytic Vidhya網站上也提供關於GBDT模型的超參數的豐富資料:

  • xgboost: "Complete Guide to Parameter Tuning in XGBoost with codes in Python"
  • lightgbm: "Which algorithm takes the crown: Light GBM vs XGBOOST?"

(3)XGBoost,LightGBM和CatBoost超參數的優化:

  • "An Example of Hyperparameter Optimization on XGBoost, LightGBM and CatBoost using Hyperopt"

下表展示了根據不同分級的重要性,參數不同重要性的總結:

圖片來源 https://towardsdatascience.com/hyperparameter-tuning-explained-d0ebb2ba1d35

2. 四個調節超參數的基本方法

2.1 手動調節

手動參數調節更多的是基於建模者對以往經驗的總結,通過修改模型的部分參數,瞭解模型分數對模型參數變化的敏感性。

手動調節參數的優勢:

  • 應用以往構建模型的經驗,選擇可能的最佳模型參數。在調參過程中至少可以手動嘗試調節模型參數;較爲快速。

手動調節參數的劣勢:

  • 缺少對模型參數與相應得分變化的宏觀把握。

比如,當你發現在訓練模型的時候,很多不用的特徵被“味”到模型中,你可以手動增加正則參數的權重進行特徵選擇。手動調節參數可以讓建模者快速掌握模型對參數變化的敏感度,以備後續提供更好的模型調參範圍。

2.2 網格搜索

又名窮盡的網格搜索(Exhaustive Grid Search)。網格搜索方法是通過設置可能的各超參數集合,將所有集合中可能的組合作爲超參數,對模型進行一次訓練。n個可能的超參數組合意味着n次模型訓練。最後,網格搜索的返回值是n次模型訓練中模型表現最好的超參數組合。因此,網格搜索隨設置的超參數個數和集合的提高,呈時間和空間的複雜性。 網格搜索的評分標準可以由用戶來指定,例如準確率,精確率,召回率等。

參數設置和模型評估可以使用sklearn中的GridSearchCV進行調用。

網格搜索的優勢:

  • 可以選用任何你認爲可能是最佳參數範圍的超參數集合進行模型訓練。

網格搜索的劣勢:

  • 網格搜索較爲耗時,因爲要運行給定的每一個超參數集。所以,如果參數集較大,則網格搜索的運行成本較高。實際上,網格搜索的參數範圍是需要被限制的,即不能無限大。

以LGBMRegressor模型爲例,分別設置了“max_depth”,“subsample”,“colsample_bytree”,“min_child_weight”超參數,它的評分器是“r2”,可能的組合個數是3*2*2*3=36,即需要訓練36次LGBMRegressor模型,如下是代碼示例:

# 導入lightgbm庫 
from lightgbm import LGBMRegressor
​
# 導入網格搜索 
from sklearn.model_selection import train_test_split, GridSearchCV
​
import pandas as pd
import numpy as np
​
# 導入數據並拆分訓練集 
df = pd.read_csv('test.csv',index_col=0)
y = df['Target']
X = df.drop(['Targe'],axis=1)
X_train0, X_test, y_train0, y_test = train_test_split(X,y,test_size=0.2, random_state= 2)
​
# 定義驗證集比例 
r = 0.1 
trainLen = round(len(X_train0)*(1-r))
​
# 拆分訓練集和驗證集 
X_train = X_train0.iloc[:trainLen,:]
y_train = y_train0[:trainLen]
X_val = X_train0.iloc[trainLen:,:]
y_val = y_train0[trainLen:]
​
# 定義網格搜索參數 
gridParams = {
    'max_depth': [3, 5, 7],
    'subsample': [0.8, 1.0],
    'colsample_bytree': [0.8, 1.0],
    'min_child_weight': [0.1, 1.0, 2.0],
}
​
# 定義lightgbm網格搜索 
reg = LGBMRegressor(learning_rate=0.1, n_estimators=1000, random_state=1000)
reg_gridsearch = GridSearchCV(reg, gridParams, cv=5, scoring='r2', n_jobs=-1) 
​
# 訓練模型 
reg_gridsearch.fit(X_train, y_train, early_stopping_rounds=100, eval_set=(X_val,y_val))
​
# 返回最佳參數 
reg_gridsearch.best_params_ 

代碼參考:https://gist.githubusercontent.com/daydreamersjp/0e588d805be6d6b755c68fa1e8095fc4/raw/e0eb0af142db38fb3ceb48b1f37e2a22671afd0a/gistfile2019120801.py

2.3 隨機搜索

隨機搜索是基於網格搜索的延伸,它與網格搜索一樣,需要預先指定超參數的候選集。隨機搜索會隨機的從參數候選集中選取參數,訓練模型。隨機搜索從由所有可能的超參數組合中隨機抽取“組合”以訓練模型,使用者可以通過設置最大迭代次數,來調節模型的運行次數。相對網格搜索而言,隨機搜索的計算成本更低,結果精度相對較低,它返回一個比較general的模型可能實現的水平。隨機搜索與網格搜索的返回值相同,均是各自策略下模型的最佳超參數。

隨機搜索還可以設置參數的密度函數,例如:均勻分佈或者正態分佈。

可以在如下庫中實現上述操作,如:sklearn中的RandomizedSearchCV。

隨機搜索的優勢:

  • 你可以通過控制參數搜索的次數,控制隨機搜索的運行成本。

隨機搜索的劣勢:

  • 它是一種“權衡”策略,運行成本和搜索精度的“權衡”。隨機搜索返回的最佳參數可能不是模型實際的最佳參數。
  • 由於設置最大搜索次數,因此,一些參數可能被遍歷的次數有限。
  • 隨機搜索不提供隨機抽取超參數的方法。

以LGBMRegressor模型爲例,分別設置了“max_depth”,“subsample”,“colsample_bytree”,“min_child_weight”,它的評分器爲“r2”,最大迭代次數爲20,代碼示例如下:

# 導入LGBMRegressor 
from lightgbm import LGBMRegressor
​
# 導入網格搜索 
from sklearn.model_selection import train_test_split, RandomizedSearchCV
​
# 可用於聲明參數分佈 
import scipy.stats as stats
​
import pandas as pd
import numpy as np
​
# 導入數據集,將數據集拆分爲訓練/測試集 
df = pd.read_csv('test.csv',index_col=0)
y = df['Target']
X = df.drop(['Target'],axis=1)
X_train0, X_test, y_train0, y_test = train_test_split(X,y,test_size=0.2, random_state= 2)
​
# 訓練集的比例 
r = 0.1 
trainLen = round(len(X_train0)*(1-r))
​
# 拆分訓練集和驗證集 
X_train = X_train0.iloc[:trainLen,:]
y_train = y_train0[:trainLen]
X_val = X_train0.iloc[trainLen:,:]
y_val = y_train0[trainLen:]
​
# 定義網格搜索空間 
randParams = {
    'max_depth': stats.randint(1,10), # 介於1到10的整數 
    'subsample': stats.uniform(0.6,1.0-0.6), # 介於0.6到1的值 
    'colsample_bytree': stats.uniform(0.6,1.0-0.6), # 介於0.6到1的值 
    'min_child_weight': stats.uniform(0.1,10.0-0.1), # 介於0.6到1的值  
}
​
# 定義lightgbm和網格搜索 
reg = LGBMRegressor(learning_rate=0.1, n_estimators=1000, random_state=1000)
reg_randsearch = RandomizedSearchCV(reg, randParams, cv=5, n_iter=20, scoring='r2', n_jobs=-1, random_state=2222) 
​
# 訓練模型 
reg_randsearch.fit(X_train, y_train, early_stopping_rounds=100, eval_set=(X_val,y_val))
## Final l2 was l2: 0.0212662.
​
# 返回最佳參數 
reg_randsearch.best_params_ 

代碼參考:https://gist.githubusercontent.com/daydreamersjp/d3e60e613f51bd223f8f153dca2ccb12/raw/8a2f28858a07e0f3e5878d2d3375780a63a80df4/gistfile2019120802.py

2.4 貝葉斯搜索

貝葉斯搜索又名貝葉斯優化。它是基於貝葉斯規則(如下圖所示),貝葉斯搜索是從隨機搜索開始,基於貝葉斯理論逐漸縮小搜索空間,即通過隨機搜索將可能超參數的先驗分佈更新爲後驗分佈。在考慮已知信息下幫助縮小“好的”超參數組合的搜索空間。 相較隨機搜索而言,貝葉斯搜索會花費更多時間,但仍比網格搜索花費更多時間。原理詳見如下鏈接。

 

圖片來源:luminousmen

貝葉斯搜索的優勢:

  • 搜索的效率較高。

貝葉斯搜索的劣勢:

  • 可能會落入局布最優化陷阱。

scikit-learn不提供貝葉斯隨機搜索的模塊,因此,此處代碼略。

 

(1)獲取更多優質內容及精彩資訊,可前往:https://www.cda.cn/?seo

(2)瞭解更多數據領域的優質課程:

 

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