从R的optim函数获取更多细节

4

我对优化函数并不是很熟悉,我想从其结果中获取以下信息:a) 实现结果需要多少次迭代? b) 绘制部分解的序列,即每次迭代最后得到的解。

我目前的代码如下:

  f1 <- function(x) {
  x1 <- x[1]
  x2 <- x[2]
  x1^2 + 3*x2^2
}

res <- optim(c(1,1), f1, method="CG")

我该如何改进它以获取更多信息?

提前致谢。

3个回答

6
你可以修改你的函数,将传递给它的值存储到一个全局列表中。
i <- 0  
vals <- list()
f1 <- function(x) {
  i <<- i+1
  vals[[i]] <<- x

  x1 <- x[1]
  x2 <- x[2]
  x1^2 + 3*x2^2  
}

res <- optim(c(1,1), f1, method="CG")

现在,如果你运行函数后检查 i 和 vals,就能看到发生了什么。如果你想在优化过程中看到这些值,请在函数中加入打印语句。

2
一个很好的函数式编程练习是编写一个函数,该函数以另一个函数作为参数,并返回一个与该参数函数相同但将日志记录到全局的函数。然后,您可以通过包装函数而不是更改函数来向任何传递给优化器的函数添加日志记录! - Spacedman
很高兴有这么多选择,但我认为这个最适合我的情境。非常感谢你们! - gcolucci

6
trace=1作为控制参数传递给optim,可以获得更详细的优化进度信息:
res <- optim(c(1,1), f1, method="CG", control=list(trace=1))
# Conjugate gradients function minimizer
# Method: Fletcher Reeves
# tolerance used in gradient test=3.63798e-12
# 0 1 4.000000
# parameters    1.00000    1.00000 
# * i> 1 4 0.480000
# parameters    0.60000   -0.20000 
#   i> 2 6 0.031667
# ......
# * i> 13 34 0.000000
# parameters   -0.00000    0.00000 
# 14 34 0.000000
# parameters   -0.00000    0.00000 
# Exiting from conjugate gradients minimizer
#   34 function evaluations used
#   15 gradient evaluations used

然而,似乎信息只写入标准输出,因此您需要使用 sink 将输出导向文本文件,然后进行一些编辑以获取绘图的参数值。


4

如果您只需要函数评估的数量,请参见结果的$counts元素:

 counts: A two-element integer vector giving the number of calls to
          ‘fn’ and ‘gr’ respectively. This excludes those calls needed
          to compute the Hessian, if requested, and any calls to ‘fn’
          to compute a finite-difference approximation to the gradient.

对于部分解决方案,您需要使用@Dason的解决方案或类似的解决方案。


+1,但我在想counts和实际迭代次数之间的关系。比如,我将最大迭代次数设置为maxit = 10,但我可以获得fn的计数为20. 我们该如何解释这个现象? - Randel
1
取决于方法和细节:例如,Nelder-Mead 方法在每次迭代中可以根据局部几何情况采用不同数量(我想是2-3个)的函数评估。例如,尝试 example("optim"); optim(c(-1.2,1), fr, method = "Nelder-Mead",control=list(trace=100)) - Ben Bolker

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接