**优化**和** uniroot **有什么区别?

时间:2015-02-17 06:49:30

标签: r

我查看了uniroot和optimize的描述,但它们有些不同,但书籍参考是一样的,我想知道是否有理由选择一个而不是另一个?

2 个答案:

答案 0 :(得分:8)

至于理由选择一个而不是另一个。在(可能)大多数情况下,一个人会更自然。正如@shadow所说,optimise用于最小化(或最大化),uniroot用于找到零点。

在某些情况下,您可以使用其中任何一种来解决问题。这通常是因为你可以采取衍生工具,但可能还有另一种方法来重构你的问题。本答案的其余部分将讨论这些案例,您实际上可以选择并需要在两种情况之间进行选择。

对于一个简单的例子,我们可能想要找到函数的最小值:

Func = function(x) {
  (2*x-pi)^2 + exp(1)*x - 18
}

执行此操作的一种方法是将optimize用作:

OResult = optimize(Func, lower = 0, upper = 5)
OResult
$minimum
[1] 1.231011

$objective
[1] -14.19195

另一种方法是通过取导数来转换函数。由于最佳点是当导数为零时,我们需要像uniroot这样的寻根算法。因此功能变为:

DerivFunction = function(x) {
  4*(2*x-pi) + exp(1)
}

通过以下方式优化:

UResult = uniroot(DerivFunction , interval = c(0,5))
UResult
$root
[1] 1.231011

$f.root
[1] 4.440892e-16

$iter
[1] 2

$init.it
[1] NA

$estim.prec
[1] 6.103516e-05

速度

如果您在上述方法之间做出选择,那么为了简单起见,您可能会使用optimize。但有些情况下uniroot可能会更快。

使用上面的例子,optimize函数调用函数7次,而uniroot只调用衍生函数5次。 (这可以通过将计数器放在上面的函数中找到)。这是合乎逻辑的,优化不知道最小值有多低,而uniroot确实知道目标函数值为零。因此,uniroot通常会知道x轴的方向,而优化则需要更多地查看。

如果我们做基准测试,那么优化速度要快得多。 所以一般来说(如果你正在考虑速度)使用优化,除非它是一个非常密集的函数,其中函数调用比优化算法正在做的更昂贵(当然在这些情况下,通常很难得到一种形式的使用uniroot的问题。)

library(microbenchmark)
microbenchmark(
  optimize(Func, lower = 0, upper = 5),
  uniroot(DerivFunction, interval = c(0,5))
)
Unit: microseconds
                                       expr    min     lq     mean  median     uq     max neval
       optimize(Func, lower = 0, upper = 5) 18.264 19.785 23.50664 20.7370 23.781 129.365   100
 uniroot(DerivFunction, interval = c(0, 5)) 63.161 67.346 74.10322 69.8195 76.858 143.062   100

多个本地Optima

优化函数可能找不到全局最优,而只是局部最优。同样适用于uniroot,它可能会找到局部零但不存在其他零。 unirootoptimize不同,但是当您设置优化以查找最大值或最小值时,uniroot会找到一个与y轴相交的点。如果你uniroot得到一个导数,那么这个点可能是最小值或最大值。

例如,如果我们有以下功能和派生词:

TwoMinFunction = function(x){
  ((x)^4)/4 + x^3 - 3*x^2 - 8*x + 16
}

TwoZeroDerivFunction = function(x){
  (x^3 + 3*x^2 − 6*x − 8) 
}

此功能如下图所示: TwoMinimumFunction

OResult = optimize(TwoMinFunction, lower = -6, upper = 4)
OResult
$minimum
[1] -4.000001

$objective
[1] 8.007817e-12

UResult = uniroot(TwoZeroDerivFunction , interval = c(-6,4))
UResult
$root
[1] -1

$f.root
[1] 0

$iter
[1] 1

$init.it
[1] NA

$estim.prec
[1] 5

这里发生的事情是优化找到了两个最小值中的一个。另一方面,uniroot功能发现了一个最大值(因为uniroot不能区分最小值和最大值)。

答案 1 :(得分:6)

这两个功能的用途完全不同:

  • optimize用于查找函数的最小值(或最大值)。

  • uniroot用于查找函数的根(零)。