tl;dr 如果响应变量大于二项式 N(这是理论 响应的最大值)。在大多数实际问题中,N 被认为是已知的,并且只估计了概率。如果您确实想估计 N,您需要 (1) 将其限制为 >= 样本中的最大值; (2) 对必须离散的参数做一些特殊的优化(这是一个高级/棘手的问题)。
此答案的第一部分显示了用于识别问题的调试策略,第二部分说明了同时优化 N 和 p 的策略(通过蛮力在合理的 N 范围内)。
设置:
set.seed(101)
n <- 100
xi <- rbinom(n, size=20, prob=0.5) # Sample
对数似然函数:
lnlike <- function(theta){
log(prod(choose(theta[1],xi))) + sum(xi*log(theta[2])) +
(n*theta[1] - sum(xi))*log(1-theta[2])
}
让我们分解一下。
theta <- c(10,0.3) ## starting values
lnlike(c(10,0.3)) ## -Inf
好的,对数似然是-Inf 的起始值。 optim() 无法使用它也就不足为奇了。
让我们研究一下这些条款。
log(prod(choose(theta[1],xi))) ## -Inf
好的,第一学期我们已经有麻烦了。
prod(choose(theta[1],xi)) ## 0
产品为零……为什么?
choose(theta[1],xi)
## [1] 120 210 10 0 0 10 120 210 0 0 45 210 1 0
很多零。为什么? xi 的哪些值有问题?
## [1] 7 6 9 12 11 9 7 6
啊哈! 7、6、9 我们没问题……但是 12 就麻烦了。
badvals <- (choose(theta[1],xi)==0)
all(badvals==(xi>10)) ## TRUE
如果你真的想这样做,你可以通过暴力枚举n 的合理值来做到这一点......
## likelihood function
llik2 <- function(p,n) {
-sum(dbinom(xi,prob=p,size=n,log=TRUE))
}
## possible N values (15 to 50)
nvec <- max(xi):50
Lvec <- numeric(length(nvec))
for (i in 1:length(nvec)) {
## optim() wants method="Brent"/lower/upper for 1-D optimization
Lvec[i] <- optim(par=0.5,fn=llik2,n=nvec[i],method="Brent",
lower=0.001,upper=0.999)$val
}
nvec[which.min(Lvec)] ## 20
par(las=1,bty="l")
plot(nvec,Lvec,type="b")