简体   繁体   English

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

[英]Simple Bayesian Network via Monte Carlo Markov Chain ported to PyMC3

I was porting the example of a Simple Bayesian Network via Monte Carlo Markov Chain from PyMC2 to PyMC3 and it works. 通过蒙特卡罗马尔可夫链PyMC2移植到简单贝叶斯网络的例子到PyMC3并且它可以工作。
The result can be found in the following gist on GitHub in the file pymc3_rain_sprinkler_grass_simple_bayesian_network.py. 结果可以在文件pymc3_rain_sprinkler_grass_simple_bayesian_network.py. GitHub上的以下要点找到 pymc3_rain_sprinkler_grass_simple_bayesian_network.py.

I wanted to extend the original example by providing evidence, eg that the grass is wet and then let PyMC3 give me the answer for questions like "given grass is wet, what is the probability that it has rained?". 我想通过提供证据来扩展原始示例,例如,草是湿的,然后让PyMC3给出答案,例如“给定草湿,下雨的概率是多少?”。

It seems that the resulting trace is "constant", eg there is no element of randomness in it any more. 似乎得到的迹线是“常数”,例如,它中不再存在随机元素。 Have a look at pymc3_rain_sprinkler_grass_simple_bayesian_network_with_evidence.py in the gist and execute the df.drop_duplicates() to see what I mean. pymc3_rain_sprinkler_grass_simple_bayesian_network_with_evidence.py中查看pymc3_rain_sprinkler_grass_simple_bayesian_network_with_evidence.py并执行df.drop_duplicates()以查看我的意思。

What am I doing wrong? 我究竟做错了什么?

I managed to solve my problem. 我设法解决了我的问题。 The main point was to set testval to "true" rather than "false". 重点是将testval设置为“true”而不是“false”。 It improved the situation to change the step method from Metropolis to BinaryGibbsMetropolis. 它改善了从Metropolis到BinaryGibbsMetropolis改变步法的情况。

For reference here is the complete solution. 这里参考是完整的解决方案。 I also updated the gist. 我还更新了要点。

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)

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM