调试函数的优化

时间:2017-06-12 15:17:10

标签: r function optimization

我有一个函数在被要求计算-logLik给定参数时工作得很好。但是,如果我尝试优化该函数,则会返回错误消息。我熟悉debug()来处理函数的问题,但是我如何为一个有效的函数调试优化呢?

Lik <- function(params, data) { 
....
return(-log( **likelihood equation** ))
}

这些工作!

Lik(params=c(3,10,2,9,rowMeans(data[1,])[1]), data = data1)
Lik(params=c(3,10,2,9.5,rowMeans(data[1,])[1]), data = data1)
  
    

GENE1 32.60705

         

GENE1 32.31657

  

这不起作用!

optim(params=c(3,10,2,9,rowMeans(data[1,])[1]), data = data1, Lik, method = "BFGS")
  

optim中的错误(params = c(3,10,2,9,rowMeans(data [1,])[1]),data = data1,:    不能强制类型'封闭'强加到'double'类型的向量

2 个答案:

答案 0 :(得分:1)

要优化的参数的optim参数名称为par,而不是params。您不需要更改Lik函数,只需要将参数优化为第一个参数,名称无关紧要。

这应该有效。在这里,我也将fn参数命名为,但因为其他参数被命名为位置查找工作。

optim(par=c(3, 10, 2, 9, rowMeans(data[1, ])[1]), 
      data=data1, fn=Lik, method="BFGS")

因此,您的代码中发生的事情是保存了paramsdata以发送到该函数,然后第一个未命名的参数是Lik,因此它匹配到optim的第一个参数,即par,要优化的参数。该参数应该是一个数字(技术上是一个double),但是你发送了一个函数(技术上是一个闭包),因此出现了错误消息。

要进行调试,您可以打开针对optim debug(optim)的调试,然后在第一次浏览时,浏览它正在使用的参数。你可能已经找到了这个,但只是在探索参数时,你会发现你错误地命名它们。

Browse[2]> print(par)
function(params, data) {... return(-log( **likelihood equation** ))}
Browse[2]> print(fn)
Error in print(fn) : argument "fn" is missing, with no default

答案 1 :(得分:0)

使用内置函数名作为用户创建(或创建)的对象名称是不好的做法。

当用户尚未创建“数据”对象(矩阵或数据框)时,R解释器扫描环境并发现名为“data”的唯一对象是内置的“数据”函数:< / p>

> class(data)
[1] "function"
> str(data)
function (..., list = character(), package = NULL, lib.loc = NULL, verbose = getOption("verbose"), 
    envir = .GlobalEnv)  

因此,R将“数据”对象视为不能被子集化的闭包(函数声明):

> data[1]
Error in data[1] : object of type 'closure' is not subsettable

所以你应该把参数的名字改为sth而不是数据。

第二点,optim的语法是:

optim(par, fn, gr = NULL, ...,
           method = c("Nelder-Mead", "BFGS", "CG", "L-BFGS-B", "SANN",
                      "Brent"),
           lower = -Inf, upper = Inf,
           control = list(), hessian = FALSE)

因此在您的示例中,提供给optim的第二个参数应该是函数Lik,而不是数据。并且解释器尝试将data1解释为闭包。您可以尝试交换data1和Lik的位置。

更重要的是,@李哲源ZheyuanLi也指出,在optim中没有名为“data”的参数。您应该将其写为“data1”来代替附加功能参数“...”。

最后,同样@Aaron指出,第一个参数被命名为“par”而不是params“。