R中的似然最大化

时间:2013-04-15 14:49:44

标签: r optimization

在R中,我写了一个包含两个递归计算的对数似然函数。对数似然函数正常工作(它给出了已知参数值的答案),但是当我尝试使用optim()来最大化时,它需要花费太多时间。我该如何优化代码?提前感谢您的想法。

这是具有使用copula函数的依赖结构的马尔可夫政权转换模型的对数似然函数。

log-likelihood function

在for循环中命名为g

g in the codes

在for循环中命名为p

p in the codes

代码中命名为f

f in the codes

一些数据:

u <- cbind(rt(100,10),rt(100,13))

f功能:

f=function(u,p,e1,e2){
     s=diag(2);s[1,2]=p
     ff=dcopula.gauss(cbind(pt(u[,1],e1),pt(u[,2],e2)),Sigma=s)*dt(u[,1],e1)*dt(u[,2],e2)
     return(ff)
  }

对数似然函数:

loglik=function(x){
  p11<-x[1];p12<-x[2];p21<-x[3];p22<-x[4];p31<-x[5];p32<-x[6];r<-x[7];a1<-x[8];a2<-x[9];s<-x[10];b1<-x[11];b2<-x[12];t<-x[13];c1<-x[14];c2<-x[15]
  p1=c(numeric(nrow(u)));p2=c(numeric(nrow(u)));p3=c(numeric(nrow(u)))
  g=c(numeric(nrow(u)))
  p1_0=.3
  p2_0=.3
  g[1]<-(p1_0*f(u,r,a1,a2)[1])+(p2_0*f(u,s,b1,b2)[1])+((1-(p1_0+p2_0))*f(u,t,c1,c2)[1])
  p1[1]<-((p1_0*p11*f(u,r,a1,a2)[1])+(p2_0*p21*f(u,r,a1,a2)[1])+((1-(p1_0+p2_0))*p31*f(u,r,a1,a2)[1]))/g[1]
  p2[1]<-((p1_0*p12*f(u,s,b1,b2)[1])+(p2_0*p22*f(u,s,b1,b2)[1])+((1-(p1_0+p2_0))*p32*f(u,s,b1,b2)[1]))/g[1]
  p3[1]<-((p1_0*(1-(p11+p12))*f(u,t,c1,c2)[1])+(p2_0*(1-(p21+p22))*f(u,t,c1,c2)[1])+((1-(p1_0+p2_0))*(1-(p31+p32))*f(u,t,c1,c2)[1]))/g[1]
  for(i in 2:nrow(u)){
    g[i]<-(p1[i-1]*p11*f(u,r,a1,a2)[i])+(p1[i-1]*p12*f(u,s,b1,b2)[i])+(p1[i-1]*(1-(p11+p12))*f(u,t,c1,c2)[i])+
      (p2[i-1]*p21*f(u,r,a1,a2)[i])+(p2[i-1]*p22*f(u,s,b1,b2)[i])+(p2[i-1]*(1-(p21+p22))*f(u,t,c1,c2)[i])+
      (p3[i-1]*p31*f(u,r,a1,a2)[i])+(p3[i-1]*p32*f(u,s,b1,b2)[i])+(p3[i-1]*(1-(p31+p32))*f(u,t,c1,c2)[i])
    p1[i]<-((p1[i-1]*p11*f(u,r,a1,a2)[i])+(p1[i-1]*p12*f(u,s,b1,b2)[i])+(p1[i-1]*(1-(p11+p12))*f(u,t,c1,c2)[i]))/g[i]
    p2[i]<-((p2[i-1]*p21*f(u,r,a1,a2)[i])+(p2[i-1]*p22*f(u,s,b1,b2)[i])+(p2[i-1]*(1-(p21+p22))*f(u,t,c1,c2)[i]))/g[i]
    p3[i]<-((p3[i-1]*p31*f(u,r,a1,a2)[i])+(p3[i-1]*p32*f(u,s,b1,b2)[i])+(p3[i-1]*(1-(p31+p32))*f(u,t,c1,c2)[i]))/g[i]
  }
  return(-sum(log(g)))
}

优化:

library(QRM)
library(copula)
start=list(0,1,0,0,0,0,1,9,7,-1,10,13,1,6,4)
##
optim(start,loglik,lower=c(rep(0,6),-1,1,1,-1,1,1,-1,1,1),
  upper=c(rep(1,6),1,Inf,Inf,1,Inf,Inf,1,Inf,Inf),
  method="L-BFGS-B") -> fit

1 个答案:

答案 0 :(得分:2)

这看起来像是Stack-Overflow的问题。

我想到的是:

  1. 定义包含值f(.,.,.,.)的向量,以避免对同一函数进行k*nrow(u)评估,并简单地调用那些感兴趣的条目。

  2. 似乎循环可以被矩阵和/或矢量产品取代。但是,如果没有进一步的信息,目前还不清楚代码在做什么,并且需要从代码中提取这些信息。