Попытка сделать чрезвычайно простой (3 категориальные переменные) байесовский вывод с PYMC3 и NetworkX - PullRequest
0 голосов
/ 26 апреля 2018

Я пытаюсь понять этот пример байесовской сети.Думаю, я бы еще больше заглушил это так, что он рассматривает только три переменные: D1, D2 и D3.Каждая из них является категориальной, а таблицы вероятностей указаны в верхней части кода ниже.Я хотел бы установить D3 = 0, а затем вычислить апостериорные вероятности D1 и D2, как более простую версию того, что сделано внизу на этой странице .Я пытался сделать это, играя с кодом из первого источника, но безуспешно, и я не понимаю сообщений об ошибках.

Любая помощь в этом будет принята с благодарностью - я действительно былизо всех сил пытается осуществить байесовский вывод.Я попытался просмотреть документацию PYMC3 Категориальная , но это довольно скудно.И пример логического вывода, который я мог найти , использует непрерывные переменные и, кажется, делает нечто иное, чем то, что я пытаюсь сделать.Или, если это не так, я не достаточно умен, чтобы установить соединение и использовать то, что они демонстрируют, для удовлетворения моих потребностей.

Я не уверен, что публикация больших разделов кода одобрена здесь?Но я не уверен, как еще это сделать.Вот мой код (гораздо более короткая и простая версия кода из первого источника):

import networkx as nx
import numpy as np
import seaborn as sns
import matplotlib.pyplot as plt
import pymc3 as pm
import theano
import theano.tensor as T
from theano.compile.ops import as_op

d1_prob = np.array([0.3,0.7])  # 2 choices
d2_prob = np.array([0.6,0.3,0.1])  # 3 choices
d3_prob = np.array([[[0.1, 0.9],  # (2x3)x2 choices
                 [0.3, 0.7], 
                 [0.4, 0.6]], 
                [[0.6, 0.4], 
                 [0.8, 0.2],
                 [0.9, 0.1]]])

BN = nx.DiGraph()
BN.add_node('D1', dtype='Discrete', prob=d1_prob)
BN.add_node('D2', dtype='Discrete', prob=d2_prob)
BN.add_node('D3', dtype='Discrete', prob = d3_prob, observe=np.array([0.]))
BN.add_edges_from([('D1', 'D3'), ('D2', 'D3')])

#print(BN.nodes(data=True))
#print(BN.pred['D3'])

def gpm(BN, node, num=0):
    return BN.node[BN.predecessors(node)[num]]['dist_obj']

with pm.Model() as mod2:

BN.node['D1']['dist_obj'] = pm.Categorical('D1', p=BN.node['D1']['prob'])
BN.node['D2']['dist_obj'] = pm.Categorical('D2', p=BN.node['D2']['prob'])
BN.node['D3']['dist_obj'] = pm.Categorical('D3', p=BN.node['D3']['prob'][
    gpm(BN,'D3', num=1),
    gpm(BN,'D3', num=0)
], observed=BN.node['D3']['observe'])

with mod2:
trace = pm.sample(10000)

pm.summary(trace, varnames=['D3'], start=1000)
pm.traceplot(trace[1000:], varnames=['D3'])

1 Ответ

0 голосов
/ 01 мая 2018

Я не могу помочь вам с PyMC3, извините.Но, возможно, вам просто нужны числа.

На самом деле я не понимаю, зачем вам вообще нужен алгоритм вывода.

Таблицы вероятностей полностью определены, пропущенных данных нет, ипоэтому вы можете просто применить правило Байеса здесь.По общему признанию я не хочу делать это с карандашом и бумагой даже для такого простого примера.Поэтому я использовал графический инструмент на основе Java samiam здесь, чтобы использовать для меня правило Байеса.

Когда ничего не наблюдается: enter image description here

Интерпретируя ваш код gpm() и observe(), вы наблюдаете d3 = 1. Тогда значения CPT изменятся на следующее:

enter image description here

(Значения state0 являются произвольными, samiam просто назначает метки по умолчанию stateX).Положение строки в CPT - вот что имеет значение.

...