Точность числового сравнения в R; передача значений между функциями

Посмотрев на этот вопрос: Сложность числового сравнения в R

Я все еще застрял, потому что я зависел от сравнения на равенство, которое глубоко в какой-то функции, которую я не могу редактировать (или я могу?)

Я проверяю в локальной среде, совпадают ли три числа к одному (sum(p)==1 --> TRUE), но когда я передаю этот вектор из трех чисел в другую функцию, подобный тест на равенство не выполняется - что заставляет меня думать, что числа меняются при переходе от одной функции к другой - возможно ли это?

Более подробно: я пытаюсь "оптимизировать" предыдущие вероятности, которые входят в модель CART, используя оптимизатор (dfoptim package, nmkb) выбрать комбинации априорных значений, отправив их в пакет rpart для подгонки модели, затем для проверки (rps функция) пакет для оценки - но где-то в rpart пакет, мои предыдущие вероятности выдают ошибку, потому что rpart считает, что они не составляют 1.

Вот воспроизводимый пример:

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

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 в моей программе может помочь... это помогает до сих пор, но я сомневаюсь, что это надежно. Я не считаю это ответом, если никто не придумает лучшего. (или объяснение того, почему это решение работает, и решения с round, signif или другие функции не работают.)

Другие вопросы по тегам