前一篇Stack(Ensemble Model),使用多種模型組成,那究竟每一個模型的超參數如何去調整呢 ?
調整前後的差異在哪呢 ? 這篇文章就是教大家如何去做超參數的調校。
*本篇使用的是 R - H2O
再開始前,先要跟大家建立一個觀念 - Parameter與Hyperparameter的差異
Parameter(參數) : 可以從訓練資料中的得到的,是機器學習算法的關鍵,像是平均值(μ)和標準差(sigma),這在機器學習中是有效的,這些參數可以用數據估計得到並用作預測模型的一部分。
具體來講,模型參數有以下特徵:
- 進行模型預測時需要模型參數。
- 模型參數值可以定義模型功能。
- 模型參數用數據估計或數據學習得到。
- 模型參數一般不由實踐者手動設置。
- 模型參數通常作為學習模型的一部分保存。
Hyperparameter(超參數) : 通常是在模型訓練前,手動設置的,其值不能從數據估計得到。其目的是為了在訓練模型時表現得更出色。我們一般說的調參數,都是指的調校超參數。
具體來講,模型超參數有以下特徵:
- 模型超參數常應用於估計模型參數的過程中。
- 模型超參數通常由實踐者直接指定。
- 模型超參數通常可以使用啟發式方法來設置。
- 模型超參數通常根據給定的預測建模問題而調整。
而要怎樣找出超參數的最佳的數值呢 ? 通常有兩種方式
- 經驗法則 : 對於模型、資料有一定熟悉度,但是並不適用全部的情況。
- 反覆測試 : 給定範圍值,給電腦自動調校,較耗時但是能夠得到最佳數值。
我個人會兩種方式混合一起用,利用經驗法則給定每一個超參數範圍值,再由電腦自動去調校,可以省掉不少時間,得出來的結果也不錯。
一、H2O - GBM
一般我們再訓練GBM模型的寫法,超參數的值都是手動去調
gbm1 <- h2o.gbm(x = x, y = y, distribution = "bernoulli",
training_frame = LOL_train_h2o,
seed = 123456,
nfolds =5,
col_sample_rate = 0.4,
col_sample_rate_per_tree = 0.85,
learn_rate = 0.04,
max_depth = 23,
min_rows = 100,
ntrees = 700,
sample_rate = 0.75,
fold_assignment = "Modulo",
keep_cross_validation_predictions = TRUE)
# training_frame = LOL_train_h2o ,設置訓練資料,記得轉換H2O DataFrame格式。
# seed ,設定種子。
# nfolds ,設定交叉驗證折數(延續上一篇,為了產生level-one資料來進行stacking)。
# col_sample_rate ,sample X% of columns per split。
# col_sample_rate_per_tree , search a large space of column sampling rates per tree。
# learn_rate ,控制模型的學習速度 ,個人認為這是超參數中最重要的ㄧ個。
# max_depth,每棵樹的最大深度。
# ntrees,構建模型時要生成的樹的棵樹。
# min_rows,This option specifies the minimum number of observations for a leaf in order to split.
#sample_rate,This option is used to specify the row (x-axis) sampling rate (without replacement). The range is 0.0 to 1.0.
#fold_assignment,劃分數據,有四個方法,如果你有做CV通常都是使用Modulo,以下有詳細的介紹。
- Auto: Allow the algorithm to automatically choose an option. Auto currently uses Random.
- Random: Randomly split the data into
nfolds
pieces. (Default) - Modulo: Performs modulo operation when splitting the folds.
- Stratified: Stratifies the folds based on the response variable for classification problems.
這種要一個個去設定時在太麻煩了,因此H2O有一個很方便的方式就是寫grid,也就是將每一個超參數給定範圍,電腦自己去跑組合
雖然會花一定的時間去跑模型,但總比你一個一個去輸入來的要快阿 ! 以下有範例給大家參考。
max_depth_opts = seq(1,30,2)
min_rows_opts = c(1,5,70,60,50,100)
learn_rate_opts = seq(0.01,1,0.01)
sample_rate_opts = seq(0.3,1,0.05)
col_sample_rate_opts = seq(0.3,1,0.05)
col_sample_rate_per_tree_opts = seq(0.3,1,0.05)
#nbins_cats_opts = seq(100,10000,100) # no categorical features
#assignment_type <- c("AUTO", "Random", "Modulo", "Stratified")
# build grid search with previously selected hyperparameters
hyper_params = list( ntrees = ntrees_opts,
max_depth = max_depth_opts,
min_rows = min_rows_opts,
learn_rate = learn_rate_opts,
sample_rate = sample_rate_opts,
col_sample_rate = col_sample_rate_opts,
col_sample_rate_per_tree = col_sample_rate_per_tree_opts
#,nbins_cats = nbins_cats_opts
)
max_runtime_secs = 600,
max_models = 100,
stopping_metric = "logloss",
score_tree_interva = 5,
stopping_tolerance = 0.001,
stopping_rounds = 3,
seed = 123456).
grid_id = "gbm_grid",
x = x,
y = y,
training_frame = LOL_train_h2o,
nfolds = nfolds,
fold_assignment = "Modulo",
search_criteria = search_criteria,
hyper_params = hyper_params)
hyper_params,上面都有詳細說明了,就不說明範圍值的限制官網文件都有說明,請參閱。
而當你的超參數範圍設太廣,以即要去避免overfitting,search_criteria這部分就分常重要。
# max_runtime_secs,每一次最多跑幾秒。
# max_models,只取最好前N個模型。
# stopping_metric,是你的評測函式,在這裡我們使用logloss。
# score_tree_interval,引數是隨機森林和GBM的特有引數。設定score_tree_interval = 5將在每五棵樹之後計算得分。
# stopping_rounds & stopping_tolerance,設定的引數指定模型將在三次評分間隔後停止訓練,若logloss增加沒有超過 0.001。
最後執行h2o.grid,就可以去做別的事情拉 !
最後結果如下圖 : 我只show兩個結果,上面設定值是100,所以全部就會給100個優化模型的超參數,依據logloss去排序
#col_sample_rate col_sample_rate_per_tree learn_rate max_depth min_rows ntrees sample_rate model_ids logloss
#1 0.8 0.35 0.34 23 50.0 100 0.8 gbm_grid_model_8 0.023587976931989343
#2 0.4 0.85 0.04 23 100.0 700 0.75 gbm_grid_model_23 0.03183414791635836
(待續..........)