R **优化**和**单根**之间有什么区别?
我查看了uniroot和optimize的描述,它们有些不同,但参考书是相同的,我想知道是否有理由选择其中一个而不是另一个?这两个函数有完全不同的用途:R **优化**和**单根**之间有什么区别?,r,R,我查看了uniroot和optimize的描述,它们有些不同,但参考书是相同的,我想知道是否有理由选择其中一个而不是另一个?这两个函数有完全不同的用途: optimize用于查找函数的最小值(或最大值) uniroot用于查找函数的根(零) 至于选择一个而不是另一个的原因。在(可能)大多数情况下,人们会更自然。正如@shadow所说,optimize用于最小化(或最大化),uniroot用于寻找零点 但是,在某些情况下,您可以使用这两种方法来解决您的问题。这通常是因为你可以使用衍生工具,但也可
用于查找函数的最小值(或最大值)optimize
用于查找函数的根(零)uniroot
optimize
用于最小化(或最大化),uniroot
用于寻找零点
但是,在某些情况下,您可以使用这两种方法来解决您的问题。这通常是因为你可以使用衍生工具,但也可能有其他方法来重组你的问题。这个答案的其余部分将讨论这些情况,在这些情况下,您实际上有一个选择,需要在这两种情况中进行选择
对于一个简单的例子,我们可能希望找到函数的最小值:
Func = function(x) {
(2*x-pi)^2 + exp(1)*x - 18
}
一种方法是使用优化作为:
OResult = optimize(Func, lower = 0, upper = 5)
OResult
$minimum
[1] 1.231011
$objective
[1] -14.19195
另一种方法是通过求导数来变换函数。由于最佳点是导数为零时,我们需要一个类似于单根的寻根算法。因此,函数变成:
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次。(这可以通过在上述函数中放置计数器来找到)。这是合乎逻辑的,optimize不知道最小值有多低,而uniroot知道将函数值设定为零。因此,uniroot通常知道x轴的方向,而optimize需要更多地查看
但是,如果我们进行基准优化,速度会快得多。
因此,通常(如果您关注速度)使用optimize,除非它是一个非常密集的函数,其中函数调用比优化算法所做的要昂贵(当然,在这些情况下,通常很难找到问题的一种形式来使用uniroot
)
多重局部最优
优化函数可能找不到全局最优解,而仅仅是局部最优解。对于uniroot
,情况也是如此,它可能会找到一个局部零,但不会找到其他存在的零uniroot
与optimize
不同,但是当您将optimize设置为查找最大值或最小值时,uniroot
将查找一个与y轴相交的点。如果你对一个导数使用单根,那么这个点可以是一个极小值或极大值
例如,如果我们有以下函数和导数:
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)
}
该功能如下图所示:
这里发生的是优化找到了两个极小值中的一个。另一方面,uniroot函数发现了一个最大值(因为uniroot无法区分最小值和最大值)。的描述部分可能会给您一些关于它们之间的区别的提示。我反对这个答案,因为虽然这是一个很小的区别,但答案并没有触及OPs问题的核心。根查找通常可以重新表示为优化。只有当f(左端点)与f(右端点)是不同的符号时,Uniroot才起作用。这不是优化所必需的。Optimize可用于在unitroot失败时查找根,例如uniroot(f=function(x){x^2-4},interval=c(-10,10))
vsOptimize(f=function(x){(x^2-5)^2},interval=c(-10,10))
。您可以检查来自optimize的答案是否是$ObjectiveForMe的根,uniroot不提供此类信息,它只给出错误消息“端点处的f()值不是相反的符号”,它没有指定关于多个根的任何内容。例如,uniroot(f=function(x){x*(x^2-4)},interval=c(-10,10))
只找到一个根,尽管有多个根。所以,也许我遗漏了一些你们正在讨论的论点。
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)
}
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