【问题标题】:MLR - calculating feature importance for bagged, boosted trees (XGBoost)MLR - 计算袋装增强树的特征重要性(XGBoost)
【发布时间】:2020-10-26 18:33:40
【问题描述】:

早上好,

我有一个关于在 R 中使用 MLR 包计算 baggedboosted 回归树模型的特征重要性的问题。我正在使用 XGBOOST 进行预测,我正在使用bagging 来估计预测的不确定性。我的数据集比较大;大约 10k 个特征和观察结果。预测工作完美(见下面的代码),但我似乎无法计算特征重要性(下面代码中的最后一行)。重要性函数崩溃而没有错误......并冻结了 R 会话。我看到了一些相关的 python 代码,人们似乎在其中计算每个袋装模型 herehere 的重要性。我也无法让它在 R 中正常工作。具体来说,我不确定如何访问 MLR 生成的对象中的各个模型(以下代码中的 mb 对象)。在 python 中,这似乎是微不足道的。在 R 中,我似乎无法提取 mb$learner.model,这在逻辑上似乎最接近我的需要。所以我想知道是否有人对此问题有任何经验?

请看下面的代码

learn1 <- makeRegrTask(data = train.all , target= "resp", weights = weights1)
lrn.xgb <- makeLearner("regr.xgboost", predict.type = "response")
lrn.xgb$par.vals <- list( objective="reg:squarederror", eval_metric="error", nrounds=300, gamma=0, booster="gbtree", max.depth=6)

lrn.xgb.bag = makeBaggingWrapper(lrn.xgb, bw.iters = 50, bw.replace = TRUE,  bw.size = 0.85, bw.feats = 1)
lrn.xgb.bag <- setPredictType(lrn.xgb.bag, predict.type="se")
mb = mlr::train(lrn.xgb.bag, learn1)

fimp1 <- getFeatureImportance(mb)

【问题讨论】:

  • getFeatureImportance() 采用包装模型,因此 mb 在这里应该没问题。另见?mlr::getLearnerModel()。也看看vignettes
  • @pat-s 谢谢。我在使用这些选项时遇到了一些有趣的错误。 mlr::getFeatureImportance(mb) 给了我Error in xgboost::xgb.importance(feature_names = .model$features, model = mod : model: must be an object of class xgb.Booster。但是,我可以提取单个模型mb1 &lt;- getLearnerModel(mb, more.unwrap = T),尝试获取单个模型mlr::getFeatureImportance(mb1[[1]]) 的重要性并获得Error: Assertion on 'object' failed: Must inherit from class 'WrappedModel', but has class 'xgb.Booster'。这在我看来像是课堂问题?
  • @pat-s 部分错误。 getFeatureImportance() 采用 WrappedModel,但由 BaggingWrapper 创建的模型是 HomogeneousEnsembleModelmlr 没有为此提供自己的方法。所以你必须手动聚合特征重要性值。但是,如果每个模型都像您的示例一样仅针对一个特征 (bw.feats = 1) 进行训练,则它将不起作用。
  • @jakob-r 谢谢。 bw.feats=1 指的是“随机选择的特征在包中的百分比大小”,因此每个模型都有很多特征。但感谢您的澄清。但是,如果我理解正确,我可以手动创建一个包含 50 个不同模型(相同的学习者但名称不同)的集合,然后 getFeatureImportance() 应该在集合上工作?
  • 对不起,你是对的。 bw.feats = 1 等于 100% 的特征,这是一个明智的决定。我发布了一个应该有效的答案。

标签: r machine-learning xgboost feature-selection mlr


【解决方案1】:

如果您设置bw.feats = 1,则平均特征重要性值可能是可行的。 基本上你只需要应用存储在HomogeneousEnsembleModel 中的所有单个模型。一些额外的小心是必要的,因为特征的顺序会因为采样而混淆 - 尽管我们将它设置为 100%。

library(mlr)
data = data.frame(x1 = runif(100), x2 = runif(100), x3 = runif(100))
data$y = with(data, x1 + 2 * x2 + 0.1 * x3 + rnorm(100))
task = makeRegrTask(data = data, target = "y")
lrn.xgb = makeLearner("regr.xgboost", predict.type = "response")
lrn.xgb$par.vals = list( objective="reg:squarederror", eval_metric="error", nrounds=50, gamma=0, booster="gbtree", max.depth=6)

lrn.xgb.bag = makeBaggingWrapper(lrn.xgb, bw.iters = 10, bw.replace = TRUE,  bw.size = 0.85, bw.feats = 1)
lrn.xgb.bag = setPredictType(lrn.xgb.bag, predict.type="se")
mb = mlr::train(lrn.xgb.bag, task)
fimps = lapply(mb$learner.model$next.model, function(x) getFeatureImportance(x)$res)
fimp = fimps[[1]]
# we have to take extra care because the results are not ordered
for (i in 2:length(fimps)) {
  fimp = merge(fimp, fimps[[i]], by = "variable")
}
rowMeans(fimp[,-1]) # only makes sense with bw.feats = 1
# [1] 0.2787052 0.4853880 0.2359068

【讨论】:

    猜你喜欢
    • 2019-12-13
    • 2016-03-17
    • 2018-08-16
    • 1970-01-01
    • 2021-02-04
    • 2021-09-07
    • 2019-12-19
    • 1970-01-01
    • 2019-09-01
    相关资源
    最近更新 更多