You need to enable JavaScript to run this app.
最新活动
大模型
产品
解决方案
定价
生态与合作
支持与服务
开发者
了解我们

如何在PyMC3中用Python函数创建Deterministic变量(替代@pm.deterministic)

Hey there! Great question—this is a super common gotcha when moving from older PyMC versions to PyMC3, since the @pm.deterministic decorator was completely removed in the switch. Let me break down the two main ways to replicate that functionality in PyMC3, with examples that align with what you'd see in Bayesian Methods for Hackers:

1. Simple Deterministic Calculations (No Explicit Registration Needed)

If your deterministic transformation is straightforward and you don't need to explicitly track it in your sampling trace, you can just compute it directly within your model context. PyMC3 automatically recognizes these as deterministic nodes tied to your random variables.

For example, if your old PyMC2 code looked like this:

@pm.deterministic
def scaled_data(x=observed_data):
    return x * 0.5 + 2

In PyMC3, you'd rewrite it as:

with pm.Model() as model:
    # First define your random variables
    x = pm.Normal('x', mu=0, sigma=1, observed=observed_data)
    # Just compute the deterministic value directly
    scaled_data = x * 0.5 + 2

PyMC3 will handle tracking this node under the hood, so you can use it in other parts of your model (like likelihoods) without extra work.

2. Explicitly Registered Deterministic Variables (For Trace Tracking)

If you need to save the deterministic variable's values in your sampling trace (to visualize or analyze later), use the pm.Deterministic class. This replaces the decorator by explicitly registering the variable with your model and giving it a name.

Let's use a classic example from the book—say you're computing a ratio of two gamma-distributed variables:
Old PyMC2 code:

@pm.deterministic
def theta(alpha=alpha_prior, beta=beta_prior):
    return alpha / (alpha + beta)

In PyMC3, this becomes:

with pm.Model() as model:
    # Define your priors first
    alpha_prior = pm.Gamma('alpha_prior', alpha=1, beta=1)
    beta_prior = pm.Gamma('beta_prior', alpha=1, beta=1)
    # Explicitly register the deterministic variable
    theta = pm.Deterministic('theta', alpha_prior / (alpha_prior + beta_prior))

Now, after sampling, you can access the trace of theta just like any other variable:

with model:
    trace = pm.sample(2000)

# View the posterior of theta
pm.plot_posterior(trace['theta'])

Bonus: Complex Deterministic Functions

If your deterministic logic is more involved (multiple steps, conditional logic, etc.), you can define a helper function and call it inside pm.Deterministic—just make sure to use PyMC's math functions (pm.math) instead of standard Python math to keep things compatible with PyMC3's tensor operations:

def calculate_log_odds(a, b):
    ratio = a / (a + b)
    # Use pm.math for tensor-compatible operations
    return pm.math.log(ratio / (1 - ratio))

with pm.Model() as model:
    alpha = pm.Gamma('alpha', alpha=2, beta=1)
    beta = pm.Gamma('beta', alpha=2, beta=1)
    log_odds = pm.Deterministic('log_odds', calculate_log_odds(alpha, beta))

The key takeaway is that PyMC3 simplifies deterministic variables by either letting you compute them on the fly or explicitly registering them when you need to track their posterior samples.

内容的提问来源于stack exchange,提问作者RSHAP

火山引擎 最新活动