【问题标题】:Numeric Comparison Precision in R; passing values between functionsR中的数值比较精度;在函数之间传递值
【发布时间】:2013-12-08 00:29:48
【问题描述】:

看了这个问题后:Numeric comparison difficulty in R

我仍然卡住了,因为我依赖于在某些我无法编​​辑(或者我可以吗?)的函​​数中进行的等式比较

我在本地环境中测试三个数字的总和是否为一个 (sum(p)==1 --> TRUE),但是当我将这个由三个数字组成的向量传递给另一个函数时,类似的相等性测试失败 - 这让我认为这些数字正在当它们从一个函数传递到下一个函数时发生变化 - 这可能吗?

更多细节:我正在尝试“优化”输入 CART 模型的先验概率,使用优化器 (dfoptim package, nmkb) 选择先验组合,将它们发送到 rpart 包进行模型拟合,然后用于评分的验证(rps 函数)包 - 但在 rpart 包中的某处,我的先验概率抛出错误,因为rpart 认为它们总和为 1。 p>

这是一个可重现的例子:

require('rpart')
require('verification')
require('dfoptim')
data(iris)
set.seed(1)
tmp1 <- paste0(names(iris),collapse="+")
tmp2 <- gsub("\\+Species","",tmp1)
fmlatext <- paste0("Species~",tmp2)
tree <- rpart(as.formula(fmlatext),data=iris,method="class")
objfun <- function(priors,fmlatext,data){
  p <- priors/sum(priors) # turn arbitrary threesome into numbers that sum to 1
  p[1] <- 1-(sum(p)-p[1]) # ensure that numbers sum to 1
  print(c(p,sum(p)),digits=16)
  tree <- rpart(as.formula(fmlatext),data=data,parms=list(prior=p),
                method="class") 
  rpst <- rps(data$Species,predict(tree,data=data))
  return(rpst$rpss)
}
nlev <- nlevels(iris$Species)
guess <- seq(nlev)*10
lb <- rep(1,nlev)
ub <- rep(100,nlev)
bestpriors <- nmkb(par=guess,fn=objfun,lower=lb,upper=ub,
                   control=list(maximize=TRUE),fmlatext=fmlatext,data=iris)

运行这段代码会给我这个输出:

[1] 0.1666666666666667 0.3333333333333333 0.5000000000000000 1.0000000000000000
[1] 0.4353687449261023 0.2354416940871099 0.3291895609867877 1.0000000000000000
[1] 0.1224920651311070 0.5548713793562775 0.3226365555126156 1.0000000000000000
[1] 0.1268712138061573 0.2390044736120877 0.6341243125817551 1.0000000000000000
[1] 0.35141687748184969 0.57028058689316308 0.07830253562498726 1.00000000000000000
[1] 0.2997590406445614 0.5077659444797995 0.1924750148756391 1.0000000000000000
[1] 0.3598141573675122 0.4350423262345758 0.2051435163979119 0.9999999999999999
Error in get(paste("rpart", method, sep = "."), envir = environment())(Y,  : 
  Priors must sum to 1

在我的真实代码中,这种情况不一致地发生,具体取决于数据和猜测值,但它确实发生了,而且真的很痛苦。

我怎样才能克服这个错误? 干杯,R

【问题讨论】:

  • 如果将输入 (p) 截断为 3 或 4 位精度会怎样?错误还会继续吗?
  • 截断是什么意思?我试过p &lt;- round(priors/sum(priors),2) 并在实践中仍然看到错误。
  • 为什么不创建一个额外的虚拟变量,'leftover
  • Carl - 我不确定这会有什么帮助 - 问题是我正在发送三个数字,它们的总和为 1 [在objfun 环境中] 到 rpart,但是当rpart 检查它们,它们不再等于 1。leftover 将如何帮助我?

标签: r precision equality rpart


【解决方案1】:

可能的答案;不确定它是否健壮,但我创建了这个函数,它适用于一些之前对我来说失败的测试用例:

makeSumToOne <- function(vec) {
  p <- round(1024*vec/sum(vec),0)
  p[1] <- 1024-(sum(p)-p[1])
  p <- p/1024
  return(p)
}

并在原始代码中替换这些行:

  p <- priors/sum(priors) # turn arbitrary threesome into numbers that sum to 1
  p[1] <- 1-(sum(p)-p[1]) # ensure that numbers sum to 1

用这个:

  p <- makeSumToOne(priors)

我正在阅读有关精度的文章,并注意到“2 的幂”经常出现,所以我认为在我的程序中使用“2 的幂”2^10=1024 可能会有所帮助......到目前为止它很有帮助,但我怀疑它很健壮。除非没有人想出更好的答案,否则我不会将此视为答案。 (或解释为什么此解决方案有效,以及带有roundsignif 或其他功能的解决方案失败。)

【讨论】:

    猜你喜欢
    • 2016-10-29
    • 1970-01-01
    • 2015-09-12
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-10-10
    相关资源
    最近更新 更多