2017-06-12 14 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) 

GENE1 32.60705

GENE1 32.31657

これは動作しません! OPTIMで

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

エラー(のparams = Cの(3、10、2、9、rowMeans(データ[1])[1])、データ= DATA1、: タイプを強制することができない '閉鎖'オブジェクト名は、ユーザーが作成した(または作成する)として、「ダブル」タイプのベクトルに

+1

関数をどのように定義すべきかについては '?optim'を見てください。 –

+0

さらなるオプションが関数に渡されるので、データを引数として持つことができます。問題は、最適化するパラメータの 'optim'パラメータ名が' params'ではなく 'par'であることです。 '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の両方を節約して、そしてそれがoptimの最初のパラメータにマッチなっていたので、最初の無名のパラメータはLikた、そのことでした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 

だから、パラメータの名前をデータ以外の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に供給された2番目のパラメータが機能リク、ではないデータでなければなりません。インタプリタは、データ1をクロージャとして解釈しようとします。 data1とLikの位置を入れ替えることができます。

さらに重要なのは、@李哲源ZheyuanLiも指摘しているように、「データ」という名前の最適化パラメータはありません。追加の関数パラメータ "..."の代わりに "data1"と書くだけです。

そして最後も@Aaronが指摘したように、最初のパラメータは「「パー」がparamsはないと命名される。パラメータがオーバー最適化するために

+0

@李哲源ZheyuanLi True、もう一つの問題は、optimのパラメータの順序です。 data = data1とLikは間違って配置されます。もちろん、あなたが指摘したように、「データ」という名前の最適化パラメータはありません。 –

+0

パラメータ 'data'の命名はコード内で問題ではありません。そして、私が通常「データ」という名前を付けるのは悪い考えですが、それを関数のパラメータとして使用することは別の問題です。これは一般的に(例えば 'lm'のように)行われ、最適化したい関数の種類に意味をなさけることができます。 – Aaron