Python 接受/拒绝算法中的高效循环
下面是两种不同的基本接受/拒绝采样器的实现方式,该采样器来自高斯密度函数,已知的归一化常数最多为“未知”,现在,基本采样器(方法1)涉及重复循环,并生成循环中每个步骤所需的两个随机变量 另一方面,对于方法2,模拟一批这些随机变量,然后循环进行首次验收,如果没有,则模拟一个新批次,依此类推。现在,当接受概率很小时,方法2看起来确实要快得多,所以我的第一个问题是方法2能更有效地实现吗?如果预先模拟随机变量的批次是最有效的方法,那么有没有原则性的方法来选择这些批次的大小 安装程序 AR方法1Python 接受/拒绝算法中的高效循环,python,performance,random,Python,Performance,Random,下面是两种不同的基本接受/拒绝采样器的实现方式,该采样器来自高斯密度函数,已知的归一化常数最多为“未知”,现在,基本采样器(方法1)涉及重复循环,并生成循环中每个步骤所需的两个随机变量 另一方面,对于方法2,模拟一批这些随机变量,然后循环进行首次验收,如果没有,则模拟一个新批次,依此类推。现在,当接受概率很小时,方法2看起来确实要快得多,所以我的第一个问题是方法2能更有效地实现吗?如果预先模拟随机变量的批次是最有效的方法,那么有没有原则性的方法来选择这些批次的大小 安装程序 AR方法1 def
def AR1():
尽管如此:
z=q.rvs()
u=均匀(低=0,高=k*q.pdf(z))
如果u因为AR中的样本是独立的,您不需要像metropolis-hastings算法那样逐个生成它们。因此,您可以一次生成它们,并通过利用数组操作来加快函数的速度
假设我们要1000个样品。使用您的AR2:
>> %timeit sample2 = [AR2() for _ in range(1000)]
513 ms ± 134 ms per loop (mean ± std. dev. of 7 runs, 1 loop each)
我们可以创建类似数组的函数:
def AR_array(size = 100):
# generate a slightly larger total samples
# based on the acceptance ratio: 1/k
Zs = q.rvs(size= np.int(size*(k+1)))
Us = uniform(low=0., high=k*q.pdf(Zs))
Pvals = p_(Zs) # unnormalized pdf p_(z)
Zs_accepted = Zs[Us <= Pvals] # select accepted samples
return Zs_accepted[0:size] # return the required sample size
健全性检查:
>> norm.fit(AR_array(1000)) # MLE of mean and std
(-0.05960200510480021, 0.9917248073504155)
由于AR中的样本是独立的,所以不需要像metropolis hastings算法那样逐个生成它们。因此,您可以一次生成它们,并通过利用数组操作来加快函数的速度
假设我们要1000个样品。使用您的AR2:
>> %timeit sample2 = [AR2() for _ in range(1000)]
513 ms ± 134 ms per loop (mean ± std. dev. of 7 runs, 1 loop each)
我们可以创建类似数组的函数:
def AR_array(size = 100):
# generate a slightly larger total samples
# based on the acceptance ratio: 1/k
Zs = q.rvs(size= np.int(size*(k+1)))
Us = uniform(low=0., high=k*q.pdf(Zs))
Pvals = p_(Zs) # unnormalized pdf p_(z)
Zs_accepted = Zs[Us <= Pvals] # select accepted samples
return Zs_accepted[0:size] # return the required sample size
健全性检查:
>> norm.fit(AR_array(1000)) # MLE of mean and std
(-0.05960200510480021, 0.9917248073504155)
>> norm.fit(AR_array(1000)) # MLE of mean and std
(-0.05960200510480021, 0.9917248073504155)