【问题标题】:Error in fitdist with gamma distribution伽马分布的 fitdist 错误
【发布时间】:2019-01-31 20:28:40
【问题描述】:

以下是我的代码:

library(fitdistrplus)

s <- c(11, 4, 2, 9, 3, 1, 2, 2, 3, 2, 2, 5, 8,3, 15, 3, 9, 22, 0, 4, 10, 1, 9, 10, 11,
 2, 8, 2, 6, 0, 15, 0 , 2, 11, 0, 6, 3, 5, 0, 7, 6, 0, 7, 1, 0, 6, 4, 1, 3, 5,
 2, 6, 0, 10, 6, 4, 1, 17, 0, 1, 0, 6, 6, 1, 5, 4, 8, 0, 1, 1, 5, 15, 14, 8, 1,
 3, 2, 9, 4, 4, 1, 2, 18, 0, 0, 10, 5, 0, 5, 0, 1, 2, 0, 5, 1, 1, 2, 3, 7)

o <- fitdist(s, "gamma", method = "mle")
summary(o)
plot(o)

错误提示:

fitdist(s, "gamma", method = "mle") 中的错误:函数 mle 无法估计参数, 错误代码 100

【问题讨论】:

  • 以下解决方案是否解决了您的问题?如果是这样,请单击复选标记以接受其中一项。如果没有,请告诉我们为什么不...

标签: r statistics fitdistrplus


【解决方案1】:

只需提供要使用optim 使用mle 计算的伽马分布参数(比例、形状)的初始值以及参数的下限,它应该可以工作。

o <- fitdist(s, "gamma", lower=c(0,0), start=list(scale=1,shape=1))
summary(o)

#Fitting of the distribution ' gamma ' by maximum likelihood 
#Parameters : 
#      estimate Std. Error
#scale 4.626262         NA
#shape 1.000000         NA
#Loglikelihood:  -250.6432   AIC:  505.2864   BIC:  510.4766 

根据@Ben Bolker 的 cmets,我们可能希望首先排除零点:

o <- fitdist(s[s!=0], "gamma", method = "mle", lower=c(0,0), start=list(scale=1,shape=1))
summary(o)
#Fitting of the distribution ' gamma ' by maximum likelihood 
#Parameters : 
#      estimate Std. Error
#scale 3.401208         NA
#shape 1.622378         NA
#Loglikelihood:  -219.6761   AIC:  443.3523   BIC:  448.19

【讨论】:

  • 再次,我认为值得指出的是,在包含零的情况下,此过程有效地拟合了指数分布(即形状参数限制为 1 的 Gamma)。
  • @Ben Bolker 正如您所提到的,它适合具有较低对数似然的指数分布(形状=1),在第一种情况下,在第二种情况下拟合的伽马分布具有较高的对数似然,因此它更适合。
  • 我对此表示反对,因为最初提出的“解决方案”可能具有高度误导性。如果在开始时编辑答案以给出警告,我很乐意恢复反对票。
【解决方案2】:

Gamma 分布不允许零值(对于 0 的响应,可能性将评估为零,并且对数似然将是无限的),除非形状参数正好是 1.0(即指数分布 - 请参阅下面)......这是一个统计/数学问题,而不是编程问题。您将不得不找到一些明智的做法来处理零值。根据您的应用程序的意义,您可以(例如)

  • 选择不同的发行版进行测试
  • 排除零值 (fitdist(s[s&gt;0], ...))
  • 将零值设置为一些合理的非零值(fitdist(replace(s,which(s==0),0.1),...)

哪些(如果有)最好取决于您的应用程序


@Sandipan Dey 的第一个答案(在数据集中保留零)似乎有道理,但实际上它停留在等于 1 的形状参数上。

o <- fitdist(s, "exp", method = "mle")

给出与@Sandipan 的代码相同的答案(除了它估计速率=0.2161572,尺度参数的倒数=4.626262,它是为 Gamma 分布估计的——这只是参数化的变化)。如果您选择拟合指数而不是 Gamma,那很好 - 但您应该故意这样做,而不是偶然...

为了说明包含零的拟合可能无法按预期工作,我将构建自己的负对数似然函数并显示每种情况的似然面。

mfun <- function(sh,sc,dd=s) {
  -sum(dgamma(dd,shape=sh,scale=sc,log=TRUE))
}

library(emdbook)  ## for curve3d() helper function

包含零的表面:

cc1 <- curve3d(mfun(x,y),
      ## set up "shape" limits" so we evaluate
      ## exactly shape=1.000 ...
        xlim=c(0.55,3.55),
        n=c(41,41),
        ylim=c(2,5),
        sys3d="none")


png("gammazero1.png")
with(cc1,image(x,y,z))
dev.off()

在这种情况下,表面仅在 shape=1 处定义(即指数分布);白色区域代表无限对数似然。不是 shape=1 是 best 合适的,而是它是 only 合适的 ...

除零表面:

cc2 <- curve3d(mfun(x,y,dd=s[s>0]),
               ## set up "shape" limits" so we evaluate
               ## exactly shape=1.000 ...
               xlim=c(0.55,3.55),
               n=c(41,41),
               ylim=c(2,5),
               sys3d="none")


png("gammazero2.png")
with(cc2,image(x,y,z))
with(cc2,contour(x,y,z,add=TRUE))
abline(v=1.0,lwd=2,lty=2)
dev.off()

【讨论】:

  • @Bon Bolker 根据伽马分布的统计特性,它不允许零值,从tminka.github.io/papers/minka-gamma.pdf 开始,对数似然有一个对非正数 x 未定义的对数项,但我认为 fitdist 使用的 mledist 函数在内部调用 optim 的迭代优化必须使用 log(0) = 0 或类似的东西,你怎么看?
  • 我猜测形状参数在您的拟合中卡在 1.0(这是您的起点),优化发现形状参数的任何其他值的 NA 值......如果您的假设是正确的,那么您的 fitdist() 调用应该给出与您从数据中排除零值相同的结果。
  • 很好的解释
  • 先生。 Bolker 我对你的推荐有一个问题。从数据集中排除零显然有效,但我正在分析特定产品集的需求变量,我需要证明几周的需求最低(又名零)。那么在这种情况下你的建议是什么,我可以用 0.001 这样的低值替换零吗?
  • 我的意思是它很复杂。见stats.stackexchange.com/questions/187824/…