为什么 "optimx" 在 R 中更改起始值时会给出不同的结果?
Why "optimx" in R give different results when changing the starting values?
我需要使用 "optimx" 但我发现当我更改起始 values.Is 时输出会改变,这是正常的还是我的脚本有错误?:
dat1 <- array(1:60, c(3,5,4));dat2 <- array(1:60, c(3,5,4));dat3 <- array(1:60, c(3,5,4))
#reorder dimensions
dat1 <- aperm(dat1, c(3,1,2)); dat2 <- aperm(dat2, c(3,1,2));dat3 <- aperm(dat3, c(3,1,2))
#make array a matrix
dat1a <- dat1;dim(dat1a) <- c(dim(dat1)[1],prod(dim(dat1)[2:3]))
dat2a <- dat2;dim(dat2a) <- c(dim(dat2)[1],prod(dim(dat2)[2:3]))
dat3a <- dat3;dim(dat3a) <- c(dim(dat3)[1],prod(dim(dat3)[2:3]))
案例一:
fun <- function(x1, x2, y) {
keep <- !(is.na(x1) | is.na(x2) | is.na(y))
if (sum(keep) > 0) {
best=function(p,x1, x2, y){
sum((y [keep]-(((p[1]*x1[keep]+p[2]*x2[keep]+p[3])^p[4])+p[5]))^2)}
res <- optimx(c(0.5,3,4,0.1,1.8),best,x1=x1,x2=x2,y=y)
res <- coef(res)[1:5]
} else { res <- c(NA, NA, NA,NA,NA) }
return(res)}
res2 <- mapply(fun, x1=as.data.frame(dat1a), x2=as.data.frame(dat2a), y=as.data.frame(dat3a))
res2:
V1 V2 V3 V4 V5 V6 V7
[1,] -6.4508094 4.3192551 -4.4118228 0.96978160 -5.3236129 1.7360552 6.7636543
[2,] -0.7073374 -0.7404623 -0.7490429 -0.56937504 -0.6729419 -0.7373379 -0.7387721
案例二:
# same function but I changed the starting values
fun=function(x1, x2, y) {
keep <- !(is.na(x1) | is.na(x2) | is.na(y))
if (sum(keep) > 0) {
best=function(p,x1, x2, y){
sum((y [keep]-(((p[1]*x1[keep]+p[2]*x2[keep]+p[3])^p[4])+p[5]))^2)}
res <- optimx(c(1,1,1,1,1),best,x1=x1,x2=x2,y=y)
res <- coef(res)[1:5]
} else { res <- c(NA, NA, NA,NA,NA) }
return(res)}
res3 <- mapply(fun, x1=as.data.frame(dat1a), x2=as.data.frame(dat2a), y=as.data.frame(dat3a))
res3:
V1 V2 V3 V4 V5 V6 V7 V8
[1,] 0.6018246 0.1993663 -0.2520812 -0.1702029 -1.176793 -6.513526 -0.1749120 -1.329519
[2,] 7.6637890 3.4957285 3.0466838 2.2510481 1.601970 1.245830 1.0175985 0.852469
您的脚本没有错误。这就是优化器的工作方式。在您的情况下,您使用 optimx
和默认参数(即未指定方法以及上下参数),这意味着内部 optimx
将使用基本 R optim
函数默认 Nelder-Mead
方法。
我引用 Wikipedia(这可能不是最好的来源,但它解释正确):
The Nelder–Mead method or downhill simplex method or amoeba method is a commonly used nonlinear optimization technique, which is a well-defined numerical method for problems for which derivatives may not be known. However, the Nelder–Mead technique is a heuristic search method that can converge to non-stationary points[1] on problems that can be solved by alternative methods.[2]
上面引用的关键字,我已经突出显示的是 heuristic:
Heuristic, is any approach to problem solving, learning, or discovery that employs a practical methodology not guaranteed to be optimal or perfect, but sufficient for the immediate goals.
因此,optim
函数试图在您的案例中找到一个局部最小值,这将提供一个快速的次优解决方案(即它没有找到全局最小值)。这是出于速度和计算目的。
因此,通过更改初始值,您可以更改方法的起点,因此每次您都会获得不同的局部最小值。
其余方法的工作方式类似,但研究每种方法以确定是否正在计算启发式解决方案是有意义的。
This 是我发现的另一个类似的问题,给出了很好的解释。
我需要使用 "optimx" 但我发现当我更改起始 values.Is 时输出会改变,这是正常的还是我的脚本有错误?:
dat1 <- array(1:60, c(3,5,4));dat2 <- array(1:60, c(3,5,4));dat3 <- array(1:60, c(3,5,4))
#reorder dimensions
dat1 <- aperm(dat1, c(3,1,2)); dat2 <- aperm(dat2, c(3,1,2));dat3 <- aperm(dat3, c(3,1,2))
#make array a matrix
dat1a <- dat1;dim(dat1a) <- c(dim(dat1)[1],prod(dim(dat1)[2:3]))
dat2a <- dat2;dim(dat2a) <- c(dim(dat2)[1],prod(dim(dat2)[2:3]))
dat3a <- dat3;dim(dat3a) <- c(dim(dat3)[1],prod(dim(dat3)[2:3]))
案例一:
fun <- function(x1, x2, y) {
keep <- !(is.na(x1) | is.na(x2) | is.na(y))
if (sum(keep) > 0) {
best=function(p,x1, x2, y){
sum((y [keep]-(((p[1]*x1[keep]+p[2]*x2[keep]+p[3])^p[4])+p[5]))^2)}
res <- optimx(c(0.5,3,4,0.1,1.8),best,x1=x1,x2=x2,y=y)
res <- coef(res)[1:5]
} else { res <- c(NA, NA, NA,NA,NA) }
return(res)}
res2 <- mapply(fun, x1=as.data.frame(dat1a), x2=as.data.frame(dat2a), y=as.data.frame(dat3a))
res2:
V1 V2 V3 V4 V5 V6 V7
[1,] -6.4508094 4.3192551 -4.4118228 0.96978160 -5.3236129 1.7360552 6.7636543
[2,] -0.7073374 -0.7404623 -0.7490429 -0.56937504 -0.6729419 -0.7373379 -0.7387721
案例二:
# same function but I changed the starting values
fun=function(x1, x2, y) {
keep <- !(is.na(x1) | is.na(x2) | is.na(y))
if (sum(keep) > 0) {
best=function(p,x1, x2, y){
sum((y [keep]-(((p[1]*x1[keep]+p[2]*x2[keep]+p[3])^p[4])+p[5]))^2)}
res <- optimx(c(1,1,1,1,1),best,x1=x1,x2=x2,y=y)
res <- coef(res)[1:5]
} else { res <- c(NA, NA, NA,NA,NA) }
return(res)}
res3 <- mapply(fun, x1=as.data.frame(dat1a), x2=as.data.frame(dat2a), y=as.data.frame(dat3a))
res3:
V1 V2 V3 V4 V5 V6 V7 V8
[1,] 0.6018246 0.1993663 -0.2520812 -0.1702029 -1.176793 -6.513526 -0.1749120 -1.329519
[2,] 7.6637890 3.4957285 3.0466838 2.2510481 1.601970 1.245830 1.0175985 0.852469
您的脚本没有错误。这就是优化器的工作方式。在您的情况下,您使用 optimx
和默认参数(即未指定方法以及上下参数),这意味着内部 optimx
将使用基本 R optim
函数默认 Nelder-Mead
方法。
我引用 Wikipedia(这可能不是最好的来源,但它解释正确):
The Nelder–Mead method or downhill simplex method or amoeba method is a commonly used nonlinear optimization technique, which is a well-defined numerical method for problems for which derivatives may not be known. However, the Nelder–Mead technique is a heuristic search method that can converge to non-stationary points[1] on problems that can be solved by alternative methods.[2]
上面引用的关键字,我已经突出显示的是 heuristic:
Heuristic, is any approach to problem solving, learning, or discovery that employs a practical methodology not guaranteed to be optimal or perfect, but sufficient for the immediate goals.
因此,optim
函数试图在您的案例中找到一个局部最小值,这将提供一个快速的次优解决方案(即它没有找到全局最小值)。这是出于速度和计算目的。
因此,通过更改初始值,您可以更改方法的起点,因此每次您都会获得不同的局部最小值。
其余方法的工作方式类似,但研究每种方法以确定是否正在计算启发式解决方案是有意义的。
This 是我发现的另一个类似的问题,给出了很好的解释。