【译】使用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上看到同样的文章,不要惊讶,那是我基友,一块儿翻译的- -。