天天看點

使用H2O進行內建學習使用H2O進行內建學習

使用H2O進行內建學習

介紹

內建學習就是組合多個機器學習算法,進而得到更好的預測性能。許多流行的現代機器學習算法實際上就是內建。比如說随機森林 和 Gradient Boosting Machine (GBM)都是2個內建學習器。Bagging(例如随機森林)和boosting(例如GBM)是內建方法,其采用一系列弱學習器(例如,決策樹)來得到單個,強大的內建學習器。

H2O的Stacked內建算法是有監督的內建算法,通過stacking來找到分類器的最優組合方式。此方法目前支援回歸和二分類任務,計劃在将來的版本中提供多分類支援。

在版本3.10.3.1中,內建算法被添加到了H2O核心中,H2O将原生支援內建算法。R語言的h2oEnsemble包是一個獨立于H2O對該方法的一個實作,然而對于新項目,我們建議使用原生H2O版本,如下所述。

Stacking / Super Learning

Stacking也可以稱之為Super Learning 或Stacked Regression,是一類涉及訓練二級“元學習器”(或稱次級學習器)以找到初級學習器的最佳組合的算法。與bagging和boosting不同,stacking的目的是将強大的,多樣化的學習器集合在一起。

雖然stacking的概念最初是在1992年提出的,但是在2007年一篇叫“Super Learner”的論文出版之前,還沒有關于stacking的理論證明。在這篇論文中表明 Super Learner 內建代表一個漸近最優的學習系統。

一些集合方法被廣泛地稱為stacking,然而,Super Learner內建與其他方法的差別是,他是通過使用交叉驗證來形成所謂的“level-one”資料,這資料也可以說成是次級分類器或某種“組合”算法的訓練資料集。下面提供了更多關于Super Learner 算法的細節。

Super Learner Algorithm

以下步驟描述了在訓練和測試Super Learner內建中涉及的各個任務。H2O自動執行以下大部分步驟,以便您可以快速輕松地建構H2O內建模型。

  1. 配置內建
    1. 指定一個包含L個初級學習器的清單(使用一組特定的模型參數)。
    2. 指定一個次級學習器。
  2. 訓練內建模型
    1. 在訓練集上訓練每個初級學習器,共L個。
    2. 對每一個學習器中執行k折交叉驗證,并記錄L個分類器在每個交叉驗證上的預測值。
    3. 每一個初級學習器上的N個交叉驗證預測值可以組成一個新的N x L 矩陣,該矩陣與原始響應向量一起被稱為“level-one”資料(N=訓練集樣本數)。
    4. 在“level-one”資料上訓練次級學習器。這個“內建模型”包含L個初級學習器和一個次級學習器,然後可以用來在測試集上生成預測。
  3. 在新資料上進行預測
    1. 為了進行內建預測,我們首先從初級學習器上得到預測值。
    2. 将這些預測值送到次級學習器中進而産生內建預測。

定義一個H2O Stacked內建模型

  • model_id: 指定要應用的模型自定義名稱。 預設情況下,H2O會自動生成目标密鑰。
  • training_frame: 指定模型訓練集。
  • validation_frame: 指定模型驗證集。
  • selection_strategy: 指定選擇要stacking的模型的政策。注意,

    choose_all

    是目前唯一的選擇政策實作。
  • base_models: 指定可堆疊在一起的模型ID清單。模型必須使用

    nfolds

    > 1進行交叉驗證,它們都必須使用相同的折數進行交叉驗證,并且

    keep_cross_validation_folds

    必須設定為True。

關于基本模型:保證初級學習器之間完全相同折數的一種方法是在所有初級學習器中設定

fold_assignment

=“Modulo”。目前,使用

fold_assignment

=“Modulo”來訓練初級學習器是一個嚴格的要求,但在下一個版本中将放寬,可以允許使用者指定折數,或用相同的随機種子來随機産生折數。

另外在将來的版本中,将存在額外的次級學習器參數,允許使用者指定所使用的次級學習器算法。目前,次級學習器固定為具有非負權重的H2O GLM。

你可以在這裡看到 H2O’s Stacked Ensemble的發展進度。

例子

library(h2o)
h2o.init(nthreads = -)

# 讀入一個二分類資料
train <- h2o.importFile("https://s3.amazonaws.com/erin-data/higgs/higgs_train_10k.csv")
test <- h2o.importFile("https://s3.amazonaws.com/erin-data/higgs/higgs_test_5k.csv")
#若讀不進,先将網站輸入浏覽器中,再在本地讀取

# Identify predictors and response
y <- "response"
x <- setdiff(names(train), y)

# 指定2分類響應變量類别為因子
train[,y] <- as.factor(train[,y])
test[,y] <- as.factor(test[,y])

# 設定交叉驗證折數(為了産生level-one資料來進行stacking)
nfolds <- 



# 有如下幾種方法來組合模型清單以進行堆疊:
# 1. 逐個訓練模型并将它們放在一個清單裡
# 2. 用h2o.grid來訓練一個不同參數的模型
# 3. 用h2o.grid來訓練多個不同參數的模型
# 注意: 所有的初級學習器必須具有相同的交叉驗證折數,并且交叉驗證預測值必須保留。


# 1. 2個模型的內建 (GBM + RF)

# Train & Cross-validate a GBM
my_gbm <- h2o.gbm(x = x,
                  y = y,
                  training_frame = train,
                  distribution = "bernoulli",
                  ntrees = ,
                  max_depth = ,
                  min_rows = ,
                  learn_rate = ,
                  nfolds = nfolds,
                  fold_assignment = "Modulo",
                  keep_cross_validation_predictions = TRUE,
                  seed = )

