2014-04-02 38 views
3

我想構建一個依賴於其他分類變量的離散(pymc.Categorical)變量的貝葉斯網絡。 作爲simplest例如,假設變量一個b是分類和b取決於一個如何使用pymc爲貝葉斯網絡製作條件概率表(CPT)

下面是一個試圖將其與pymc代碼(假設一個需要三個值中的一個和b取四個值中的一個)。這個想法是,使用pymc從數據中學習CPT分佈。

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]) 

如果我們得出這樣的模型,它看起來像this

但是,運行這段代碼,我們得到一個錯誤:

Probabilities in categorical_like sum to [ 0.8603345] 

顯然,pymc可以採取狄氏變量的參數分類變量。 當Categorical變量得到一個Dirichlet變量作爲它的參數時,它知道期望一個k-1向量的概率,並假設第k個概率將向量加到1上。然而,當Dirichlet變量是輸出的確定性變量,這是我需要做一個CPT。

我對此有何看法?如何解決表達不匹配問題?我應該提到,我對pymc和Python比較陌生。

這一問題與上一個問題上making a discrete state Markov model with pymc

+0

我也嘗試用pymc.Index替換selectedCPTLine的確定性變量定義,但這不能解決Dirichlet - 分類不兼容問題 – shpigi

回答

2

好的,謝謝。問題是,雖然PyMC通常會將Dirichlet識別爲Categorical的父項,並完成概率單純形,此時您的類別被嵌入到容器中,而Categorical不會進行所需的自動調整。下面的代碼爲你做這個:

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]) 

希望有所幫助。

+0

看起來這是我需要的! 任何想法爲什麼b的定義返回: 「零概率:隨機b值超出其支持, 或它禁止其父母的當前值。」 ? – shpigi

+0

表示存在無效值,例如分類變量範圍之外的整數。 –

+0

沒錯。缺少dtype = int。這現在可行,謝謝! – shpigi

0

混亂的一對夫婦點:

  • 模型似乎不包含數據(觀察隨機指標),所以沒有信息,以適應模型
  • 不確定你的意思是Dirichlet變量是確定性的輸出。只要概率長度爲k-1並且它們總和小於1,那麼你應該是好的。如果你有一個統一的值,你可以傳遞第一個k-1的值。
+0

感謝您關注此問題。 *我的模型不包含任何數據,因爲我將一些簡單的東西放在一起作爲示例。在現實世界的問題中,會有更多的變量,有些人會觀察到會驅動其餘分佈的數據。 – shpigi

+0

oops。編輯註釋 – shpigi

+0

關於你的第二點:我有一個確定性函數(selectCPTLine),它接受一個Dirichlet變量數組和一個分類變量,用於選擇哪個Dirichlet變量是函數的輸出。所以該函數返回一個Dirichlet變量。我想我應該寫出「確定性函數」,而不是「變量」。 希望這個澄清我想要做的。 – shpigi