在R中发出abour integrate()函数

时间:2014-12-07 04:29:48

标签: r

我有一个关于R中的integrate()函数的问题。当我使用积分函数找到后验均值时,结果非常小(小于绝对误差)。如果我将Inf的上限更改为0.2或更小的数字,结果数字更有意义。为什么集成功能在较大的上限下无法正常工作?

非常感谢!

以下是我的代码:

dat = read.table("c://AAPL_logret.txt")$V1
mu = 0.005
theta = 200

posterior = function (sigma2, dat)
{
  numerator = function (sigma2, dat)
  {
    out = dexp(sigma2,theta)
    for (i in 1:length(dat))
    {
     out = out * dnorm(dat[i],mu, sqrt(sigma2))
    }
    return(out)   

  }

  denominator = integrate(numerator,lower = 0, upper = Inf, dat=dat)$value

  return (numerator(sigma2,dat)/denominator)
}

curve(posterior(x,dat), from =0, to = 0.006,xlab=expression(sigma^2), 
      ylab = "Density", cex.axis = 1.3, cex.lab=1.3, col=4,lwd=1.5,lty=4,n=20000)

posterior_times_sigma2 = function(sigma2,dat)
{
  return(sigma2 * posterior(sigma2,dat))
}

posteriormean = integrate(posterior_times_sigma2, lower =0, upper= Inf, dat=dat)$value

1 个答案:

答案 0 :(得分:2)

您尚未发布" AAPL_logret.txt"的内容。文件,所以我生成了可能看起来像这样的虚假数据,例如:

dat <- rlnorm(200, -4, 1)

使用此数据,您的曲线()图表显示后验分布的大部分概率质量包含在0到0.006之间:

 1-integrate(posterior, lower=0, upper=0.006, dat=dat)$value

约为4e-11,因此后部在数值上无法区分,超过0.006。 integrate()的R帮助页面解释了这里出了什么问题:

&#34;与所有数值积分程序一样,这些程序会评估 在有限的一组点上起作用。如果功能是 几乎所有的几乎恒定(特别是零) 范围可能是结果和误差估计可能 严重错误。&#34;

我认为这里没有一般的解决方案:任何给定的 您需要探索不同选择的情况。在你的情况下, 一种可能性是限制积分间隔:

integrate(posterior_times_sigma2, lower=0, upper=Inf, dat=dat)$value
integrate(posterior_times_sigma2, lower=0, upper=0.2, dat=dat)$value
integrate(posterior_times_sigma2, lower=0, upper=0.1, dat=dat)$value
integrate(posterior_times_sigma2, lower=0, upper=0.006, dat=dat)$value

不同的集成方法也可能有所帮助,例如pracma包提供的那些:

library(pracma)
integral(posterior_times_sigma2, xmin=0, xmax=Inf, dat=dat)

这是整个剧本:

##dat = read.table("c://AAPL_logret.txt")$V1

set.seed(1233)
dat <- rlnorm(100, -3, 0.1)

mu= 0.005
theta = 200

posterior = function (sigma2, dat){
numerator = function (sigma2, dat)  {
    out = dexp(sigma2, theta)
    for (i in 1:length(dat))    {
    out = out * dnorm(dat[i], mu, sqrt(sigma2))
    }
    return(out)   
}

denominator = integrate(numerator,lower = 0, upper = Inf, dat=dat)$value
return (numerator(sigma2,dat)/denominator)
}

curve(posterior(x,dat), from=0, to = 0.006,
  xlab=expression(sigma^2), ylab = "Density", cex.axis = 1.3,
  cex.lab=1.3, col=4, lwd=1.5, lty=4, n=20000)

integrate(posterior, lower=0, upper=0.006, dat=dat)$value

posterior_times_sigma2 = function(sigma2,dat){
return(sigma2 * posterior(sigma2,dat))
}

integrate(posterior_times_sigma2, lower=0, upper=Inf, dat=dat)$value
integrate(posterior_times_sigma2, lower=0, upper=0.2, dat=dat)$value
integrate(posterior_times_sigma2, lower=0, upper=0.1, dat=dat)$value
integrate(posterior_times_sigma2, lower=0, upper=0.006, dat=dat)$value



library(pracma)
integral(posterior_times_sigma2, xmin=0, xmax=Inf, dat=dat)
integral(posterior_times_sigma2, xmin=0, xmax=Inf, dat=dat, method="Kronrod")