r - 在 R 中使用 `nls.lm` 时如何处理边界约束

标签 r mathematical-optimization nls

我问 this question不久以前。我不确定我是否应该将此作为答案或新问题发布。我没有答案,但我通过使用 nls.lm 应用 Levenberg-Marquardt 算法“解决”了这个问题。在 R 中并且当解决方案处于边界时,我运行信任区域反射算法(TRR,在 R 中实现)以远离它。现在我有新的问题。

根据我的经验,这样做程序会达到最佳状态,并且对起始值不那么敏感。但这只是摆脱我在使用 nls.lm 时遇到的问题的实用方法。以及 R 中的其他优化函数。我想知道为什么 nls.lm对于具有边界约束的优化问题以及在使用 nls.lm 时如何处理边界约束,这种行为方式是这样的在实践中。

下面我举例说明了使用 nls.lm 的两个问题。 .

  • 它对起始值很敏感。
  • 当某个参数到达边界时它会停止。

  • 可重复的示例:焦点数据集 D
    library(devtools)
    install_github("KineticEval","zhenglei-gao")
    library(KineticEval)
    data(FOCUS2006D)
    km <- mkinmod.full(parent=list(type="SFO",M0 = list(ini   = 0.1,fixed = 0,lower = 0.0,upper =Inf),to="m1"),m1=list(type="SFO"),data=FOCUS2006D)
    system.time(Fit.TRR <- KinEval(km,evalMethod = 'NLLS',optimMethod = 'TRR'))
    system.time(Fit.LM <- KinEval(km,evalMethod = 'NLLS',optimMethod = 'LM',ctr=kingui.control(runTRR=FALSE)))
    compare_multi_kinmod(km,rbind(Fit.TRR$par,Fit.LM$par))
    dev.print(jpeg,"LMvsTRR.jpeg",width=480)
    

    LM fit vs TRR fit

    描述模型/系统的微分方程是:
    "d_parent = - k_parent * parent"                                                 
    "d_m1 = - k_m1 * m1 + k_parent * f_parent_to_m1 * parent" 
    

    左边的图中是带有初始值的模型,中间是使用“TRR”的拟合模型(类似于Matlab lsqnonlin函数中的算法),右边是使用“LM”的拟合模型nls.lm .查看拟合参数( Fit.LM$par ),您会发现一个拟合参数( f_parent_to_m1 )位于边界 1 处.如果我更改一个参数的起始值 M0_parent从 0.1 到 100,然后我使用 nls.lm 得到了相同的结果和 lsqnonlin .我有很多这样的案例。
    newpars <- rbind(Fit.TRR$par,Fit.LM$par)
    rownames(newpars)<- c("TRR(lsqnonlin)","LM(nls.lm)")
    newpars
    
                       M0_parent   k_parent        k_m1 f_parent_to_m1
    TRR(lsqnonlin)  99.59848 0.09869773 0.005260654       0.514476
    LM(nls.lm)      84.79150 0.06352110 0.014783294       1.000000
    

    除了以上问题,经常会出现nls.lm返回的Hessian不可逆(特别是当某些参数在边界上时)所以我无法估计协方差矩阵。另一方面,“TRR”算法(在 Matlab 中)几乎总是通过计算解点处的雅可比来给出估计。我认为这很有用,但我也确信 R 优化算法(我尝试过的那些)没有这样做是有原因的。我想知道我是否通过使用计算协方差矩阵的Matlab方法来获得参数估计的标准误差。

    最后一点,我在 previous post 中声明Matlab lsqnonlin几乎在所有情况下都优于 R 的优化函数。我错了。从上面的例子可以看出,如果也在 R 中实现,Matlab 中使用的“信任区域反射”算法实际上更慢(有时慢得多)。但是,它仍然比 R 的基本优化算法更稳定并达到更好的解决方案。

    最佳答案

    首先,我不是 Matlab 和优化方面的专家,也从未使用过 R。

    我不确定我明白你的实际问题是什么,但也许我可以解释你的困惑:

    LM 是略微增强的 Gauß-Newton 方法 - 对于具有多个局部最小值的问题,它对初始状态非常敏感。包括边界通常会产生更多的最小值。

    TRR 类似于 LM,但更健壮。它具有更好的“跳出”不良局部最小值的能力。与 LM 相比,它表现得更好,但表现更差,这是完全可行的。实际上解释为什么是非常困难的。您需要详细研究算法并查看它们在这种情况下的行为。

    我无法解释 Matlab 和 R 实现之间的区别,但是可能 Matlab 使用了 TRR 的几个扩展,而 R 没有。
    您交替使用 LM 和 TRR 的方法是否比单独使用 TRR 收敛得更好?

    关于r - 在 R 中使用 `nls.lm` 时如何处理边界约束,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/17041164/

    相关文章:

    python - 并行多维优化

    r - 理解 R 中 optim() 的 maxit 参数

    r - 如何通过 nls() 计算拟合值的置信区间

    r - 关于 nls fit in R 的问题 - 为什么这如此奇怪?

    r - R中两个向量之间的差异

    根据R中的条件用前一行值替换值

    r - 标记多个日期范围内的日期

    r - 创建具有全彩色背景的 kable 表

    MATLAB:特定线性程序的快速且内存高效的解决方案

    r - 初始参数估计时 nls 奇异梯度矩阵的误差