python - pymc3 变量如何分配给当前事件模型?

标签 python pymc3

PyMC3你可以这样做

basic_model = pm.Model()

with basic_model:

    # Priors for unknown model parameters
    alpha = pm.Normal('alpha', mu=0, sd=10)
    beta = pm.Normal('beta', mu=0, sd=10, shape=2)
    sigma = pm.HalfNormal('sigma', sd=1)

    # Expected value of outcome
    mu = alpha + beta[0]*X1 + beta[1]*X2

    # Likelihood (sampling distribution) of observations
    Y_obs = pm.Normal('Y_obs', mu=mu, sd=sigma, observed=Y)

并且所有变量 (pm.Normal, ...) 将被“分配”给 basic_model 实例。

From the docs

The first line,

basic_model = Model()

creates a new Model object which is a container for the model random variables.

Following instantiation of the model, the subsequent specification of the model components is performed inside a with statement:

with basic_model:

This creates a context manager, with our basic_model as the context, that includes all statements until the indented block ends. This means all PyMC3 objects introduced in the indented code block below the with statement are added to the model behind the scenes. Absent this context manager idiom, we would be forced to manually associate each of the variables with basic_model right after we create them. If you try to create a new random variable without a with model: statement, it will raise an error since there is no obvious model for the variable to be added to.

我认为对于图书馆来说,它非常优雅。实际上是如何实现的?

我能想到的唯一方法就是本着这样的精神:

class Model:
    active_model = None
    def __enter__(self):
        Model.active_model = self
    def __exit__(self, *args, **kwargs):
        Model.active_model = None

class Normal:
    def __init__(self):
        if Model.active_model is None:
            raise ValueError("cant instantiate variable outside of Model")
        else:
            self.model = Model.active_model

它适用于我的简单 REPL 测试,但我不确定这是否有一些陷阱,实际上就是那么简单。

最佳答案

您非常接近,甚至有一段时间与您的实现非常相似。请注意,threading.local 用于存储对象,并将其维护为列表以允许嵌套多个模型,并允许多重处理。实际实现中有一些额外的内容,允许在输入我删除的模型上下文时设置 theano 配置:

class Context(object):
    contexts = threading.local()

    def __enter__(self):
        type(self).get_contexts().append(self)
        return self

    def __exit__(self, typ, value, traceback):
        type(self).get_contexts().pop()

    @classmethod
    def get_contexts(cls):
        if not hasattr(cls.contexts, 'stack'):
            cls.contexts.stack = []
        return cls.contexts.stack

    @classmethod
    def get_context(cls):
        """Return the deepest context on the stack."""
        try:
            return cls.get_contexts()[-1]
        except IndexError:
            raise TypeError("No context on context stack")

Model 类是 Context 的子类,因此在编写算法时,我们可以从上下文管理器内部调用 Model.get_context() 并有权访问到对象。这相当于您的 Model.active_model

关于python - pymc3 变量如何分配给当前事件模型?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/49573131/

相关文章:

python - 带有表示频率的单独列表的直方图

python - Django 过滤子对象的值

python - 如何在 Python 中生成唯一随机 float 列表

python-3.x - 在 debian sid 上安装 pymc 时出错

pymc3:njobs>1 与 GPU 的并行计算

python-2.7 - 在 pymc3 : how? 之外使用 pymc3 可能性/后验

pymc - pymc3 中转换的便捷方法

python - 在 Twisted 中将 HTTP 代理转换为 HTTPS 代理

python - 连接重置错误: [WinError 10054] An existing connection was forcibly closed by the remote host (while accessing Gmail emails)

python - PyMC3:对分类变量进行采样时出现 PositiveDefiniteError