Error with custom density function definition for mle2 formula call

泄露秘密 提交于 2019-12-23 00:25:14

问题


I want to define my own density function to be used in the formula call to mle2 from R's bbmle package. The parameters of the model are estimated but I cannot apply functions like residuals or predict on the returned mle2 object.

This is an example in which I define a function for a simple Poisson model.

library(bbmle)

set.seed(1)
hpoisson <- rpois(1000, 10)

myf <- function(x, lambda, log = FALSE) {
  pmf <- (lambda^x)*exp(-lambda)/factorial(x)
  if (log)
    log(pmf)
  else
    pmf
}

myfit <- mle2(hpoisson ~ myf(lambda), start = list(lambda=9), data=data.frame(hpoisson))
residuals(myfit)

In myfit, the lambda is estimated correctly but when I call residuals on myfit, I get an error which says:

Error in myf(9.77598906811668) : 
  argument "lambda" is missing, with no default

On the other hand, if I simply fit the model as follows using R's built-in dpois function, the residuals are computed:

myfit <- mle2(hpoisson ~ dpois(lambda), start = list(lambda=9), data=data.frame(hpoisson))
    residuals(myfit)

Could anyone please tell me what I am doing wrong in the function definition of myf?

Thanks


回答1:


It's not very clearly explained in the documents, but there are a few prerequisites for using custom density functions:

  • the function's name must start with d, must have first argument x, and must have a named argument log. (The log argument has to do something sensible: in particular, mle2 will call the function with log=TRUE, and the function had better return the log-likelihood!) In general, although it's not required, it's more numerically sensible to compute the log-likelihood directly and then exponentiate if log=FALSE, rather than computing the likelihood and logging it if log=TRUE (there are cases, such as zero-inflated models, where this isn't really feasible). For example, compare my dmyf() definition with the myf() definition in the OP's code ...
  • in order to use additional methods such as predict you have to define an additional function whose name starts with s; it returns a list of moments, summary statistics, etc. for a specified parameter -- see example below, which is copied from bbmle::spois.
library("bbmle")
set.seed(1)
hpoisson <- rpois(1000, 10)

dmyf <- function(x, lambda, log = FALSE) {
    logpmf <- x*log(lambda)-lambda-lfactorial(x)
    if (log) return(logpmf)  else return(exp(logpmf))
}
smyf <- function(lambda) {
    list(title = "modified Poisson",
         lambda = lambda, mean = lambda,
         median = qpois(0.5, lambda),
         mode = NA, variance = lambda, sd = sqrt(lambda))
}
myfit <- mle2(hpoisson ~ dmyf(lambda),
              start = list(lambda=9), data=data.frame(hpoisson))
residuals(myfit)



回答2:


Not really an answer, but more help needed on this:

I used this to try to make a "custom" beta-binomial function to mimic the one in the first bit of the bbmle vignette.

set.seed(1001)
x1 <- rbetabinom(n=1000, prob=0.1, size=50, theta=10)
dmybetabinom <- function(x, N, theta, p, log=FALSE) {
    (choose(N,x)*beta(N-x+theta*(1-p),x+theta*p))/beta(theta*(1-p),theta*p)
}

The function works like dbetabinom:

dbetabinom(0:9,size=9,theta=4, prob=0.5) [1] 0.04545455 0.08181818 0.10909091 0.12727273 0.13636364 0.13636364 0.12727273 0.10909091 [9] 0.08181818 0.04545455 dmybetabinom(0:9,N=9,theta=4, p=0.5) [1] 0.04545455 0.08181818 0.10909091 0.12727273 0.13636364 0.13636364 0.12727273 0.10909091 [9] 0.08181818 0.04545455

But when I try to use the mle2 function on it, I am met with this error:

m0fa <- mle2(x1~dmybetabinom( N=50, theta, p), start=list(p=0.2, theta=9), data=data.frame(x1) )`

Error in optim(par = c(0.2, 9), fn = function (p)  :   non-finite finite-difference value [1] `


来源:https://stackoverflow.com/questions/28384164/error-with-custom-density-function-definition-for-mle2-formula-call

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!