如何在已知参数时从自定义分布中抽样?

2024-05-08 02:25:08 发布

您现在位置:Python中文网/ 问答频道 /正文

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

例如,自定义分布是p(X |θ),其中θ是K维的参数向量,X是N维的随机向量。你知道吗

现在我们知道(1)θ已知;(2)p(X |θ)未知,但我知道p(X |θ)∞f(X,θ),f是已知函数。你知道吗

pymc3能从p(X |θ)进行这样的采样吗?怎么做?你知道吗

其目的不是从参数的后验分布中抽样,而是要从一个自定义的分布中抽样。你知道吗

从伯努利分布抽样的一个简单例子开始。我做了以下工作:

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。然而,我得到了奇怪的结果,在输出中出现了非常大的数字。你知道吗

我知道有点不对劲。请帮助如何正确编写pymc3代码这样的非后验MCMC采样问题。你知道吗


Tags: importlog参数asstatsstepwithdensity
1条回答
网友
1楼 · 发布于 2024-05-08 02:25:08

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

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

这里是一个类似工厂的实现,它创建了一个与pm.DensityDistrandom参数兼容的Bernoulli RNG(即,接受pointsizekwargs)。你知道吗

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和参数。你知道吗

相关问题 更多 >