【问题标题】:R global optimization problem with potential warnings/errors and the use of tryCatch具有潜在警告/错误和使用 tryCatch 的 R 全局优化问题
【发布时间】:2021-09-01 05:55:41
【问题描述】:

简单地说,我有一个函数f(x, t2),我想找到x 的值,它使f(x, t2) 相对于t2 的积分最大化。我选择 pso 算法进行优化。可执行代码如下

library(pso)
xl=0; xu=2000; n=1; t2l=100; t2u=2000; t1=1
g<-function(x, t2) t1*x/(t2+x)
h<-function(z) 1/z^n
gdot<-function(x, t2){
  c(x/(t2+x),-t1*x/(t2+x)^2)
}
logdetHinv<-function(dp, dw, t2){
  gmat=mapply(function(x) gdot(x,t2),dp)
  D0=gmat%*%diag(dw)%*%t(gmat)
  D1=gmat%*%diag(1/h(g(dp,t2)))%*%diag(dw)%*%t(gmat)
  2*log(det(D1))-log(det(D0))
}
obj<-function(x){
  dp=x[1:2]; dw=c(x[3],1-x[3])
  fitness_value=-integrate(Vectorize(function(t2) logdetHinv(dp, dw, t2)*1/(t2u-t2l)), t2l, t2u)$value
  return(ifelse(dw[2]>0, fitness_value, fitness_value+1e3))
}

x <- psoptim(rep(1,3), fn = obj, lower = c(rep(xl,2),0.1), upper = c(rep(xu,2), 0.9))$par
x

由于全局优化涉及一些随机过程,因此有时会报告正确的结果

> x
[1] 2000.0000  754.4146    0.5000

其他时候报错

Error in integrate(Vectorize(function(t2) logdetHinv(dp, dw, t2) * 1/(t2u -  : 
  non-finite function value
In addition: There were 11 warnings (use warnings() to see them)
> warnings()
Warning messages:
1: In log(det(D1)) : NaNs produced
2: In log(det(D0)) : NaNs produced
3: In log(det(D1)) : NaNs produced
4: In log(det(D0)) : NaNs produced

我想该算法尝试记录logdetHinv 中的一些负值,它返回带有警告消息的NaN,还不是错误,最后导致integrate 中的错误。

我想避免这样的值,可能用tryCatch,比如如果函数logdetHinv有警告,它返回一个很小的值,但不是NaN,所以不会导致@987654334出错@,而psoptim 在最大化目标函数(最小化-integrate(logdetHinv))时不太可能选择这样的值。在这种复杂的情况下,我不熟悉tryCatch。我应该把tryCatch 放在哪里?谢谢。

此外,我想知道 R 中是否有一些调试技术可以让我知道在这种情况下是什么随机值 (D0/D1) 导致了错误。我猜它是 log 中的一些负值,但它不应该,因为 log 内部是正定矩阵的行列式。在回溯模式下,在浏览中,如果我输入D0,将找不到对象'D0'。

【问题讨论】:

  • tryCatch({2*log(det(D1))-log(det(D0))}, warning = function(w) &lt;your alternative return value&gt;)?这对我来说似乎很危险。我会尝试找到一种更好的方法来处理负面决定因素。

标签: r debugging optimization try-catch


【解决方案1】:

在这种情况下,我不会使用在测试中通常比在您的主代码中更合适的 tryCatch。为什么不简单地测试函数中的决定因素?类似的东西应该可以工作:

logdetHinv<-function(dp, dw, t2){
    gmat=mapply(function(x) gdot(x,t2),dp)
    D0=gmat%*%diag(dw)%*%t(gmat)
    D1=gmat%*%diag(1/h(g(dp,t2)))%*%diag(dw)%*%t(gmat)
    detD1 <- max(0.01, det(D1))
    detD0 <- max(0.01, det(D0)) 
    2*log(detD1)-log(detD0)
}

【讨论】:

  • 好主意。我想到tryCatch 的原因是我不确定这是由于负行列式。您的代码确认了我,因为它不再报告错误。但它不能直接应用,因为行列式实际上远小于0.01,接近于0,这可能是错误的根源。我将其修改为 detD1 &lt;- max(0.01, 1e10*det(D1)) detD0 &lt;- max(0.01, 2e10*det(D0)) 就像一个魅力。
  • 很高兴听到您解决了问题。
猜你喜欢
  • 2019-12-31
  • 2016-06-17
  • 2017-02-25
  • 2021-10-25
  • 1970-01-01
  • 2019-11-06
  • 2013-10-26
  • 2013-02-24
  • 1970-01-01
相关资源
最近更新 更多