通过 Monte Carlo 马尔可夫链移植到 PyMC3 的简单贝叶斯网络
Simple Bayesian Network via Monte Carlo Markov Chain ported to PyMC3
我在文件 pymc3_rain_sprinkler_grass_simple_bayesian_network.py.
中的 GitHub 上移植了 Simple Bayesian Network via Monte Carlo Markov Chain from PyMC2
to PyMC3
and it works.
The result can be found in the following gist 的示例
我想通过提供证据来扩展原始示例,例如草是湿的然后让 PyMC3
给我回答 "given grass is wet, what is the probability that it has rained?".
这样的问题
生成的轨迹似乎是 "constant",例如它不再有随机性的元素。看看要点中的 pymc3_rain_sprinkler_grass_simple_bayesian_network_with_evidence.py
并执行 df.drop_duplicates()
看看我的意思。
我做错了什么?
我设法解决了我的问题。要点是将 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)
我在文件 pymc3_rain_sprinkler_grass_simple_bayesian_network.py.
PyMC2
to PyMC3
and it works. The result can be found in the following gist 的示例
我想通过提供证据来扩展原始示例,例如草是湿的然后让 PyMC3
给我回答 "given grass is wet, what is the probability that it has rained?".
生成的轨迹似乎是 "constant",例如它不再有随机性的元素。看看要点中的 pymc3_rain_sprinkler_grass_simple_bayesian_network_with_evidence.py
并执行 df.drop_duplicates()
看看我的意思。
我做错了什么?
我设法解决了我的问题。要点是将 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)