如何从具有不可计算 CDF 的分布中采样?

机器算法验证 采样 模拟 蒙特卡洛
2022-03-18 11:12:44

半计算机科学模拟相关问题在这里。

我有一个发行版

P(x) =(eb1)eb(nx)ebn+b1

对于一些常量 b 和 n,x 是一个整数,使得0xn

现在,我需要从这个分布中取样。它有一个可逆的 CDF,所以理论上可以直接做到这一点。问题是涉及的数字很大。实际上如此之大,以至于它们都溢出了传统格式的变量,并且至少需要几分钟(在某些时候我放弃了......)才能使用任意精度格式进行计算。基本上,逆 CDF 仍然涉及项,对于尽管如此,输出数字仍将在范围内,因此似乎应该有一种方法可以做到这一点。eb(n+1)350<n<35000n

我正在寻找的是一种从可计算的分布中近似采样的方法是否有其他抽样方法?这些是什么?

4个回答

CDF 很容易反转。 反演公式导致必须是最简单和最方便的可能解决方案之一。

首先观察结果成正比因此,如果我们 _{\ max }=\ sum_ =,我们只需要找到最大k0knebkq0qmax=k=0nebk(1eb(n+1))/(1eb)k

qi=0kebi=1e(k+1)b1eb.

简单代数给出了解决方案

k=ceiling(log(1q(1eb))b).

这是一个与所有其他随机数生成器一样构造的R实现:它的第一个参数指定要生成多少个iid值,其余参数命名参数( as as ):bbnn.max

rgeom.truncated <- function(n=1, b, n.max) {
  a <- 1 - exp(-b)
  q.max <- (1 - exp(-b*(n.max+1))) / a
  q <- runif(n, 0, q.max)
  return(-ceiling(log(1 - q*a) / b))
}

作为其使用示例,让我们根据此分布生成一百万个随机变量:

b <- 0.001
n.max <- 3500
n.sim <- 10^6
set.seed(17)
system.time(sim <- rgeom.truncated(n.sim, b,n.max))

秒。)0.10

h <- hist(sim+1, probability=TRUE, breaks=50, xlab="Outcome+1")
pmf <- exp(-b * (0: n.max)); pmf <- pmf / sum(pmf)
lines(0:n.max, pmf, col="Red", lwd=2)

直方图

添加到每个值以创建更好的直方图:过程有一个特质(=错误),其中当左端点设置为零时,第一个条形太高。)红色曲线是参考分布这个模拟试图重现。让我们用卡方检验评估拟合优度:1Rhist

observed <- table(sim)
expected <- n.sim * pmf
chi.square <- (observed-expected)^2 / expected
pchisq(sum(chi.square), n.max, lower.tail=FALSE)

p 值为:非常合适。0.84

您正在处理的截断几何分布。有多种方法可以解决这个问题。p=1eb

我会在不同的情况下建议不同的选择;一些选项将涉及从几何模拟并在其超出范围时重新生成,采用适当的截断指数的整数部分(如此处),或使用针对有限范围内的离散分布量身定制的几种快速技术中的任何一种。鉴于很大,取截断指数的下限可能相对较快,但它是否是最佳选择还取决于nb

这是关于 math.SE的相关问题

在我尝试具体建议之前,的典型值范围是多少?b

首先,请注意如果是连续的,它将与指数分布有关。然后,您可以做的是从截断的指数分布进行模拟并获取(整数部分)观测值。P(x)ebxxfloor()

截断指数的 cdf 是

F(x;n,b)=1ebx1ebn.

然后,如果我们使,我们得到如果很大,则建议近似F(x;n,b)=ux=1blog[1u(1ebn)]bnebn0x1blog[1u]

rweirdp <- function(ns,n,b){
u <- runif(ns)
samp <- - log(1-u*(1-exp(-n*b)))/b
return(floor(samp))
}

rweirdp(1000,10,1)

从目标分布中采样的一种方法是p(k)exp{bk}

  1. 运行 Metropolis-Hastings 实验以确定分布的(有趣的)支持,即它集中在的哪个子集中;{0,1,,n}

    metro=function(N,b,n){
    x=sample(0:n,N,rep=TRUE)
    for (t in 2:N){
      x[t]=prop=x[t-1]+sample(c(-1,1),1)
    
      if ((prop<0)||(prop>n)||(log(runif(1))>b*(x[t]-prop)))
          x[t]=x[t-1]
      }
    return(x)
    }
    
  2. 使用如此确定的支持,来计算精确概率为以避免溢出。{k0,,k1}p(k)exp{bk+bk0}

更新:考虑更多时,由于在 k 中减小,分布的有效支持将始终从开始。如果很大,这种支持将很快结束,在这种情况下,无关紧要,因为永远不会访问如果非常小,则 pdf 几乎是平坦的,这意味着可以使用上的均匀分布作为接受-拒绝提议。并在接受步骤中使用日志以避免溢出。p()k0=0bnkb{0,1,,n}