# Train & Cross-validate a RF
my_rf <- h2o.randomForest(x = x,
                          y = y,
                          training_frame = train,
                          ntrees = ,
                          nfolds = nfolds,
                          fold_assignment = "Modulo",
                          keep_cross_validation_predictions = TRUE,
                          seed = )

# Train a stacked ensemble using the GBM and RF above
ensemble <- h2o.stackedEnsemble(x = x,
                                y = y,
                                training_frame = train,
                                model_id = "my_ensemble_binomial",
                                base_models = list([email protected]_id, [email protected]_id))

#在測試集上評估內建模型性能
perf <- h2o.performance(ensemble, newdata = test)

# 比較初級學習器在測試集上的性能
perf_gbm_test <- h2o.performance(my_gbm, newdata = test)
perf_rf_test <- h2o.performance(my_rf, newdata = test)
baselearner_best_auc_test <- max(h2o.auc(perf_gbm_test), h2o.auc(perf_rf_test))
ensemble_auc_test <- h2o.auc(perf)
print(sprintf("Best Base-learner Test AUC:  %s", baselearner_best_auc_test))
print(sprintf("Ensemble Test AUC:  %s", ensemble_auc_test))

#在訓練集上産生預測 
pred <- h2o.predict(ensemble, newdata = test)



# 2. Generate a random grid of models and stack them together

# GBM 超參數
learn_rate_opt <- c(, )
max_depth_opt <- c(, , , , )
sample_rate_opt <- c(, , , )
col_sample_rate_opt <- c(, , , , , , )
hyper_params <- list(learn_rate = learn_rate_opt,
                     max_depth = max_depth_opt,
                     sample_rate = sample_rate_opt,
                     col_sample_rate = col_sample_rate_opt)

search_criteria <- list(strategy = "RandomDiscrete",
                        max_models = ,
                        seed = )

gbm_grid <- h2o.grid(algorithm = "gbm",
                     grid_id = "gbm_grid_binomial",
                     x = x,
                     y = y,
                     training_frame = train,
                     ntrees = ,
                     seed = ,
                     nfolds = nfolds,
                     fold_assignment = "Modulo",
                     keep_cross_validation_predictions = TRUE,
                     hyper_params = hyper_params,
                     search_criteria = search_criteria)

#使用GBM網格參數來訓練一個stacked ensemble模型 
ensemble <- h2o.stackedEnsemble(x = x,
                                y = y,
                                training_frame = train,
                                model_id = "ensemble_gbm_grid_binomial",
                                base_models = [email protected]_ids)

# 在測試集上評估內建模型性能
perf <- h2o.performance(ensemble, newdata = test)

# 在測試集上比較初級學習器性能
.getauc <- function(mm) h2o.auc(h2o.performance(h2o.getModel(mm), newdata = test))
baselearner_aucs <- sapply([email protected]_ids, .getauc)
baselearner_best_auc_test <- max(baselearner_aucs)
ensemble_auc_test <- h2o.auc(perf)
print(sprintf("Best Base-learner Test AUC:  %s", baselearner_best_auc_test))
print(sprintf("Ensemble Test AUC:  %s", ensemble_auc_test))

# 在訓練集上産生預測 
pred <- h2o.predict(ensemble, newdata = test)
           

FAQ

  • 內建模型總是比單個模型更好嗎?
希望是這樣,但并不總是如此。這就是為什麼總要檢查你的內建模型性能,并将其與個體初級學習器的性能進行比較。
  • 怎麼提高內建模型的性能

如果你發現你的內建模型性能不如最優的初級學習器,那麼你可以嘗試幾個不同的東西。

首先,看看是否有初級學習器的表現比其他初級學習器差很多(例如,GLM)。若有,将它從內建模型中移除,并在此模組化。

其次,你應該增加初級學習器的個數,特别是增加初級學習器的多樣性。

未來新版本中添加了自定義次級學習器 支援,你可以嘗試不同的次級學習器。

  • 該算法如何處理響應變量中的高度不平衡資料
在初級學習器中指定

balance_classes

,

class_sampling_factors

max_after_balance_size

來進行過抽樣或者欠抽樣。

拓展閱讀

  • 2017年1月的Ensemble slidedeck提供了H2O中新的Stacked Ensemble方法的概述,以及與以前存在的h2oEnsemble R軟體包的比較。

參考文獻

David H. Wolpert. “Stacked Generalization.” Neural Networks. Volume 5. (1992)

Leo Breiman. “Stacked Regressions.” Machine Learning, 24, 49-64 (1996)

Mark J van der Laan, Eric C Polley, and Alan E Hubbard. “Super Learner.” Journal of the American Statistical Applications in Genetics and Molecular Biology. Volume 6, Issue 1. (September 2007).

LeDell, E. “Scalable Ensemble Learning and Computationally Efficient Variance Estimation” (Doctoral Dissertation). University of California, Berkeley, USA. (2015)

原文位址:http://docs.h2o.ai/h2o/latest-stable/h2o-docs/data-science/stacked-ensembles.html#defining-an-h2o-stacked-ensemble-model

作為分享主義者(sharism),本人所有網際網路釋出的圖文均遵從CC版權,轉載請保留作者資訊并注明作者a358463121專欄:http://blog.csdn.net/a358463121,如果涉及源代碼請注明GitHub位址:https://github.com/358463121/。商業使用請聯系作者。

繼續閱讀