PyMC3中使用黑盒似然函数出现MissingInputError如何解决?
问题原因
错误发生在采样结束后ArviZ转换结果格式的阶段,和采样逻辑本身无关。你给DensityDist传入的observed参数是包含随机变量k的tensortheta,ArviZ存储观测值时会尝试执行eval()计算这个tensor的实际值,但此时采样流程已经结束,没有对应k的输入上下文,所以抛出输入缺失错误。
解决方案
方案1:直接禁用自动转换InferenceData
调用pm.sample时添加return_inferencedata=False参数,直接返回PyMC3原生的MultiTrace对象,跳过ArviZ的观测值读取步骤:
trace = pm.sample(ndraws, tune = nburn, discard_tuned_samples=True, return_inferencedata=False)
如果后续需要用ArviZ做分析,可以手动从MultiTrace中提取参数值构造InferenceData,不需要读取观测项即可完成大部分后处理操作。
方案2:修正黑盒似然的注册写法(更推荐)
你不需要把参数作为观测值传入DensityDist,黑盒似然所有数据已经内置,直接用pm.Potential注册对数似然项即可,完全不会触发观测值读取逻辑。
把模型块里的这两行:
# Convert the prior to a theano tensor variable theta = tt.as_tensor_variable([k]) # Create density distribution for our numerical likelihood pm.DensityDist("likelihood", lambda y: logl(y), observed={'y':theta})
替换为:
theta = tt.as_tensor_variable([k]) pm.Potential("likelihood", logl(theta))
这种写法更符合黑盒似然的使用逻辑,既不会触发报错,也不影响采样结果。
额外优化建议
你遇到的Could not pickle model, sampling singlethreaded警告是因为自定义Theano Op写在主脚本作用域无法序列化,如果需要开启多进程加速采样,把LogLike类和自定义对数似然函数放到独立的.py文件中导入使用即可。
内容的提问来源于stack exchange,提问作者GreenLlama
相关产品推荐
相关产品推荐

