Optimization 超越R';s最优函数

Optimization 超越R';s最优函数,optimization,r,Optimization,R,我试图用R来估计一个带有手动规范的多项式logit模型。我发现了一些软件包,可以让您估算MNL模型或 我还发现了一些关于“滚动”您自己的MLE函数的其他著作。然而,从我的挖掘来看,所有这些函数和包都依赖于内部的optim函数 在我的基准测试中,optim是瓶颈。使用一个包含16000个观察值和7个参数的模拟数据集,R在我的机器上大约需要90秒。等效模型大约需要10秒。一位同事在报告中为同一模型编写了自己的代码,时间约为4秒 是否有人有编写自己的MLE函数的经验,或者可以为我指出一些超出默认opt

我试图用R来估计一个带有手动规范的多项式logit模型。我发现了一些软件包,可以让您估算MNL模型或

我还发现了一些关于“滚动”您自己的MLE函数的其他著作。然而,从我的挖掘来看,所有这些函数和包都依赖于内部的
optim
函数

在我的基准测试中,
optim
是瓶颈。使用一个包含16000个观察值和7个参数的模拟数据集,R在我的机器上大约需要90秒。等效模型大约需要10秒。一位同事在报告中为同一模型编写了自己的代码,时间约为4秒

是否有人有编写自己的MLE函数的经验,或者可以为我指出一些超出默认
optim
函数优化的方向(没有双关语)

如果有人想要R代码重新创建模型,请告诉我-我很乐意提供它。我没有提供它,因为它与优化
optim
函数和保留空间的问题没有直接关系

编辑:谢谢大家的想法。基于下面的大量评论,对于更复杂的模型,我们能够得到与Biogeme相同的R,对于我们运行的几个更小/更简单的模型,R实际上更快。我认为这个问题的长期解决方案将涉及编写一个独立的最大化函数,该函数依赖于fortran或C库,但我肯定会接受其他方法。

已经尝试过nlm()函数了吗?不知道它是否更快,但它确实提高了速度。同时检查选项。optim使用慢速算法作为默认值。使用拟牛顿算法(method=“BFGS”)而不是默认算法,可以获得>5倍的加速比。如果您不太关心最后的数字,还可以将nlm()的公差级别设置得更高,以获得额外的速度

f <- function(x) sum((x-1:length(x))^2)

a <- 1:5

system.time(replicate(500,
     optim(a,f)
))
   user  system elapsed 
   0.78    0.00    0.79 

system.time(replicate(500,
     optim(a,f,method="BFGS")
))
   user  system elapsed 
   0.11    0.00    0.11 

system.time(replicate(500,
     nlm(f,a)
))
   user  system elapsed 
   0.10    0.00    0.09 

system.time(replicate(500,
      nlm(f,a,steptol=1e-4,gradtol=1e-4)
))
   user  system elapsed 
   0.03    0.00    0.03 

<代码> f> p>你是否考虑了在

fWW上的材料,我用C-OIST做了这个,使用opt9。你很难跑得更快。有很多方法可以让事情变慢,比如运行像R这样的解释器


补充:从评论中可以明显看出,OPTIF9被用作优化引擎。这意味着大部分时间很可能都花在评估R中的目标函数上。虽然C函数可能被用于某些操作,但仍然存在解释器开销。有一种快速的方法可以确定R中的哪些代码行和函数调用在大部分时间内负责,那就是使用Escape键暂停它并检查堆栈。如果一条语句占用X%的时间,则它在堆栈上占用X%的时间。您可能会发现,有些操作不打算使用C,而应该使用C。当您找到一种并行化R执行的方法时,您通过这种方式获得的任何加速因子都将被保留。

我是R包optimParallel的作者,这对您的情况可能会有所帮助。该软件包提供了基于梯度的优化方法的并行版本
optim()
。这个包的主要功能是
optimParallel()
,它的用法和输出与
optim()
相同。使用
optimParallel()
可以显著减少优化时间,如下图所示(
p
是参数的数量)。
有关更多信息,请参阅和

魔鬼在细节中。您可能会弄乱
optim
参数(请参阅文档中关于
control
的部分)。您可以将默认参数与同事代码或Biogeme使用的参数进行比较。它们是否不同,如果是,那么为什么?@Marek-Biogeme依赖于一个用C编写的自定义最大化例程,Ox也是一个类似的故事。这对我来说是一个新领域,但我开始了解使用的不同方法。据我所知,nlm()和R中的其他优化例程可能已经用C编写。我建议你直接寻找内部函数的访问权限,这样你就可以摆脱开销,而不是重新发明wheelJoris,你能解释一下吗?我不知道它是否更快,但它确实再次提高了速度?我今天只喝了两杯咖啡。你的意思是“更快,但不确定多少”?呃,键盘这边也需要更多的咖啡。。。事实上,在我测试它的函数上,它的速度更快,有时是很小的,有时是相当大的。它还取决于控件设置,如代码中所示。感谢有关nlm()的提示。正如上面所述,在改变了步长和梯度之后,它是最快的。相当多的R的底层例程是用C或Fortran编写的。所以理论上,R的速度应该接近C。现在只需要找到一个好的实现。不知道是否使用了OPTIF9,但如果有一个额外的软件包,这将是一个不错的主意;-)Dennis Schnabel算法“optif9”在nlm的R中实现。(快速查看R源代码可以发现它是对旧fortran子程序的c重写)。@eyjo:@Joris:那很好,这正是我所期望的。然后,大部分时间将花在R中用户编码的目标函数上。如果有可能将其转换为编译器语言,它应该与C语言处于相同的范围内。是的,您将遇到这个问题。正如Chase所说,Ox或多或少是一个定制的c编译器,它在4秒内完成了自己的模型,而在R中只需90秒。但是,在R中处理统计数据的灵活性是无与伦比的,并且可以通过定制的c调用轻松地扩展它。如果您用c编写目标函数,并包含R.h、Rinternals.h和R_ext/Applic.h头,然后从那里调用相关的optim例程,为R编译它,我认为您应该非常接近,它在R中无缝工作。@eyjo:对。目标函数每次调用100次