【问题标题】:Simple Bayesian Network via Monte Carlo Markov Chain ported to PyMC3通过 Monte Carlo Markov Chain 移植到 PyMC3 的简单贝叶斯网络
【发布时间】:2017-02-26 15:45:45
【问题描述】:

我正在将Simple Bayesian Network via Monte Carlo Markov Chain 的示例从PyMC2 移植到PyMC3,它可以工作。
结果可以在GitHub上的pymc3_rain_sprinkler_grass_simple_bayesian_network.py.文件pymc3_rain_sprinkler_grass_simple_bayesian_network.py.

中找到

我想通过提供证据来扩展原始示例,例如草是湿的,然后让PyMC3 给我回答“如果草是湿的,下雨的概率是多少?”。

似乎生成的跟踪是“恒定的”,例如它不再有随机性的元素。查看要点中的pymc3_rain_sprinkler_grass_simple_bayesian_network_with_evidence.py 并执行df.drop_duplicates() 以了解我的意思。

我做错了什么?

【问题讨论】:

  • 我已经用PyMC2 中的相同代码更新了要点。 PyMC2 版本不会遇到与 PyMC3 版本相同的问题。有什么想法吗?
  • 在pymc3-multiple-observed-values 中,我发现了以下声明:“除了任何贝叶斯 MCMC 分析的缺陷外,您的方法没有任何根本性错误:(1) 不收敛,(2)先验,(3)模型。”我认为我这里的情况是类似的情况,我将继续调整解决方案。如果我提供草不湿而不是草湿的证据,PyMC3 版本也可以。我将继续在这里和要点中更新我的发现。

标签: python pymc3


【解决方案1】:

我设法解决了我的问题。要点是将 testval 设置为“true”而不是“false”。它改善了将步进方法从 Metropolis 更改为 BinaryGibbsMetropolis 的情况。

参考这里是完整的解决方案。我也更新了要点。

import numpy as np
import pandas as pd
import pymc3 as pm

niter = 10000  # 10000
tune = 5000  # 5000

model = pm.Model()

with model:
    tv = [1]
    rain = pm.Bernoulli('rain', 0.2, shape=1, testval=tv)
    sprinkler_p = pm.Deterministic('sprinkler_p', pm.math.switch(rain, 0.01, 0.40))
    sprinkler = pm.Bernoulli('sprinkler', sprinkler_p, shape=1, testval=tv)
    grass_wet_p = pm.Deterministic('grass_wet_p', pm.math.switch(rain, pm.math.switch(sprinkler, 0.99, 0.80), pm.math.switch(sprinkler, 0.90, 0.0)))
    grass_wet = pm.Bernoulli('grass_wet', grass_wet_p, observed=np.array([1]), shape=1)

    trace = pm.sample(20000, step=[pm.BinaryGibbsMetropolis([rain, sprinkler])], tune=tune, random_seed=124)

# pm.traceplot(trace)

dictionary = {
              'Rain': [1 if ii[0] else 0 for ii in trace['rain'].tolist() ],
              'Sprinkler': [1 if ii[0] else 0 for ii in trace['sprinkler'].tolist() ],
              'Sprinkler Probability': [ii[0] for ii in trace['sprinkler_p'].tolist()],
              'Grass Wet Probability': [ii[0] for ii in trace['grass_wet_p'].tolist()],
              }
df = pd.DataFrame(dictionary)

p_rain = df[(df['Rain'] == 1)].shape[0] / df.shape[0]
print(p_rain)

p_sprinkler = df[(df['Sprinkler'] == 1)].shape[0] / df.shape[0]
print(p_sprinkler)

【讨论】:

  • 我已经用 pyjags 版本更新了要点。如果我没有为 JAGS 指定正确的起始条件,它会给我一条错误消息:console.JagsError: Error in node grass_wet; Observed node inconsistent with unobserved parents at initialization. Try setting appropriate initial values. 如果 PyMC3 会给出类似的警告,那就太好了。
猜你喜欢
  • 2013-04-08
  • 1970-01-01
  • 1970-01-01
  • 2011-01-09
  • 2012-07-14
  • 2013-05-11
  • 2013-07-19
  • 2019-11-05
相关资源
最近更新 更多