【问题标题】:Apply weights in rpart model gives error在 rpart 模型中应用权重会产生错误
【发布时间】:2014-04-11 02:39:37
【问题描述】:

我正在使用rpart 包来适应某些模型,如下所示:

fitmodel = function(formula, data, w) {

    fit = rpart(formula, data, weights = w)
}

调用自定义函数

fit = fitmodel(y ~ x1 + x2, data, w)

这会导致错误:

Error in eval(expr, envir, enclos) : object 'w' not found

然后我决定使用

fitmodel = function(formula, data, w) {

    data$w = w
    fit = rpart(formula, data, weights = w)
}

这可行,但还有另一个问题:

这会起作用

fit = fitmodel(y ~ x1 + x2, data, w)

这不起作用

fit = fitmodel(y ~ ., data, w)

Error in eval(expr, envir, enclos) : object 'w' not found

在自定义函数中应用权重的正确方法是什么?谢谢!

【问题讨论】:

  • 试试environment(formula) = sys.frame(sys.nframe())。这可能是因为公式在与函数(可能是全局环境)不同的环境中定义,rpart 将在其中查找变量。
  • 哪种情况?谢谢!
  • 第一种情况。你是从另一个函数中调用这个函数吗?
  • 是的,有一个调用链。
  • 您是否正在编写自己的 adaboost 实现?

标签: r function rpart


【解决方案1】:

希望其他人给出更完整的答案。 rpart 找不到 w 的原因是 rpart 在定义公式的环境中搜索数据、权重等。公式是在某些环境中创建的,很可能是 GlobalEnv 和 @ 987654325@ 是在其他函数中创建的。将公式的环境更改为使用parent.frame 创建w 的环境可以解决此问题。 rpart 仍然可以找到数据,因为搜索路径将始终继续到 GlobalEnv。我不确定为什么 sys.frame(sys.nframe()) 可以工作,因为环境不一样,但显然 w 仍然在搜索路径上

编辑:sys.frame(sys.nframe()) 似乎与将论坛的环境设置为调用函数rpart 的环境相同(在此示例中为foo3)。在这种情况下,rpartfoo3 中查找wdata 等,然后是bar3,然后是GlobalEnv

library(rpart)
data(iris)

bar <- function(formula, data) {
   w <- rpois(nrow(iris), 1)
   print(environment())
   foo(formula, data, w)
}

foo <- function(formula, data, w) {
  print(environment(formula))
  fit <- rpart(formula, data, weights = w)
  return(fit)
}


bar(I(Species == "versicolor") ~ ., data = iris)
## <environment: 0x1045b1a78>
## <environment: R_GlobalEnv>
## Error in eval(expr, envir, enclos) (from #2) : object 'w' not found


bar2 <- function(formula, data) {
  w <- rpois(nrow(iris), 1)
  print(environment())
  foo2(formula, data, w)
}

foo2 <- function(formula, data, w) {
  print(environment(formula))
  environment(formula) <- parent.frame()
  print(environment(formula))
  fit <- rpart(formula, data, weights = w)
  return(fit)
}

bar2(I(Species == "versicolor") ~ ., data = iris)
## <environment: 0x100bf5910>
## <environment: R_GlobalEnv>
## <environment: 0x100bf5910>


bar3 <- function(formula, data) {
  w <- rpois(nrow(iris), 1)
  print(environment())
  foo3(formula, data, w)
}

foo3 <- function(formula, data, w) {
  print(environment(formula))
  environment(formula) <- environment() ## seems to be the same as sys.frame(sys.nframe())
  print(environment(formula))
  print(environment())
  fit <- rpart(formula, data, weights = w)
  return(fit)
}

bar3(I(Species == "versicolor") ~ ., data = iris)
## <environment: 0x104e11bb8>                                                                                                                                                                                                                 
## <environment: R_GlobalEnv>                                                                                                                                                                                                                 
## <environment: 0x104b4ff78>                                                                                                                                                                                                                 
## <environment: 0x104b4ff78>

【讨论】:

  • 谢谢,我会努力更好地理解这一点!
  • @Fernando 我弄清楚了为什么最后一个示例有效并编辑了答案。希望编辑有意义并更好地解释事情。
【解决方案2】:

根据 rpart 文档(2017 年 3 月 12 日,第 23 页,第 6.1 节),“尚不支持权重,如果存在,将被忽略。”

https://cran.r-project.org/web/packages/rpart/vignettes/longintro.pdf

【讨论】:

  • 虽然当你添加权重时它确实会对答案产生影响!可能文档有误!
  • 好的,我联系了作者,这个评论已经过时了。确实实现了权重。
【解决方案3】:

我已经设法使用下面的代码解决了这个问题,但我确信有更好的方法:

弱学习者

fitmodel = function(formula, data, w) {

    # just paste the weights into the data frame
    data$w = w
    rpart(formula, data, weights = w, control = rpart.control(maxdepth = 1))
}

算法

ada.boost = function(formula, data, wl.FUN = fitmodel, test.data = NULL, M = 100) {

    # Just rewrites the formula and get ride of any '.'
     dep.var = all.vars(formula)[1]
     vars = attr(terms(formula, data = data), "term.labels")
     formula = as.formula(paste(dep.var, "~", paste(vars, collapse = "+")))


    # ...more code
}

现在一切正常!

【讨论】:

  • Hola @Fernando, rpart 函数中 weights 参数的目的是什么?我查看了文档,但没有找到任何解释。权重可以是任意实数还是需要为 [0,1]?谢谢。
  • 我猜它们是您想为每个观察提供的初始“重要性”。默认情况下,每个样本的权重都是 1,但我不确定。
猜你喜欢
  • 2017-09-13
  • 2020-07-20
  • 1970-01-01
  • 1970-01-01
  • 2020-12-30
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-02-24
相关资源
最近更新 更多