将nlm()调用转换为nlminb()调用

时间:2017-10-25 17:15:20

标签: r nonlinear-optimization

我有一些使用nlm()进行非线性优化的遗留代码。我打算将代码更新为nlminb(),以便可以进行约束优化。我理解这些方法可能不相同或等效,但考虑到提供给nlm()的以下参数,为nlminb的类似调用提供的调用和参数是什么?

##' @param print.level Arguments for nlm.
##' @param typsize Arguments for nlm.
##' @param ndigit Arguments for nlm.
##' @param gradtol Arguments for nlm.
##' @param stepmax Arguments for nlm.
##' @param steptol Arguments for nlm.
##' @param iterlim Arguments for nlm.
##' @param fscale Arguments for nlm.


# Take the legacy nlm() call and ...    
z0 <- nlm(like,p=p,hessian=TRUE,print.level=print.level,typsize=typsize,
    ndigit=ndigit,gradtol=gradtol,stepmax=stepmax,steptol=steptol,
    iterlim=iterlim,fscale=fscale)


# turn into nlminb call:
z0 <- nlminb(nlminb args with different names but taking same @param from parent function)

1 个答案:

答案 0 :(得分:0)

有趣的问题!我最终会建议使用optimxRdocsJSS site),但现在让nlm映射到nlminb

我会修改你写的内容:

##' @param print.level Arguments for nlm.
##' @param typsize Arguments for nlm.
##' @param ndigit Arguments for nlm.
##' @param gradtol Arguments for nlm.
##' @param stepmax Arguments for nlm.
##' @param steptol Arguments for nlm.
##' @param iterlim Arguments for nlm.
##' @param fscale Arguments for nlm.


# Take the legacy nlm() call and ...    
z0 <- nlm(f=like,
          p=p,
          hessian=TRUE,
          print.level=print.level,
          typsize=typsize,
          ndigit=ndigit,
          gradtol=gradtol,
          stepmax=stepmax,
          steptol=steptol,
          iterlim=iterlim,
          fscale=fscale
          )

nlminb()中的类似通话如下所示。我们首先要注意的是nlminb()使用control参数与control parameters,以及参数objectivestart而不是fp(分别;和nlm的顺序不同,所以请务必明确键入参数):

# turn into nlminb call:
z0 <- nlminb(objective=like,
             start=p,
             hessian=TRUE,
             control = list(trace=print.level,  #for 0, same behavior
                            #typsize=typsize,
                            #ndigit=ndigit,
                            #gradtol=gradtol,
                            step.max=stepmax,
                            #steptol=steptol,
                            iter.max=iterlim,
                            #fscale=fscale
             )
)

我建议在父函数中添加更多参数并使用optimx

##' @param print.level Arguments for nlm.
##' @param typsize Arguments for nlm.
##' @param ndigit Arguments for nlm.
##' @param gradtol Arguments for nlm.
##' @param stepmax Arguments for nlm, nlminb
##' @param steptol Arguments for nlm.
##' @param iterlim Arguments for optimx, nlm, nlminb
##' @param fscale Arguments for nlm.
##' @param trace Arguments for nlminb
##' @param method Argument for optimx

z0 <- optimx(fn=like, 
             par=p, 
             hessian=TRUE, ## not `hess`
             method=c("nlminb"), 
             itnmax=iterlim, 
             control = list(
               # for nlm:
               print.level=print.level,
               typsize=typsize,
               ndigit=ndigit,
               gradtol=gradtol,
               stepmax=stepmax,
               steptol=steptol,
               #iterlim=iterlim, # preferred as itnmax above
               fscale=fscale,
               # for nlminb:
               trace=trace,
               step.max=stepmax
               # ... any other nlminb args
             )             
)

要从optimx中提取出粗麻布,请执行:

## hessian extraction (1st row or by name):
attr(fit, "details")[1,]$nhatend
attr(fit, "details")["nlminb",]$nhatend

以下问题不是必需的,但只需将感兴趣的nlm参数放在一个地方,然后得出结论:{没有完美的1对1匹配{ {1}}

以下是nlminbnlm()print.leveltypsizendigitgradtol的{​​{1}}参数定义, stepmax的{​​{1}}和steptol的{​​{1}}(来自Rdocs):

  • iterlim此参数确定在最小化过程中完成的打印级别。默认值0表示不进行打印,值1表示打印初始和最终详细信息,值2表示打印完整跟踪信息。

  • fscale估算每个参数的大小。

  • nlm()函数print.level中的有效位数。

  • typsize一个正标量,给出了一个容差,在该容差下,缩放的梯度被认为足够接近零以终止算法。缩放梯度是每个方向p [i]的f相对变化除以p [i]的相对变化的量度。

  • ndigit一个正标量,它给出了允许的最大缩放步长。 f用于防止导致优化函数溢出的步骤,防止算法离开参数空间中的感兴趣区域,或者检测算法中的偏差。选择gradtol小到可以防止前两次发生,但应该大于任何预期的合理步骤。

  • stepmax提供最小允许相对步长的正标量。

  • stepmax一个正整数,指定在程序终止之前要执行的最大迭代次数。

  • stepmax估计f的大小至少。

现在我们尝试在steptol中找到匹配项(从Rdocs拉出来)。我们首先注意到的是iterlim使用fscale参数nlminb()

nlminb()

control&#39; control parameters最接近的可能是# turn into nlminb call: z0 <- nlminb(objective=like, start=p, hessian=TRUE, control = list(trace=print.level, #for 0, same behavior #typsize=typsize, #ndigit=ndigit, #gradtol=gradtol, step.max=stepmax, #steptol=steptol, iter.max=iterlim, #fscale=fscale ) ) 。对于值0,两者都做同样的事情。但是,对于非零值,它们的运行方式不同。

  • nlmprint.level次迭代打印一次目标函数和参数的值。默认为0,表示不打印任何跟踪信息。

结论:在文档中查看更接近精确匹配可能具有挑战性。这就是为什么我抨击并建议扩展父参数和使用optimx。