pymc.model.core.Potential#

pymc.model.core.Potential(name, var, model=None, dims=None)[源代码]#

向模型对数概率中添加一个任意项。

参数:
名称 : strstr

要在模型中注册的潜在变量的名称。

var : 类似张量tensor_like

要添加到模型关节对数概率的表达式。

模型 : Model, 可选模型,可选

要添加势函数的模型对象。如果提供 None ,则使用上下文堆栈中的当前模型。

dims : strtuplestr,可选python:str 或 python:tuple of python:str, 可选

变量的维度名称。

返回:
var : 类似张量tensor_like

已注册的命名模型变量。

警告

潜在项仅影响基于概率的采样,例如 pm.sample,但不会影响像 pm.sample_prior_predictivepm.sample_posterior_predictive 这样的前向采样。当使用包含潜在项的模型进行前向采样时,会引发警告。

示例

在这个例子中,我们定义了 x 必须大于或等于 0 的约束。语句 pm.math.log(pm.math.switch(constraint, 0, 1)) 根据约束是否满足,向模型 logp 添加 0 或 -inf。在采样过程中,任何 x 为负的提案都将被拒绝。

import pymc as pm

with pm.Model() as model:
    x = pm.Normal("x", mu=0, sigma=1)

    constraint = x >= 0
    potential = pm.Potential("x_constraint", pm.math.log(pm.math.switch(constraint, 1, 0)))

相反,使用一个软约束,如 pm.math.log(pm.math.switch(constraint, 1, 0.5)),采样器不太可能,但并非禁止,接受 x 的负值。

import pymc as pm

with pm.Model() as model:
    x = pm.Normal("x", mu=0, sigma=1)

    constraint = x >= 0
    potential = pm.Potential("x_constraint", pm.math.log(pm.math.switch(constraint, 1.0, 0.5)))

一个潜在项可以依赖于多个变量。在下面的例子中,soft_sum_constraint 潜在项鼓励 xy 的和小。和偏离零越多,(-((x + y)**2)) 的惩罚值就越负。

import pymc as pm

with pm.Model() as model:
    x = pm.Normal("x", mu=0, sigma=10)
    y = pm.Normal("y", mu=0, sigma=10)
    soft_sum_constraint = pm.Potential("soft_sum_constraint", -((x + y)**2))

一个 Potential 可以用来定义一个特定的先验项。以下示例在 max_items 上施加了一个幂律先验,形式为 log(1/max_items),这会惩罚 max_items 的极大值。

import pymc as pm

with pm.Model() as model:
    # p(max_items) = 1 / max_items
    max_items = pm.Uniform("max_items", lower=1, upper=100)
    pm.Potential("power_prior", pm.math.log(1/max_items))

    n_items = pm.Uniform("n_items", lower=1, upper=max_items, observed=60)

势能可以用来定义特定的似然项。在下面的例子中,一个正态似然项被添加到固定数据中。通过使用观察到的 Normal 变量,可以得到相同的结果。

import pymc as pm

def normal_logp(value, mu, sigma):
    return -0.5 * ((value - mu) / sigma) ** 2 - pm.math.log(sigma)

with pm.Model() as model:
    mu = pm.Normal("x")
    sigma = pm.HalfNormal("sigma")

    data = [0.1, 0.5, 0.9]
    llike = pm.Potential("llike", normal_logp(data, mu, sigma))