Simple Bayesian Network via Monte Carlo Markov Chain ported to PyMC3

試著忘記壹切 提交于 2019-12-10 20:26:59

问题


I was porting the example of a Simple Bayesian Network via Monte Carlo Markov Chain from PyMC2 to PyMC3 and it works.
The result can be found in the following gist on GitHub in the file pymc3_rain_sprinkler_grass_simple_bayesian_network.py.

I wanted to extend the original example by providing evidence, e.g. 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?".

It seems that the resulting trace is "constant", e.g. 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.

What am I doing wrong?


回答1:


I managed to solve my problem. The main point was to set testval to "true" rather than "false". It improved the situation to change the step method from Metropolis to 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)


来源:https://stackoverflow.com/questions/42470592/simple-bayesian-network-via-monte-carlo-markov-chain-ported-to-pymc3

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!