蒙特卡罗马尔可夫链的简单贝叶斯网络移植到PyMC3

时间:2017-02-26 15:45:45

标签: python pymc3

我正在将PyMC2的示例从PyMC3移植到pymc3_rain_sprinkler_grass_simple_bayesian_network.py.并且它可以正常工作。
结果可以在文件PyMC3

中的 GitHub 上的Simple Bayesian Network via Monte Carlo Markov Chain中找到

我想通过提供证据来扩展原始示例,例如:草是湿的,然后让pymc3_rain_sprinkler_grass_simple_bayesian_network_with_evidence.py给我一个问题的答案,例如“草已经湿了,下雨的几率是多少?”。

似乎所得到的迹线是“恒定的”,例如它中不再有任何随机因素。查看要点中的df.drop_duplicates()并执行function isLogged(req) { var x = false; if(req.session.logged === 'Yes'){ x = true; } else{ return false; } } 以了解我的意思。

我做错了什么?

1 个答案:

答案 0 :(得分:2)

我设法解决了我的问题。重点是将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)