集成学习就是组合多个机器学习算法,从而得到更好的预测性能。许多流行的现代机器学习算法实际上就是集成。比如说随机森林 和 Gradient Boosting Machine (GBM)都是2个集成学习器。Bagging(例如随机森林)和boosting(例如GBM)是集成方法,其采用一系列弱学习器(例如,决策树)来得到单个,强大的集成学习器。
H2O的Stacked集成算法是有监督的集成算法,通过stacking来找到分类器的最优组合方式。此方法目前支持回归和二分类任务,计划在将来的版本中提供多分类支持。
在版本3.10.3.1中,集成算法被添加到了H2O内核中,H2O将原生支持集成算法。R语言的h2oEnsemble包是一个独立于H2O对该方法的一个实现,然而对于新项目,我们建议使用原生H2O版本,如下所述。
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集成中涉及的各个任务。H2O自动执行以下大部分步骤,以便您可以快速轻松地构建H2O集成模型。
choose_all
是当前唯一的选择策略实现。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)
希望是这样,但并不总是如此。这就是为什么总要检查你的集成模型性能,并将其与个体初级学习器的性能进行比较。
如果你发现你的集成模型性能不如最优的初级学习器,那么你可以尝试几个不同的东西。
首先,看看是否有初级学习器的表现比其他初级学习器差很多(例如,GLM)。若有,将它从集成模型中移除,并在此建模。
其次,你应该增加初级学习器的个数,特别是增加初级学习器的多样性。
未来新版本中添加了自定义次级学习器 支持,你可以尝试不同的次级学习器。
在初级学习器中指定
balance_classes
,class_sampling_factors
和max_after_balance_size
来进行过抽样或者欠抽样。
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/。商业使用请联系作者。