2017-06-12 99 views
1

我有一个函数,在要求计算-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) 

基因1 32.60705

基因1 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(数据[1,])[1]),数据= DATA1,: 不能强制类型 '闭合'到型“双重”的矢量

+1

查看'?optim'来了解函数应该如何定义。 –

+0

其他选项将传递给该函数,因此将数据作为参数很好。问题是要优化的参数的'optim'参数名称是'par',而不是'params'。你不需要改变你的'Lik'函数,只需要将参数优化为第一个参数即可,名字无关紧要。 – Aaron

回答

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,参数要优化过。该参数应该是一个数字(在技术上是双精度),但是你发送了一个函数(技术上是闭包),因此是错误信息。

要进行调试,您可以打开调试优化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 
0

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

当没有“数据”对象(矩阵或数据框),R解释器扫描环境并找到唯一的对象名为“数据”是建立在“数据”功能:

> 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 

所以你应该将参数的名称改为数据以外的其他名称。

和第二点,的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第二个参数应该是函数沥,而不是数据。解释器试图将data1解释为闭包。你可以尝试交换data1和Lik的位置。

更重要的是@李哲源ZheyuanLi还指出,没有参数在优化中被命名为“数据”。你应该把它写成“data1”来代替附加的功能参数“...”。

而在去年,同样@Aaron指出,第一个参数被命名为“相提并论”不PARAMS”。

+0

@李哲源ZheyuanLi确实,另一个问题是优化参数的顺序。 data = data1和Lik错位。当然,您也指出,没有任何名为“数据”的优化参数。 –

+0

命名参数'数据'不是代码中的问题。虽然我通常都认为命名“数据”是个坏主意,但将它用作函数中的参数是另一回事。它通常是完成的(例如'lm'),并且可以在你想优化的功能类型中使用。 – Aaron