PyMC耦合线性贝叶斯模型新输入预测维度异常问题排查
问题根源
你得到的维度不符合预期,核心原因是生成后验预测时没指定用新的O₁数据,PyMC默认复用了训练阶段的95行原始O₁数据,所以输出维度对应训练数据的行数。
解决步骤
要拿到对应新数据的后验预测,按以下方式修改代码:
1. 建模时明确区分训练与预测变量
构建模型时,单独定义新数据的预测路径,不要只依赖训练数据的变量:
import pymc as pm import arviz as az # 假设你的训练数据:O1_train (95个样本), O2_train, O3_train # 新数据:O1_new (1个样本,形状要和训练数据一致,比如是[new_value]这样的一维数组) with pm.Model() as coupled_model: # 定义先验 m2 = pm.Normal("m2", mu=0, sigma=10) q2 = pm.Normal("q2", mu=0, sigma=10) m3 = pm.Normal("m3", mu=0, sigma=10) q3 = pm.Normal("q3", mu=0, sigma=10) sigma2 = pm.HalfNormal("sigma2", sigma=5) sigma3 = pm.HalfNormal("sigma3", sigma=5) # 训练数据的O2预测与似然 O2_train_pred = pm.Deterministic("O2_train_pred", m2 * O1_train + q2) pm.Normal("O2_obs", mu=O2_train_pred, sigma=sigma2, observed=O2_train) # 训练数据的O3预测与似然 O3_train_pred = pm.Deterministic("O3_train_pred", m3 * O2_train_pred + q3) pm.Normal("O3_obs", mu=O3_train_pred, sigma=sigma3, observed=O3_train) # 关键:新增新数据的预测链 O2_new_pred = pm.Deterministic("O2_new_pred", m2 * O1_new + q2) O3_new_pred = pm.Deterministic("O3_new_pred", m3 * O2_new_pred + q3) # 执行采样 trace = pm.sample(2000, chains=4, return_inferencedata=True)
2. 生成后验预测时指定目标变量
采样完成后,调用sample_posterior_predictive时,明确指定要采样O3_new_pred,而不是默认的观测变量:
with coupled_model: ppc = pm.sample_posterior_predictive(trace, var_names=["O3_new_pred"])
3. 验证输出维度
此时ppc.posterior_predictive["O3_new_pred"]的维度就是(4, 2000, 1),完全符合你的预期。
避坑提示
- 别直接对
O2_obs或O3_obs做后验预测:这些观测变量的后验预测默认绑定训练数据的输入,输出维度必然和训练数据一致。 - 确保新数据形状正确:
O1_new要和训练时的O1_train维度匹配,比如训练时是一维数组,新数据也要是一维(哪怕只有一个元素,别用标量)。
内容的提问来源于stack exchange,提问作者Marco
相关产品推荐
相关产品推荐

