【譯】使用H2O進行集成學習【2】

使用H2O進行集成學習html

介紹算法

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

H2O的Stacked集成算法是有監督的集成算法,經過stacking來找到分類器的最優組合方式。此方法目前支持迴歸和二分類任務,計劃在未來的版本中提供多分類支持。app

在版本3.10.3.1中,集成算法被添加到了H2O內核中,H2O將原生支持集成算法。R語言的h2oEnsemble包是一個獨立於H2O對該方法的一個實現,然而對於新項目,咱們建議使用原生H2O版本,以下所述。dom

Stacking / Super Learning機器學習

Stacking也能夠稱之爲Super Learning 或Stacked Regression,是一類涉及訓練二級「元學習器」(或稱次級學習器)以找到初級學習器的最佳組合的算法。與bagging和boosting不一樣,stacking的目的是將強大的,多樣化的學習器集合在一塊兒。ide

雖然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 = -1)

# 讀入一個二分類數據
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 <- 5



# 有以下幾種方法來組合模型列表以進行堆疊:
# 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 = 10,
                  max_depth = 3,
                  min_rows = 2,
                  learn_rate = 0.2,
                  nfolds = nfolds,
                  fold_assignment = "Modulo",
                  keep_cross_validation_predictions = TRUE,
                  seed = 1)

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

# 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(my_gbm@model_id, my_rf@model_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(0.01, 0.03)
max_depth_opt <- c(3, 4, 5, 6, 9)
sample_rate_opt <- c(0.7, 0.8, 0.9, 1.0)
col_sample_rate_opt <- c(0.2, 0.3, 0.4, 0.5, 0.6, 0.7, 0.8)
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 = 3,
                        seed = 1)

gbm_grid <- h2o.grid(algorithm = "gbm",
                     grid_id = "gbm_grid_binomial",
                     x = x,
                     y = y,
                     training_frame = train,
                     ntrees = 10,
                     seed = 1,
                     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 = gbm_grid@model_ids)

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

# 在測試集上比較初級學習器性能
.getauc <- function(mm) h2o.auc(h2o.performance(h2o.getModel(mm), newdata = test))
baselearner_aucs <- sapply(gbm_grid@model_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...

若是你在csdn上看到同樣的文章,不要驚訝,那是我基友,一塊兒翻譯的- -。

相關文章
相關標籤/搜索