R 中具有多个变量的 nlm
nlm with multiple variables in R
我正在尝试使用 nlm()
来最小化函数中的 SSE。我在使用它们的语法和获取 nlm()
来提供两个变量的估计时遇到了问题。最终 t_1
、t_2
和 t_3
将是从 data.frame
中提取的值,但我只是给它们分配了数字,直到我可以让 nlm()
工作。我尝试了这些线程的解决方案 and there,但没有成功:
t_1 <- 1.91
t_2 <- 3.23
t_3 <- 4.20
fun <- function(s,y){
(10 - s*(t_1-y + y*exp(-t_1/y)))^2+
(20 - s*(t_2-y + y*exp(-t_2/y)))^2+
(30 - s*(t_3-y + y*exp(-t_3/y)))^2
}
## Testing the function
fun(9.57,1.13)
[1] 0.9342627
我已经为我的 nlm 语法尝试了多种方法。对于 2 个变量,我相信我必须为 p 插入一个数组,但是当我尝试它时它没有用。 None 以下解决方案有效:
# Attempt 1
p = array(c( 1,0), dim=c(2,1) )
ans <- nlm(fun, p)
# Attempt 2
ans <- nlm(fun, c( 0.1, 0.1))
# The first two return a "Error in f(x, ...) : argument "y" is missing, with no default"
# Attempt 3 returns a "invalid function value in 'nlm' optimizer" error
ans <- nlm(fun, c( 0.1, 0.1), y = c(1,1))
我确定我的代码中有几个错误,但我不确定在哪里。这个任务比我以前尝试过的要复杂,因为我对 R 还比较陌生。
如果您仔细观察 nlm
函数。它只要求一个参数。一种解决方案是:
fun <- function(x){
s <- x[1]
y <- x[2]
(10 - s*(t_1-y + y*exp(-t_1/y)))^2+
(20 - s*(t_2-y + y*exp(-t_2/y)))^2+
(30 - s*(t_3-y + y*exp(-t_3/y)))^2
}
p <- array(c(0.4, 0.4), dim = c(2, 1))
# p <- c(0.4, 0.4)
ans <- nlm(f = fun, p = p)
vector
或 array
都有效,但是您不能像您那样给出两个参数。
编辑
在数值优化中,初始点非常重要。我建议你使用 optim
函数,它对初始点的错误指定不太敏感。
一个想法是这样做,你制作一个由许多初始点组成的网格,然后 select 给你最好的结果:
initialisation <- expand.grid(seq(1, 3, 0.5),
seq(1, 3, 0.5))
res <- data.frame(optim = rep(0, nrow(initialisation)),
nlm = rep(0, nrow(initialisation)))
for(i in 1:nrow(initialisation)){
res[i, 1] <- optim(as.numeric(initialisation[i, ]), fun)$value
res[i, 2] <- try(nlm(f = fun, p = as.numeric(initialisation[i, ]))$minimum, silent = T)
}
res
我坚持认为上面的例子 optim
函数确实更稳定。如果你没有其他限制,我建议你使用它。
由于 ?nlm
,您可以检查函数参数。
希望对您有所帮助。
编辑 2
fun <- function(x){
s <- x[1]
y <- x[2]
(10 - s*(t_1-y + y*exp (-t_1/y)))^2+
(20 - s*(t_2-y + y*exp(-t_2/y)))^2+
(30 - s*(t_3-y + y*exp(-t_3/y)))^2
}
我选择这个初始点,因为它看起来更接近最佳点。
p <- c(10, 1)
ans <- nlm(f = fun, p = p)
您可以像这样获取两个参数:
小号是:
s <- ans$estimate[1]
y 是:
y <- ans$estimate[2]
您还有最佳值:
ans$minimum :
0.9337047
fun(c(s, y)) :
0.9337047
我的第二个 post,编辑只是为了说明使用 nlm
函数进行优化有点棘手,因为您需要仔细选择初始值。
optim
也是 R 的优化函数,在我给出的带有许多初始化点的示例中更稳定。
expand.grid
函数对于获得这样的网格很有用:
initialisation <- expand.grid(s = seq(2, 3, 0.5),
y = seq(2, 3, 0.5))
initialisation :
s y
1 2.0 2.0
2 2.5 2.0
3 3.0 2.0
4 2.0 2.5
5 2.5 2.5
6 3.0 2.5
7 2.0 3.0
8 2.5 3.0
9 3.0 3.0
res data.frame
给出不同初始值的最小值。
您会看到第一个初始值给 nlm
没有好的结果,但 optim
.
的结果相对稳定
res <- data.frame(optim = rep(0, nrow(initialisation)),
nlm = rep(0, nrow(initialisation)))
for(i in 1:nrow(initialisation)){
res[i, 1] <- optim(as.numeric(initialisation[i, ]), fun)$value
res[i, 2] <- if(is.numeric(try(nlm(f = fun, p = as.numeric(initialisation[i, ]))$minimum, silent = T)) == T){
round(nlm(f = fun, p = as.numeric(initialisation[i, ]))$minimum, 8)
}else{
NA
}
}
try
函数只是为了避免循环中断。 if
是把NA放在正确的位置。
res :
optim nlm
1 0.9337094 <NA>
2 0.9337058 0.93370468
3 0.9337054 <NA>
4 0.9337101 0.93370468
5 0.9337125 61.18166446
6 0.9337057 0.93370468
7 0.9337120 0.93370468
8 0.9337080 0.93370468
9 0.9337114 0.93370468
当有 NA
值时,这意味着 nlm
由于初始化而无法正常工作。我建议你选择optim
,如果你不需要非常精确的优化,因为它的稳定性。
关于 optim
与 nlm
的广泛讨论,你可以看看 their。在您的特定情况下, optim
似乎是更好的选择。我不知道我们是否可以概括一下。
我正在尝试使用 nlm()
来最小化函数中的 SSE。我在使用它们的语法和获取 nlm()
来提供两个变量的估计时遇到了问题。最终 t_1
、t_2
和 t_3
将是从 data.frame
中提取的值,但我只是给它们分配了数字,直到我可以让 nlm()
工作。我尝试了这些线程的解决方案
t_1 <- 1.91
t_2 <- 3.23
t_3 <- 4.20
fun <- function(s,y){
(10 - s*(t_1-y + y*exp(-t_1/y)))^2+
(20 - s*(t_2-y + y*exp(-t_2/y)))^2+
(30 - s*(t_3-y + y*exp(-t_3/y)))^2
}
## Testing the function
fun(9.57,1.13)
[1] 0.9342627
我已经为我的 nlm 语法尝试了多种方法。对于 2 个变量,我相信我必须为 p 插入一个数组,但是当我尝试它时它没有用。 None 以下解决方案有效:
# Attempt 1
p = array(c( 1,0), dim=c(2,1) )
ans <- nlm(fun, p)
# Attempt 2
ans <- nlm(fun, c( 0.1, 0.1))
# The first two return a "Error in f(x, ...) : argument "y" is missing, with no default"
# Attempt 3 returns a "invalid function value in 'nlm' optimizer" error
ans <- nlm(fun, c( 0.1, 0.1), y = c(1,1))
我确定我的代码中有几个错误,但我不确定在哪里。这个任务比我以前尝试过的要复杂,因为我对 R 还比较陌生。
如果您仔细观察 nlm
函数。它只要求一个参数。一种解决方案是:
fun <- function(x){
s <- x[1]
y <- x[2]
(10 - s*(t_1-y + y*exp(-t_1/y)))^2+
(20 - s*(t_2-y + y*exp(-t_2/y)))^2+
(30 - s*(t_3-y + y*exp(-t_3/y)))^2
}
p <- array(c(0.4, 0.4), dim = c(2, 1))
# p <- c(0.4, 0.4)
ans <- nlm(f = fun, p = p)
vector
或 array
都有效,但是您不能像您那样给出两个参数。
编辑
在数值优化中,初始点非常重要。我建议你使用 optim
函数,它对初始点的错误指定不太敏感。
一个想法是这样做,你制作一个由许多初始点组成的网格,然后 select 给你最好的结果:
initialisation <- expand.grid(seq(1, 3, 0.5),
seq(1, 3, 0.5))
res <- data.frame(optim = rep(0, nrow(initialisation)),
nlm = rep(0, nrow(initialisation)))
for(i in 1:nrow(initialisation)){
res[i, 1] <- optim(as.numeric(initialisation[i, ]), fun)$value
res[i, 2] <- try(nlm(f = fun, p = as.numeric(initialisation[i, ]))$minimum, silent = T)
}
res
我坚持认为上面的例子 optim
函数确实更稳定。如果你没有其他限制,我建议你使用它。
由于 ?nlm
,您可以检查函数参数。
希望对您有所帮助。
编辑 2
fun <- function(x){
s <- x[1]
y <- x[2]
(10 - s*(t_1-y + y*exp (-t_1/y)))^2+
(20 - s*(t_2-y + y*exp(-t_2/y)))^2+
(30 - s*(t_3-y + y*exp(-t_3/y)))^2
}
我选择这个初始点,因为它看起来更接近最佳点。
p <- c(10, 1)
ans <- nlm(f = fun, p = p)
您可以像这样获取两个参数: 小号是:
s <- ans$estimate[1]
y 是:
y <- ans$estimate[2]
您还有最佳值:
ans$minimum :
0.9337047
fun(c(s, y)) :
0.9337047
我的第二个 post,编辑只是为了说明使用 nlm
函数进行优化有点棘手,因为您需要仔细选择初始值。
optim
也是 R 的优化函数,在我给出的带有许多初始化点的示例中更稳定。
expand.grid
函数对于获得这样的网格很有用:
initialisation <- expand.grid(s = seq(2, 3, 0.5),
y = seq(2, 3, 0.5))
initialisation :
s y
1 2.0 2.0
2 2.5 2.0
3 3.0 2.0
4 2.0 2.5
5 2.5 2.5
6 3.0 2.5
7 2.0 3.0
8 2.5 3.0
9 3.0 3.0
res data.frame
给出不同初始值的最小值。
您会看到第一个初始值给 nlm
没有好的结果,但 optim
.
res <- data.frame(optim = rep(0, nrow(initialisation)),
nlm = rep(0, nrow(initialisation)))
for(i in 1:nrow(initialisation)){
res[i, 1] <- optim(as.numeric(initialisation[i, ]), fun)$value
res[i, 2] <- if(is.numeric(try(nlm(f = fun, p = as.numeric(initialisation[i, ]))$minimum, silent = T)) == T){
round(nlm(f = fun, p = as.numeric(initialisation[i, ]))$minimum, 8)
}else{
NA
}
}
try
函数只是为了避免循环中断。 if
是把NA放在正确的位置。
res :
optim nlm
1 0.9337094 <NA>
2 0.9337058 0.93370468
3 0.9337054 <NA>
4 0.9337101 0.93370468
5 0.9337125 61.18166446
6 0.9337057 0.93370468
7 0.9337120 0.93370468
8 0.9337080 0.93370468
9 0.9337114 0.93370468
当有 NA
值时,这意味着 nlm
由于初始化而无法正常工作。我建议你选择optim
,如果你不需要非常精确的优化,因为它的稳定性。
关于 optim
与 nlm
的广泛讨论,你可以看看 their。在您的特定情况下, optim
似乎是更好的选择。我不知道我们是否可以概括一下。