如何计算对数正态数据集平均值的置信区间?


19

我在很多地方都听说过/可以通过获取每个样本的对数来将数据集转换为正态分布的东西,计算转换后的数据的置信区间,并使用逆运算将其转换回(例如,将分别提高10到下限和上限的幂)。log10

但是,我对此方法有点怀疑,仅仅是因为它不适用于平均值:10mean(log10(X))mean(X)

正确的方法是什么?如果它对均值本身不起作用,那么如何在均值的置信区间内起作用?


3
你说的很对。这种方法通常不起作用,通常会产生不包括总体平均值甚至样本平均值的置信区间。这是有关此问题的一些讨论:amstat.org/publications/jse/v13n1/olsson.html这不是答案,因为我没有深入研究此问题,无法对链接进行详细评论。
艾里克(Erik)

3
这个问题有一个经典的解决方案:projecteuclid.org/…epa.gov/oswer/riskassesssment/pdf/ucl.pdf中提供了一些其他解决方案,包括代码,但请仔细阅读,因为那里至少描述了一种方法(“ Chebyshev不等式方法”)完全是错误的。
ub

Answers:


11

有几种计算对数正态分布平均值的置信区间的方法。我将介绍两种方法:引导程序和概要文件可能性。我还将介绍有关杰弗里斯事前的讨论。

引导程序

对于MLE

在这种情况下,的MLE对样品(μ,σ)(x1,...,xn)

μ^=1nj=1nlog(xj);σ^2=1nj=1n(log(xj)μ^)2.

然后,平均值的MLE为。通过重新采样,我们可以获得的引导样本,并使用此样本,可以计算出多个引导置信区间。以下代码显示了如何获取它们。δ^=exp(μ^+σ^2/2)δ^R

rm(list=ls())
library(boot)

set.seed(1)

# Simulated data
data0 = exp(rnorm(100))

# Statistic (MLE)

mle = function(dat){
m = mean(log(dat))
s = mean((log(dat)-m)^2)
return(exp(m+s/2))
}

# Bootstrap
boots.out = boot(data=data0, statistic=function(d, ind){mle(d[ind])}, R = 10000)
plot(density(boots.out$t))

# 4 types of Bootstrap confidence intervals
boot.ci(boots.out, conf = 0.95, type = "all")

对于样本均值

现在,考虑到估计δ~=x¯代替MLE。也可以考虑其他类型的估计量。

rm(list=ls())
library(boot)

set.seed(1)

# Simulated data
data0 = exp(rnorm(100))

# Statistic (MLE)

samp.mean = function(dat) return(mean(dat))

# Bootstrap
boots.out = boot(data=data0, statistic=function(d, ind){samp.mean(d[ind])}, R = 10000)
plot(density(boots.out$t))

# 4 types of Bootstrap confidence intervals
boot.ci(boots.out, conf = 0.95, type = "all")

轮廓可能性

有关似然和轮廓似然函数的定义,请参见。使用我们可以reparameterise的可能性的不变性性质如下(μ,σ)(δ,σ),其中,δ=exp(μ+σ2/2),然后计算数值的简档的可能性δ

Rp(δ)=supσL(δ,σ)supδ,σL(δ,σ).

该函数取值;级别为的间隔的置信度约为。我们将使用此属性为构造置信度间隔。以下代码显示如何获取此间隔。(0,1]0.147 95 δ95%δR

set.seed(1)

# Simulated data
data0 = exp(rnorm(100))

# Log likelihood
ll = function(mu,sigma) return( sum(log(dlnorm(data0,mu,sigma))))

# Profile likelihood
Rp = function(delta){
temp = function(sigma) return( sum(log(dlnorm(data0,log(delta)-0.5*sigma^2,sigma)) ))
max=exp(optimize(temp,c(0.25,1.5),maximum=TRUE)$objective     -ll(mean(log(data0)),sqrt(mean((log(data0)-mean(log(data0)))^2))))
return(max)
}

vec = seq(1.2,2.5,0.001)
rvec = lapply(vec,Rp)
plot(vec,rvec,type="l")

# Profile confidence intervals
tr = function(delta) return(Rp(delta)-0.147)
c(uniroot(tr,c(1.2,1.6))$root,uniroot(tr,c(2,2.3))$root)

贝叶斯

在本节中,提出了一种基于Metropolis-Hastings采样和使用Jeffreys Prior的替代算法,用于计算的可信区间。δ

回想一下,现有杰弗瑞斯为在对数正态模型是(μ,σ)

π(μ,σ)σ2,

并且该先验在重新参数化下是不变的。该先验是不适当的,但是如果样本大小为,则参数的后验是正确的。以下代码显示了如何使用此贝叶斯模型获得95%的可信区间。n2R

library(mcmc)

set.seed(1)

# Simulated data
data0 = exp(rnorm(100))

# Log posterior
lp = function(par){
if(par[2]>0) return( sum(log(dlnorm(data0,par[1],par[2]))) - 2*log(par[2]))
else return(-Inf)
}

# Metropolis-Hastings
NMH = 260000
out = metrop(lp, scale = 0.175, initial = c(0.1,0.8), nbatch = NMH)

#Acceptance rate
out$acc

deltap = exp(  out$batch[,1][seq(10000,NMH,25)] + 0.5*(out$batch[,2][seq(10000,NMH,25)])^2  )

plot(density(deltap))

# 95% credibility interval
c(quantile(deltap,0.025),quantile(deltap,0.975))

请注意,它们非常相似。


1
(+1),我想你也可以基于与distrMod [R封装的最大似然理论置信区间
斯特凡洛朗

@StéphaneLaurent感谢您的信息。我希望看到您的代码具有新的先验结果。我不知道您使用的命令和程序包。

4
n

一流的反应!此处建议的方法假设同构模型错误-我曾在此假设难以成立的项目中工作。我还建议使用伽玛回归作为替代方法,这样可以避免进行偏差校正。
Isabella Ghement

4

您可以尝试用杰弗里斯(Jeffreys)的贝叶斯方法。它应产生具有正确的频繁匹配属性的可信区间:可信区间的置信度接近其可信度。

 # required package
 library(bayesm)

 # simulated data
 mu <- 0
 sdv <- 1
 y <- exp(rnorm(1000, mean=mu, sd=sdv))

 # model matrix
 X <- model.matrix(log(y)~1)
 # prior parameters
 Theta0 <- c(0)
 A0 <- 0.0001*diag(1)
 nu0 <- 0 # Jeffreys prior for the normal model; set nu0 to 1 for the lognormal model
 sigam0sq <- 0
 # number of simulations
 n.sims <- 5000

 # run posterior simulations
 Data <- list(y=log(y),X=X)
 Prior <- list(betabar=Theta0, A=A0, nu=nu0, ssq=sigam0sq)
 Mcmc <- list(R=n.sims)
 bayesian.reg <- runireg(Data, Prior, Mcmc)
 mu.sims <- t(bayesian.reg$betadraw) # transpose of bayesian.reg$betadraw
 sigmasq.sims <- bayesian.reg$sigmasqdraw

 # posterior simulations of the mean of y: exp(mu+sigma²/2)
 lmean.sims <- exp(mu.sims+sigmasq.sims/2)

 # credibility interval about lmean:
 quantile(lmean.sims, probs = c(0.025, 0.975))

这听起来很有趣,并且由于我倾向于喜欢贝叶斯方法,所以我对此表示赞同。仍然可以通过添加一些参考或什至最好是对其工作原理的可理解的解释加以改进。
艾里克(Erik)2012年

μσ2μσ2μσ2f(μ,σ2)μσ2。我不知道是否有一些参考,但否则您可以通过模拟进行检查。
斯蒂芬·洛朗

非常感谢您的讨论。为了清楚起见,为了避免混淆,我删除了所有评论。(+1)

1
@Procrastinator也谢谢。我还删除了我的注释,并在代码中添加了有关Jeffreys的观点。
斯特凡·洛朗

有人可以向我解释boots.out = boot(data = data0,statistic = function(d,ind){mle(d [ind])},R = 10000)的工作方式。我看到“ ind”是一个索引,但是我不明白如何找到“ ind”。第二个参数在哪里引用?我已经尝试过使用其他功能,但没有用。查看实际的功能启动,我也看不到Ind的引用。
andor kesselman

0

但是,我对此方法有点怀疑,只是因为它不适用于平均值本身:10mean(log10(X))≠mean(X)

您是对的-这是几何平均值的公式,而不是算术平均值。算术平均值是来自正态分布的参数,通常对对数正态数据意义不大。如果您想更有意义地谈论数据的集中趋势,则几何平均值是对数正态分布中的相应参数。

实际上,您可以通过取数据的对数,照常计算平均值和CI并进行反变换来计算有关几何平均值的CI。没错,您真的不想通过将几何平均值的CI放在算术平均值周围来混合您的分布。。。

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.