2017-06-12 137 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