如何在不反转R中的奇异Hessian矩阵的情况下获得置信区间?

时间:2010-04-21 17:25:34

标签: r statistics confidence-interval

我是一名学生,正在研究R中的流行病学模型,使用最大似然法。我创建了我的负对数似然函数。这看起来很糟糕,但现在是:

NLLdiff = function(v1, CV1, v2, CV2, st1 = (czI01 - czV01), st2 = (czI02 - czV02), st01 = czI01, st02 = czI02, tt1 = czT01, tt2 = czT02) { 
    prob1 = (1 + v1 * CV1 * tt1)^(-1/CV1)
    prob2 = ( 1 + v2 * CV2 * tt2)^(-1/CV2) 
    -(sum(dbinom(st1, st01, prob1, log = T)) + sum(dbinom(st2, st02, prob2, log = T)))
 }

第一行看起来如此糟糕的原因是它所需的大部分数据都是在那里输入的。例如,czI01已经宣布。我这样做只是为了让我后来对函数的调用不一定都有可怕的向量。

然后我使用mle2(library bbmle)对CV1,CV2,v1和v2进行了优化。这看起来有点粗糙,看起来像:

ml.cz.diff = mle2 (NLLdiff, start=list(v1 = vguess, CV1 = cguess, v2 = vguess, CV2 = cguess), method="L-BFGS-B", lower = 0.0001)

现在,一切正常,直到这里。 ml.cz.diff给了我值,我可以把它变成一个合理地符合我数据的图。我也有几种不同的模型,可以获得AICc值来比较它们。但是,当我试图获得v1,CV1,v2和CV2周围的置信区间时,我遇到了问题。基本上,我在CV1上得到一个负面界限,这是不可能的,因为它实际上代表了生物模型中的平方数以及一些警告。

是否有更好的方法来获得置信区间?或者,真的,一种获得有意义的置信区间的方法吗?

我所看到的是,巧合的是,我的粗体矩阵对于优化空间中的某些值是单数的。但是,由于我优化了超过4个变量并且没有过多的编程知识,我无法想出一种不依赖于粗麻布的优化方法。我已经用Google搜索了问题 - 它表明我的模型很糟糕,但我正在重建之前完成的一些工作,这表明我的模型真的不太糟糕(我使用ml.cz.diff制作的图表看起来像原始作品的情节)。我还阅读了手册的相关部分以及Bolker的书生态模型在R 。我也尝试了不同的优化方法,这导致运行时间更长但错误相同。 “SANN”方法在一小时内没有完成运行,所以我没有等到看到结果。

简而言之:我的置信区间很差。是否有一种相对简单的方法可以在R中修复它们?

我的载体是:

czT01 = c(5, 5, 5, 5, 5, 5, 5, 25, 25, 25, 25, 25, 25, 25, 50, 50, 50, 50, 50, 50, 50)
czT02 = c(5, 5, 5, 5, 5, 10, 10, 10, 10, 10, 25, 25, 25, 25, 25, 50, 50, 50, 50, 50, 75, 75, 75, 75, 75)
czI01 = c(25, 24, 22, 22, 26, 23, 25, 25, 25, 23, 25, 18, 21, 24, 22, 23, 25, 23, 25, 25, 25)
czI02 = c(13, 16, 5, 18, 16, 13, 17, 22, 13, 15, 15, 22, 12, 12, 13, 13, 11, 19, 21, 13, 21, 18, 16, 15, 11)
czV01 = c(1, 4, 5, 5, 2, 3, 4, 11, 8, 1, 11, 12, 10, 16, 5, 15, 18, 12, 23, 13, 22)
czV02 = c(0, 3, 1, 5, 1, 6, 3, 4, 7, 12, 2, 8, 8, 5, 3, 6, 4, 6, 11, 5, 11, 1, 13, 9, 7)

我得到了猜测:

v = -log((c(czI01, czI02) - c(czV01, czV02))/c(czI01, czI02))/c(czT01, czT02)
vguess = mean(v)
cguess = var(v)/vguess^2

我也可能做其他完全错误的事情,但我的结果似乎合理,所以我没有抓住它。

1 个答案:

答案 0 :(得分:6)

您可以更改参数化,以便始终满足约束。将可能性重写为ln(CV1)和ln(CV2)的函数,这样就可以确保CV1和CV2保持严格正数。

NLLdiff_2 = function(v1, lnCV1, v2, lnCV2, st1 = (czI01 - czV01), st2 = (czI02 - czV02), st01 = czI01, st02 = czI02, tt1 = czT01, tt2 = czT02) { 
prob1 = (1 + v1 * exp(lnCV1) * tt1)^(-1/exp(lnCV1))
prob2 = ( 1 + v2 * exp(lnCV2) * tt2)^(-1/exp(lnCV2)) 
-(sum(dbinom(st1, st01, prob1, log = T)) + sum(dbinom(st2, st02, prob2, log = T)))
 }