手动计算的对数似然值与logLik函数计算值的差异问题
Gamma分布对数似然值计算差异解惑
你遇到的问题很典型——Gamma分布的参数化方式很容易搞混,这正是两个结果差异的核心原因!
先复盘你的操作:
你用rgamma(50, shape=2, scale=10)生成符合Gamma分布的样本,通过fitdist(x, "gamma")拟合模型后,调用logLik()得到对数似然值为-189.4192;但自己编写的gmll函数传入真实参数(scale=10, shape=2)后,得到的结果却是-246.6081,两者数值差距明显。
问题根源:手动对数似然公式错误
首先明确R中Gamma分布的参数化规则:rgamma()使用的是shape(α)和scale(θ)的参数形式,对应的概率密度函数(PDF)为:
f(x) = (x^(α-1) * exp(-x/θ)) / (θ^α * Γ(α))
对所有样本的PDF取对数后求和,得到对数似然函数(注意是对数似然,而非负对数似然)的正确形式:
[
\ell(\alpha, \theta) = (\alpha-1)\sum\log(x_i) - \frac{1}{\theta}\sum x_i - n\alpha\log\theta - n\log\Gamma(\alpha)
]
对比你的gmll函数:
gmll <- function(scale,shape,datta){ a <- scale # 错误:将scale赋值给a,而公式中lgamma的参数应为shape b <- shape # 错误:参数对应关系混乱 n <- length(datta) sumd <- sum(datta) sumlogd <- sum(log(datta)) gmll <- n*a*log(b) + n*lgamma(a) + sumd/b - (a-1)*sumlogd gmll }
这里存在三个关键错误:
- 参数对应完全颠倒:
lgamma()的参数应该是shape(α),你却传入了scale(θ); - 符号全部写反:正确公式里的
nαlogθ、nlogΓ(α)是减项,你写成了加项;sum(x_i)/θ是减项,你写成了加项;(α-1)Σlog(x_i)是加项,你写成了减项; - 参数代入错误:
sumd/b中用shape(α)做分母,正确的应该是用scale(θ)做分母。
修正后的手动计算函数
把公式修正后,手动计算的结果就会和logLik()的输出一致:
gmll_correct <- function(shape, scale, datta){ alpha <- shape theta <- scale n <- length(datta) sum_x <- sum(datta) sum_logx <- sum(log(datta)) # 正确的对数似然计算公式 ll <- (alpha - 1)*sum_logx - sum_x/theta - n*alpha*log(theta) - n*lgamma(alpha) ll }
测试验证(设置随机种子保证结果可复现):
set.seed(123) x <- rgamma(50, shape = 2, scale = 10) Gamma_fitdist <- fitdist(x, "gamma") # 拟合参数的对数似然 logLik(Gamma_fitdist) # 真实参数的对数似然 gmll_correct(shape=2, scale=10, datta=x)
两者结果会非常接近(因为拟合参数是真实参数的最大似然估计,样本随机生成会有微小误差)。
内容的提问来源于stack exchange,提问作者felipe gateño
相关产品推荐
相关产品推荐

