You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在单个PyMC3模型中基于多似然与固定先验生成多后验分布

在PyMC3单个模型中基于多组二项观测估计后验均值

问题背景

有两组二元观测子集,子集比例相同但长度不同,希望基于固定Beta先验和对应的二项似然,在单个PyMC3模型内生成两个p的后验分布并收集均值,而非构建两个独立模型。

原代码如下:

with pm.Model() as single_model:
    data = [[1, 0, 1, 1, 0, 0, 0, 0], [0, 1, 0, 0, 1, 0, 0, 0, 0, 1, 0, 1, 0, 0, 1, 1]]
    estimations = []
    p = pm.Beta('p', alpha=1, beta=1)
    for i in data:
                y = pm.Binomial('y', n=1, p=p, observed=i)
                trace = pm.sample(500)
                estimations.append(trace['p'].mean())

运行后报错:

ValueError: Variable name y already exists.

问题原因

  1. 变量名冲突:循环中每次都创建同名的y似然变量,PyMC3不允许模型内存在重复名称的变量。
  2. 采样时机错误:在模型定义的with块内循环调用pm.sample,违反PyMC3的工作流程——需先完整定义所有模型组件,再执行一次采样。

解决方案

正确实现代码

# 将数据集移到模型块外(可选,代码结构更清晰)
data = [[1, 0, 1, 1, 0, 0, 0, 0], [0, 1, 0, 0, 1, 0, 0, 0, 0, 1, 0, 1, 0, 0, 1, 1]]

with pm.Model() as single_model:
    # 定义2个共享Beta(1,1)先验的p参数,shape=2表示生成两个独立参数
    p = pm.Beta('p', alpha=1, beta=1, shape=2)
    
    # 循环为每组数据创建唯一名称的似然变量
    for idx, obs in enumerate(data):
        pm.Binomial(f'y_{idx}', n=1, p=p[idx], observed=obs)
    
    # 一次性完成所有参数的采样
    trace = pm.sample(500, return_inferencedata=False)
    
    # 收集每个p的后验均值
    estimations = [trace['p'][:, i].mean() for i in range(2)]

print(estimations)

关键说明

  • 唯一变量名:用f'y_{idx}'为每组数据的似然生成唯一名称,彻底避免重复冲突。
  • 多参数定义:通过shape=2让Beta先验生成两个独立的p参数,分别对应两组观测的后验估计。
  • 单次采样:模型定义完成后仅执行一次采样,效率更高且完全符合PyMC3的设计逻辑。

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.21 16:43:31