Как составить таблицы условных вероятностей (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 значений.
Другие вопросы по тегам