Как составить таблицы условных вероятностей (CPT) для байесовских сетей с pymc
Я хотел бы построить байесовскую сеть дискретных (pymc.Categorical) переменных, которые зависят от других категориальных переменных. В качестве простейшего примера предположим, что переменные a и b являются категориальными, а b зависит от
Вот попытка закодировать его с помощью pymc (при условии, что a принимает одно из трех значений, а b принимает одно из четырех значений). Идея состоит в том, что распределения CPT будут изучены из данных с использованием pymc.
import numpy as np
import pymc as pm
aRange = 3
bRange = 4
#make variable a
a = pm.Categorical('a',pm.Dirichlet('aCPT',np.ones(aRange)/aRange))
#make a CPT table as an array of
CPTLines = np.empty(aRange, dtype=object)
for i in range(aRange):
CPTLines[i] = pm.Dirichlet('CPTLine%i' %i,np.ones(bRange)/bRange)
#make a deterministic node that holds the relevant CPT line (dependent on state1)
@pm.deterministic
def selectedCPTLine(CPTLines=CPTLines,a=a):
return CPTLines[a]
#make a node for variable b
b=pm.Categorical('b', selectedCPTLine)
model = pm.MCMC([a, b, selectedCPTLine])
Если мы нарисуем эту модель, она выглядит так
Однако, запустив этот код, мы получаем ошибку:
Probabilities in categorical_like sum to [ 0.8603345]
По-видимому, pymc может принимать переменную Дирихле в качестве параметра категориальной переменной. Когда переменная Категорийная получает переменную Дирихле в качестве своего параметра, она знает, что ожидается вектор вероятностей k-1 с предположением, что k-я вероятность суммирует вектор в 1. Однако это происходит, когда переменная Дирихле является выходом детерминированная переменная, это то, что мне нужно сделать CPT.
Я иду об этом правильным путем? Как можно решить проблему несовпадения представлений? Я должен отметить, что я относительно новичок в Pymc и Python.
Этот вопрос связан с предыдущим вопросом о создании марковской модели с дискретным состоянием с помощью pymc
2 ответа
Хорошо спасибо. Проблема заключается в том, что, хотя обычно PyMC распознает Dirichlet как родительский элемент для категории и завершает симплекс вероятности, здесь ваши категории встроены в контейнер, а категория не выполняет автоматическую настройку. Следующий код делает это за вас:
import numpy as np
import pymc as pm
aRange = 3
bRange = 4
aCPT = pm.Dirichlet('aCPT', np.ones(aRange))
#make variable a
a = pm.Categorical('a', aCPT)
#make a CPT table as an array of
CPTLines = [pm.Dirichlet('CPTLine%i' %i, np.ones(bRange)) for i in range(aRange)]
#make a node for variable b
@pm.stochastic(dtype=int)
def b(value=0, CPT=CPTLines, a=a):
return pm.categorical_like(value, p=pm.extend_dirichlet(CPT[a]))
model = pm.MCMC([a, b, CPTLines])
Надеюсь, это поможет.
Пара моментов путаницы:
- Ваша модель, похоже, не содержит данных (наблюдаемая стохастика), поэтому нет информации, подходящей для модели
- не уверен, что вы подразумеваете под переменной Дирихле, являющейся выходом детерминированного. Пока вероятности имеют длину k-1 и они составляют в сумме меньше единицы, вы должны быть хорошими. Если у вас есть значение, которое суммируется с единицей, вы можете просто передать первый k-1 значений.