简体   繁体   中英

Evaluating and plotting a 3d log-likelihood function using R

My objective is to evaluate and to plot the following log-likelihood function with two parameters:

set.seed(123)
N = 100
x = 4*rnorm(N)
y = 0.8*x + 2*rnorm(N);

LogL <- function(param,x,y,N){
        beta = param[1]
        sigma2 = param[2]
        LogLikelihood =  -N/2*log(2*pi*sigma2) - sum( (y - beta*x)^2 / (2*sigma2) ) }

I've tried using 'outer' in order to use 'wireframe' as in the following thread:

How can I plot 3D function in r?

but without success:

param1 <- seq(-2, 2, length= 30)
param2 <- seq(0.1, 4, length= 30)
values1 <- matrix(c(param1,param2),30)
z <- outer(values1, x=x,y=y,N=N, LogL)

How can I use 'outer' properly in this case? Is there any other alternative to evaluate and to plot the function 'LogL'?

The first question is that outer() needs to have the two arguments to LogL() as separate vectors, which means rewriting your function to use the two arguments instead of one length 2 argument that you unpack. In addition, (from ?outer)

Each will be extended by rep to length the products of the lengths of X and Y before FUN is called.

so the function needs to deal with ALL the possible values of X and Y in a single call. There's probably a better way to do this, but in the interest of simplicity, I used a for() loop to loop over the different values of X and Y.

set.seed(123)
N = 100
x = 4*rnorm(N)
y = 0.8*x + 2*rnorm(N);

LogL <- function(param1, param2, x, y, N){
  beta = param1
  sigma2 = param2
  LogLikelihood = vector("numeric",length(beta))
  for (i in 1:length(beta)){
    LogLikelihood[i] = -N/2*log(2*pi*sigma2[i]) - sum( (y - beta[i]*x)^2 / (2*sigma2[i]) )
  }
  return(LogLikelihood)
}

param1 <- seq(-2, 2, length= 30)
names(param1) <- param1
param2 <- seq(0.1, 4, length= 30)
names(param2) <- param2


z <- outer(X = param1, Y = param2, FUN = LogL, N = N, x = x, y = y)

require(lattice)
#> Loading required package: lattice
wireframe(z, drape=T, col.regions=rainbow(100))

# test it out
LogL(param1[3], param2[3],  x = x, y = y, N = N)
#> [1] -11768.37

z[3,3]
#> [1] -11768.37

and that works.

Created on 2018-03-13 by the reprex package (v0.2.0).

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM