2

截断法线由下式给出:

dtnorm<- function(x, mean, sd, a, b) {
dnorm(x, mean, sd)/(pnorm(b, mean, sd)-pnorm(a, mean, sd))
}
ptnorm <- function(x, mean, sd, a, b) {
(pnorm(x,mean,sd) - pnorm(a,mean,sd)) / 
  (pnorm(b,mean,sd) - pnorm(a,mean,sd))
}

拟合由下式给出:

fitdist( data, tnorm, method="mle",
                    start=list(mean=mapply("[[", results[1], 1),
                               sd=mapply("[[", results[1], 2)),
                    fix.arg=list(a=minLoose,b=maxLoose))

其中 results[i] 是一个矩阵,其中 fitdist 的 mle 结果使用 normal 而不是 tnormal。

我得到以下 tnorm 的结果:

mean=-0.00844725266454969, sd=0.012540928272073

而规范:

mean=0.00748402597402597, sd=0.00614293813955003

数据均大于 0 且小于 0.04,因此为 tnorm 获得的 mle 似乎不正确....有什么建议吗?

谢谢!

4

2 回答 2

5

您的数据都高于正态(呃,而不是高于 0)这一事实与截断分布的最佳拟合的“平均值”是否超过 0 几乎没有关系。您正在拟合正态分布的右尾到您的数据。截断的估计位置参数并不是真正的平均值,而是平均值在未经审查的数据集中的位置,其右尾的密度“形状”与您的数据相同。(这实际上是一个统计问题,而不是 R 问题。)

您可以在 Wikipedia 文章的时刻部分找到计算双重截断 Normal 的期望值的公式: http ://en.wikipedia.org/wiki/Truncated_normal_distribution它很容易转化为对pnorm和的调用qnorm

进一步思考:查看在包中处理截断分布的工具:“gamlss”和“gamlss.tr”。

于 2012-08-23T18:22:54.173 回答
1

您可以使用此脚本的部分来估计参数

rm(list=ls(all=TRUE))


dtnorm<- function(x, mean, sd, a, b) {
dnorm(x, mean, sd)/(pnorm(b, mean, sd)-pnorm(a, mean, sd))
}


simuls=5
simul_mat=matrix(nrow=simuls,ncol=6)
for(simul in 1:simuls) {
acm=rnorm(1)
acsd=runif(1)*2+0.5
limits=sort(acm+rnorm(2))

all=limits[1]
aul=limits[2]



x=rnorm(10000)*acsd+acm
x=subset(x,x>all & x<aul)




    norm_parms<-function(parms){
    mp=parms[1]
    sdp=parms[2]^2
    ll=median(x)-parms[3]^2
    ul=median(x)+parms[4]^2

    xs=subset(x,x>ll & x<ul)
    ds=dtnorm(xs,mp,sdp,ll,ul)

    if(length(x)>5){
    do=rep(dnorm(-6),length(x)-length(xs))
    ds=c(ds,do)
    }
    if(length(x)<=5){
    ds=rep(dnorm(-9),length(x))
    }


    mll=-sum(log(ds))
    return(mll)
    }



bestv=Inf
methodss=c("Nelder-Mead", "BFGS", "CG", "L-BFGS-B", "SANN")
for(method in methodss){
try(bestc<-optim(par=c(0,1,1,1),norm_parms,method=method))
if(bestc$value<bestv) {best=bestc;bestv=bestc$value}
}



parms=best$par
mp=parms[1]
sdp=parms[2]^2
ll=median(x)-parms[3]^2
ul=median(x)+parms[4]^2
print(c(acm,acsd,all,aul))
print(c(mp,sdp,ll,ul))
print(best$value)
acparms=c(acm,acsd,sqrt(median(x)-all),sqrt(aul-median(x)))
acv=norm_parms(acparms) 
cnames=c("Actual a","Estimated a","Actual b","Estimated b","Actual optim","Best optim`")
simul_mat[simul,]=c(all,ll,aul,ul,best$value,acv)

cnames=c("Actual a","Estimated a","Actual b","Estimated b","Actual optim","Best optim`")
colnames(simul_mat)=cnames
print(simul_mat)

}
于 2015-09-24T21:36:56.837 回答