[Machine Learning] 調校超參數 (R H2O Hyperparameter)

  • 3970
  • 0
  • 2019-05-06

前一篇Stack(Ensemble Model),使用多種模型組成,那究竟每一個模型的超參數如何去調整呢 ?

調整前後的差異在哪呢 ? 這篇文章就是教大家如何去做超參數的調校。

*本篇使用的是  R - H2O 

再開始前,先要跟大家建立一個觀念 - ParameterHyperparameter的差異

Parameter(參數) : 可以從訓練資料中的得到的,是機器學習算法的關鍵,像是平均值(μ)和標準差(sigma),這在機器學習中是有效的,這些參數可以用數據估計得到並用作預測模型的一部分。

具體來講,模型參數有以下特徵:

  • 進行模型預測時需要模型參數。
  • 模型參數值可以定義模型功能。
  • 模型參數用數據估計或數據學習得到。
  • 模型參數一般不由實踐者手動設置。
  • 模型參數通常作為學習模型的一部分保存。

Hyperparameter(超參數) : 通常是在模型訓練前,手動設置的,其值不能從數據估計得到。其目的是為了在訓練模型時表現得更出色。我們一般說的調參數,都是指的調校超參數。

具體來講,模型超參數有以下特徵:

  • 模型超參數常應用於估計模型參數的過程中。
  • 模型超參數通常由實踐者直接指定。
  • 模型超參數通常可以使用啟發式方法來設置。
  • 模型超參數通常根據給定的預測建模問題而調整。

而要怎樣找出超參數的最佳的數值呢 ? 通常有兩種方式

  1. 經驗法則 : 對於模型、資料有一定熟悉度,但是並不適用全部的情況。
  2. 反覆測試 : 給定範圍值,給電腦自動調校,較耗時但是能夠得到最佳數值。

我個人會兩種方式混合一起用,利用經驗法則給定每一個超參數範圍值,再由電腦自動去調校,可以省掉不少時間,得出來的結果也不錯。

一、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,也就是將每一個超參數給定範圍,電腦自己去跑組合

雖然會花一定的時間去跑模型,但總比你一個一個去輸入來的要快阿 ! 以下有範例給大家參考。

ntrees_opts = seq(50,1000,50)      
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
)
search_criteria = list(strategy = "RandomDiscrete", 
                       max_runtime_secs = 600, 
                       max_models = 100, 
                       stopping_metric = "logloss",
                       score_tree_interva = 5,
                       stopping_tolerance = 0.001, 
                       stopping_rounds = 3, 
                       seed = 123456).
gbm_grid <- h2o.grid("gbm", 
                     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去排序

#Hyper-Parameter Search Summary: ordered by increasing 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

(待續..........)