为什么我试图估计的参数是“未找到”?

时间:2011-07-02 23:04:34

标签: r optimization

我正在尝试优化R_jR_m的似然函数,使用optim估算al_jau_jb_jsigma_j 。这就是我所做的。

a = read.table("D:/ff.txt",header=T)
attach(a)   
a

  R_j         R_m
1  2e-03 0.026567295
2  3e-03 0.009798475
3  5e-02 0.008497274
4 -1e-02 0.012464578
5 -9e-04 0.002896023
6  9e-02 0.000879473
7  1e-02 0.003194435
8  6e-04 0.010281122

需要估算参数al_j,au_j,b_j和sigma_j。

llik=function(R_j,R_m)
 if(R_j< 0)
 {
 sum[log(1/(2*pi*(sigma_j^2)))-(1/(2*(sigma_j^2))*(R_j+al_j-b_j*R_m))^2]
 }else if(R_j>0)
 {
 sum[log(1/(2*pi*(sigma_j^2)))-(1/(2*(sigma_j^2))*(R_j+au_j-b_j*R_m))^2]
 }else if(R_j==0)
 {
 sum(log(pnorm(au_j,mean=b_j*R_m,sd=sigma_j)-pnorm(al_j,mean=b_j*R_m,sd=sigma_j)))
 }

start.par=c(al_j=0,au_j=0,sigma_j=0.01,b_j=1) 
out1=optim(llik,par=start.par,method="Nelder-Mead")

Error in pnorm(au_j, mean = b_j * R_m, sd = sigma_j) : 
  object 'au_j' not found

2 个答案:

答案 0 :(得分:2)

让我们从错误消息开始:

Error in pnorm(au_j, mean = b_j * R_m, sd = sigma_j) : 
  object 'au_j' not found

所以R告诉你,当它进入pnorm调用时,它无法在该调用中找到任何名为'au_j'的东西。您的下一步应该是查看您的函数llik,并尝试确定您希望如何在该函数中定义变量'au_j'。

此时,答案应该相当清楚(也许!)。在llik中没有任何地方为变量'au_j'分配了一个值。因此它不会在函数内“创建”。然后,R的范围规则将使它在全局环境中看到函数外的“au_j”。

你可能会说这是事情应该工作的地方,因为你在start.par中为'au_j'分配了一个值。但这是一个列表,R无法在列表中找到命名对象'au_j'。

所以这里的解决方案最有可能重写你的函数llik,以便它将所有它将使用的参数作为参数,因此你将把start.par中的所有内容添加到llik的参数中。类似的东西:

llik <- function(par=c(al_j,au_j,sigma_j,b_j),R_j,R_m){...}

然后在llik中你将使用par [1]等来引用al_j。然后optim调用应该类似于:

optim(start.par,llik,R_j=a$R_j,R_m=a$R_m)

由于您已经在a中附加了数据,因此您可能没有在optim调用中明确传递参数R_j和R_m,但这样做可能是一种好习惯。< / p>

我已经重建了你想要在这里完成的东西(以数学为模,我甚至没有看过),但我承认你的代码有点难以解析。我建议花一些时间在?optim中的示例,以确保您了解该函数的调用方式。

答案 1 :(得分:2)

很难说从哪里开始。

正如@mac所说,你的代码难以阅读。它还包含错误。

例如,如果您尝试sum[c(1,2)],则会收到错误:您应该使用sum(c(1,2))。无论如何,你似乎把钱花在了错误的地方。您无法在向量上使用ifelse if,并且需要使用ifelse。你没有什么可以阻止标准偏差消极。还有更多。

以下代码运行时没有错误或警告。你仍然需要决定它是否符合你的要求。

a <- data.frame( R_j = c(0.002,0.003,0.05,-0.01,-0.0009,0.09,0.01,0.0006),
                 R_m = c(0.026567295,0.009798475,0.008497274,0.012464578,
                         0.002896023,0.000879473,0.003194435,0.010281122) )

llik = function(x) 
   { 
    al_j=x[1]; au_j=x[2]; sigma_j=x[3];  b_j=x[4]
    sum(
        ifelse(a$R_j< 0, log(1/(2*pi*(sigma_j^2)))-
                           (1/(2*(sigma_j^2))*(a$R_j+al_j-b_j*a$R_m))^2, 
         ifelse(a$R_j>0 , log(1/(2*pi*(sigma_j^2)))-
                           (1/(2*(sigma_j^2))*(a$R_j+au_j-b_j*a$R_m))^2,
                          log(pnorm(au_j,mean=b_j*a$R_m,sd=sqrt(sigma_j^2))-
                           pnorm(au_j,mean=b_j*a$R_m,sd=sqrt(sigma_j^2))))) 
       )
   } 

start.par = c(0, 0, 0.01, 1) 
out1 = optim(llik, par=start.par, method="Nelder-Mead")