R中随机森林分类中一组预测变量的相对重要性


31

我想确定变量集对randomForestR中的分类模型的相对重要性。该importance函数MeanDecreaseGini为每个单独的预测变量提供度量标准-是否像对集合中的每个预测变量求和一样简单?

例如:

# Assumes df has variables a1, a2, b1, b2, and outcome
rf <- randomForest(outcome ~ ., data=df)
importance(rf)
# To determine whether the "a" predictors are more important than the "b"s,
# can I sum the MeanDecreaseGini for a1 and a2 and compare to that of b1+b2?

Answers:


46

首先,我想澄清一下重要性指标的实际作用。

MeanDecreaseGini是一种用于衡量重要程度的变量,该指标基于用于训练期间分裂计算的基尼杂质指数。一个常见的误解是,变量重要性度量是指用于声明模型性能的基尼,基尼与AUC密切相关,但这是错误的。这是Breiman和Cutler编写的randomForest软件包的解释:

基尼重要性
每次在变量m上分割节点时,两个后代节点的基尼杂质准则都小于父节点。将森林中所有树木上每个变量的基尼系数加起来得出的快速变量重要性通常与排列重要性度量非常一致。

G=一世=1个ñCp一世1个-p一世
ñCp一世是这个类的比率。

对于两类问题,这将导致以下曲线,该曲线对于50-50样本最大,对于齐次集合最小: 基尼2级杂质

一世=Gp一种[RËñŤ-Gsp一世Ť1个-Gsp一世Ť2

Ë[Ë[X|ÿ]]=Ë[X]

现在,直接回答您的问题并不只是简单地总结每个组中的所有重要性以得到合并的MeanDecreaseGini,而是计算加权平均值将为您找到所需的答案。我们只需要找到每个组中的可变频率即可。

这是一个简单的脚本,可以从R中的随机森林对象中获取它们:

var.share <- function(rf.obj, members) {
  count <- table(rf.obj$forest$bestvar)[-1]
  names(count) <- names(rf.obj$forest$ncat)
  share <- count[members] / sum(count[members])
  return(share)
}

只需传入组中变量的名称作为members参数即可。

我希望这回答了你的问题。如果感兴趣,我可以编写一个函数直接获取组的重要性。

编辑:
这是一个函数,它给定randomForest对象的重要性和带有变量名的向量列表,从而赋予组重要性。它使用var.share如先前定义的。我没有进行任何输入检查,因此您需要确保使用正确的变量名。

group.importance <- function(rf.obj, groups) {
  var.imp <- as.matrix(sapply(groups, function(g) {
    sum(importance(rf.obj, 2)[g, ]*var.share(rf.obj, g))
  }))
  colnames(var.imp) <- "MeanDecreaseGini"
  return(var.imp)
}

用法示例:

library(randomForest)                                                          
data(iris)

rf.obj <- randomForest(Species ~ ., data=iris)

groups <- list(Sepal=c("Sepal.Width", "Sepal.Length"), 
               Petal=c("Petal.Width", "Petal.Length"))

group.importance(rf.obj, groups)

>

      MeanDecreaseGini
Sepal         6.187198
Petal        43.913020

它也适用于重叠的组:

overlapping.groups <- list(Sepal=c("Sepal.Width", "Sepal.Length"), 
                           Petal=c("Petal.Width", "Petal.Length"),
                           Width=c("Sepal.Width", "Petal.Width"), 
                           Length=c("Sepal.Length", "Petal.Length"))

group.importance(rf.obj, overlapping.groups)

>

       MeanDecreaseGini
Sepal          6.187198
Petal         43.913020
Width          30.513776
Length        30.386706

感谢您明确而严格的回答!如果您不介意为组的重要性添加功能,那将很棒。
Max Ghenis 2014年

感谢您的回答!如果有时间,请回答两个问题:(1)然后将重要性计算为...:关于Breiman的定义,是那里的“基尼减少”,而重要性将是减少的总和,正确的?(2)对涉及问题的预测变量的森林中的所有分割取平均值:我可以用涉及该特定特征的所有分割的节点替换它吗?确保我完全理解;)
RemiMélisson2014年

1
您的评论使我对定义有了更多的思考,因此我翻阅了R中使用的randomForest代码以正确回答它。老实说,我有点不对劲。对所有树而不是所有节点进行平均。我会在有时间的时候尽快更新答案。以下是您当前问题的答案:(1)是。这是在树级别定义的方式。然后将所有树的减少总和平均。(2)是的,这就是我要说的,但实际上并没有成立。
虽然

4

上面在类[pi(1-pi)]上定义为G = sum的函数实际上是熵,这是评估拆分的另一种方式。子节点和父节点的熵之间的差异是信息增益。GINI杂质函数在类[pi ^ 2]上为G = 1和。

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.