简体   繁体   English

R中三参数逆威布尔模型实现的最大似然估计

[英]Maximum-Likelihood Estimation of three parameter reverse Weibull model implementation in R

I'm implementing a Maximum-Likelihood estimation in R for a three parameter reverse Weibull model and have some troubles to get plausible results, which include: Bad optimization results, unwanted optimx behaviour.我正在 R 中为三参数反向 Weibull 模型实现最大似然估计,但在获得合理结果时遇到了一些麻烦,其中包括:优化结果不佳、不想要的 optimx 行为。 Beside these I wonder, how I could make use of parscale in this model.除了这些,我想知道如何在这个模型中使用 parscale。

Here is my implementation attempt:这是我的实现尝试:

To generate data I use the probabilty integral transform:为了生成数据,我使用概率积分变换:

#Generate N sigma*RWei(alph)-mu distributed points        
gen.wei <- function(N, theta) {
      alph <- theta[1]
      mu <- theta[2]
      sigma <- theta[3]
      return(
        mu - sigma * (- log (runif(N)))**(1/alph)
      )
    }

Now I define the Log-Likelihood and negative Log-Likelihood to use optimx optimization:现在我定义对数似然和负对数似然来使用 optimx 优化:

#LL----
ll.wei <- function(theta,x) {
  N <- length(x)
  alph <- theta[1]
  mu <- theta[2]
  sigma <- theta[3]
  val <- sum(ifelse(
    x <= mu,
    log(alph/sigma) + (alph-1) * log( (mu-x)/sigma) - ( (mu-x)/sigma)**(alph-1),
    -Inf
  ))
  return(val)
}
#Negative LL----
nll.wei <- function(theta,x) {
  return(-ll.wei(theta=theta, x=x))
         }

Afterwards I define the analytical gradient of the negative LL.然后我定义负 LL 的解析梯度。 Remark: There are points at which the negative LL isn't differentiable (the upper end-point mu)备注:有一些点是负 LL 不可微的(上端点 mu)

gradnll.wei <- function(theta,x) {
  N <- length(x)
  alph <- theta[1]
  mu <- theta[2]
  sigma <- theta[3]
  argn <- (mu-x)/sigma
  del.alph <- sum(ifelse(x <= mu,
    1/alph + log(argn) - log(argn) * argn**(alph-1),
    0
  ))
  del.mu <- sum(ifelse(x <= mu,
    (alph-1)/(mu-x) - (alph-1)/sigma * argn**(alph-2),
    0))
  del.sigma <- sum(ifelse(x <= mu,
    ((alph-1)*argn**(alph-1)-alph)/sigma,
    0))
  return (-c(del.alph, del.mu, del.sigma))
}

