gpt4 book ai didi

python - 当参数已知时如何从自定义分布中采样?

转载 作者:行者123 更新时间:2023-12-01 07:38:34 25 4
gpt4 key购买 nike

目标是从参数已知的分布中获取样本。

例如,自定义分布为p(X|theta),其中theta为K维参数向量,X为N维随机向量。

现在我们知道 (1) theta 是已知的; (2) p(X|theta) 未知,但我知道 p(X|theta) ∝ f(X,theta),并且 f 是已知函数。

pymc3 可以从 p(X|theta) 进行这样的采样吗?如何采样?

目的不是从参数的后验分布中采样,而是想从自定义的分布中采样。

从伯努利分布采样的简单示例开始。我做了以下事情:

import pymc3 as pm
import numpy as np
import scipy.stats as stats
import pandas as pd
import theano.tensor as tt

with pm.Model() as model1:
p=0.3
density = pm.DensityDist('density',
lambda x1: tt.switch( x1, tt.log(p), tt.log(1 - p) ),
) #tt.switch( x1, tt.log(p), tt.log(1 - p) ) is the log likelihood from pymc3 source code

with model1:
step = pm.Metropolis()
samples = pm.sample(1000, step=step)

我期望结果是1000个二进制数字,其中1的比例约为0.3。但是,我得到了奇怪的结果,输出中出现了非常大的数字。

我知道出了什么问题。请帮助了解如何正确编写此类非后验 MCMC 采样问题的 pymc3 代码。

最佳答案

事先预测采样(您应该使用 pm.sample_prior_predictive())仅涉及使用计算图中的 RandomVariable 对象提供的 RNG。默认情况下,DensityDist 不实现 RNG,但为此提供了 random 参数,因此您需要使用它。对数似然仅针对可观测值进行评估,因此它在这里不起作用。

为任意分布生成有效 RNG 的简单方法是使用 inverse transform sampling 。在这种情况下,我们对单位间隔上的均匀分布进行采样,然后通过所需函数的逆 CDF 对其进行变换。对于伯努利情况,逆 CDF 根据成功概率对单位线进行划分,将 0 分配给一个部分,将 1 分配给另一部分。

这是一个类似工厂的实现,它创建与 pm.DensityDistrandom 参数兼容的伯努利 RNG(即接受 point大小 kwargs)。

def get_bernoulli_rng(p=0.5):

def _rng(point=None, size=1):
# Bernoulli inverse CDF, given p (prob of success)
_icdf = lambda q: np.uint8(q < p)

return _icdf(pm.Uniform.dist().random(point=point, size=size))

return _rng

因此,要填写示例,它会类似于

with pm.Model() as m:
p = 0.3
y = pm.DensityDist('y', lambda x: tt.switch(x, tt.log(p), tt.log(1-p)),
random=get_bernoulli_rng(p))
prior = pm.sample_prior_predictive(random_seed=2019)

prior['y'].mean() # 0.306

显然,这同样可以用random=pm.Bernoulli.dist(p).random来完成,但上面一般说明了如何在给定逆 CDF 的情况下对任意分布执行此操作,即您只需要修改_icdf和参数即可。

关于python - 当参数已知时如何从自定义分布中采样?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/56838680/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com