Finally I try to optimize using the optimx package and the methods Nelder-Mead (derivative free) and BFGS (my LL is kinda smooth, there's just one point, which is problematic).最后,我尝试使用 optimx 包和方法 Nelder-Mead(无导数)和 BFGS(我的 LL 有点平滑,只有一点,这是有问题的)进行优化。

      #MLE for Weibull
       mle.wei <- function(start,sample) {
      optimx(
        par=start,
        fn = nll.wei,
        gr = gradnll.wei,
        method = c("BFGS"),
        x = sample
      )
    }
    theta.s <- c(4,1,1/2) #test for parameters
    sample <- gen.wei(100, theta.s) #generate 100 data points distributed like theta.s
mle.wei(start=c(8,4, 2), sample) #MLE Estimation

To my surprise I get the following error:令我惊讶的是,我收到以下错误:

Error in optimx.check(par, optcfg$ufn, optcfg$ugr, optcfg$uhess, lower,  : 
  Cannot evaluate function at initial parameters

I checked manually: Both nll and gradnll are finite at the initial parameters... If i switch to optim instead of optim x I get a result, but a pretty bad one:我手动检查: nll 和 gradnll 在初始参数上都是有限的......如果我切换到 optim 而不是 optim x我得到一个结果,但一个非常糟糕的结果:

 $par
[1] 8.178674e-01 9.115766e-01 1.745724e-06

$value
[1] -1072.786

$counts
function gradient 
     574      100 

$convergence
[1] 1

$message
NULL

So it doesn't converge.所以不会收敛。 If I don't supply the gradient to BFGS, there isn't a result.如果我不向 BFGS 提供梯度,就没有结果。 If I use Nelder-Mead instead:如果我改用 Nelder-Mead:

$par
[1] 1.026393e+00 9.649121e-01 9.865624e-18

$value
[1] -3745.039

$counts
function gradient 
     502       NA 

$convergence
[1] 1

$message
NULL

So it is also very bad...所以也很不好...

My questions are:我的问题是:

  1. Should I instead of defining the ll outside of the support as -Inf give it a very high negative value like -1e20 to circumvent -Inf errors or does it not matter?我应该将支持之外的 ll 定义为 -Inf 给它一个非常高的负值,如 -1e20 来规避 -Inf 错误还是无关紧要?
  2. Like the first one but for the gradient: technically the ll isn't defined outside of the support but since the likelihood is 0 albeit constant outside of the support, is it smart to define the gradnll as 0 outside?与第一个一样,但对于梯度:从技术上讲,ll 不是在支持之外定义的,但是由于可能性是 0 尽管在支持之外是恒定的,将 gradnll 定义为 0 在外部是否明智? 3.I checked the implementation of the MLE estimator fgev from the evd package and saw that they use the BFGS method but don't supply the gradient even though the gradient does exist. 3.我检查了evd包中的 MLE estimator fgev的实现,看到他们使用BFGS方法但不提供梯度,即使梯度确实存在。 Therefore my question is, whether there are situations where it is contraproductive to supply the gradient since it isn't defined everywhere (like my and the evd case)?因此,我的问题是,是否存在提供梯度会适得其反的情况,因为它没有在任何地方都定义(例如我和 evd 的情况)?
  3. I got an error of "argument x matches multiple formal arguments" type in optimx but not in optim, which surprised me.我在 optimx 中遇到了“参数 x 匹配多个正式参数”类型的错误,但在 optim 中没有,这让我感到惊讶。 What am I doing wrong in supplying my functions and data to the optimx function?我在向 optimx 函数提供函数和数据时做错了什么?

Thank you very much in advance!非常感谢您提前!

Re 3: That's kind of a bug in optimx , but one that's hard to avoid.回复 3:这是optimx的一个错误,但很难避免。 It uses x as a variable name when calculating a numerical gradient;它在计算数值梯度时使用x作为变量名; you also use it as an "additional parameter" to your functions.您还可以将其用作函数的“附加参数”。 You can work around that by renaming your argument, eg call it xdata in your functions.你可以通过重命名你的参数来解决这个问题,例如在你的函数中调用它xdata

Re 1 & 2: There are several techniques to handle boundary problems in optimization. Re 1 & 2:有几种技术可以处理优化中的边界问题。 Setting to a big constant value tends not to work: if the optimizer goes out of bounds, it finds the objective function really flat.设置一个大的常数值往往不起作用:如果优化器越界,它会发现目标函数非常平坦。 If the exact boundary is legal, then pushing the parameter to the boundary and adding a penalty sometimes works.如果确切的边界是合法的,那么将参数推到边界并添加惩罚有时会起作用。 If the exact boundary is illegal, you might be able to reflect: eg if mu > 0 is a requirement, sometimes replacing mu by abs(mu) in the objective function gets things to work.如果确切的边界是非法的,您可能能够反映:例如,如果 mu > 0 是一个要求,有时在目标函数中用 abs(mu) 替换 mu 会使事情起作用。 Sometimes the best solution is to get rid of the boundary by transforming the parameters.有时最好的解决方案是通过变换参数来摆脱边界。

Edited to add some more details:编辑以添加更多详细信息:

For this problem, it looks to me as though transformations of the parameters might work.对于这个问题,在我看来,参数的转换可能有效。 I think alpha and sigma must both be positive.我认为alphasigma必须都是正数。 Setting alpha <- exp(theta[1]) and sigma <- exp(theta[3]) will guarantee that.设置alpha <- exp(theta[1])sigma <- exp(theta[3])将保证这一点。 Limits on mu are harder, but I think mu > max(xdata) is needed, so mu <- max(xdata) + exp(theta[2]) should keep it in bounds.mu限制更难,但我认为mu > max(xdata)是必需的,因此mu <- max(xdata) + exp(theta[2])应该将其保持在界限内。 Of course, making these changes messes up your gradient formula and starting values.当然,进行这些更改会弄乱您的渐变公式和起始值。

As to resources: I'm afraid I don't know any.至于资源:恐怕我不知道。 This advice is based on years of painful experience.这个建议是基于多年的痛苦经验。

https://web.ncf.ca/nashjc/optimx202112/ has a version of the package that deals with at least some variable clashes in the dot args. https://web.ncf.ca/nashjc/optimx202112/有一个版本的包,至少可以处理点参数中的一些变量冲突。

There are some separate cleanups to be done before this goes on CRAN, but the package should be more or less robust at the moment.在 CRAN 上执行此操作之前,需要进行一些单独的清理工作,但目前该包应该或多或少是健壮的。

JN江南

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM