Hello, PyMC3 community!
I’ve been trying to implement independent bayesian classifier combination according to Kim, Ghahramani (2012). [Figure 1, see below]
-
Sample class probabilities from Dirichlet, with hyper parameter nu
-
Sample class labels array from Multinomial, I’ve picked to use Categorical
-
Sample sample parameters alpha from exponential, given hyper parameter lambda
-
Sample classifier confusion matrices from dirichlet
-
Generate classifier classes given their confusion matrices conditioned on a sample of label array t at instance i.
At first I was not able to index confusion matrices pi, given the value of the target t, as below:
I = 100 # number of instances
J = 3 # number of classes
K = 4 # number of classifiers
nu_vec = np.array([1. for _ in range(J)], dtype=np.float32)
lambda_mat = np.array([[.3, 3., 2.], [2., .5, 3.], [2., 3., .5]], dtype=np.float32)
IBCC = pm.Model()
with IBCC:
p_vec = pm.Dirichlet(name='p_vec', a=nu_vec)
t = pm.Categorical(name='t', p=p_vec, shape=I)
alpha = [pm.Exponential('alpha_{}'.format(k), lam=lambda_mat, shape=(J, J)) for k in range(K)]
pi = [[pm.Dirichlet('pi_j{}k{}'.format(j, k), alpha[k][j], shape=(3)) for j in range(J)] for k in range(K)]
c = [[] for k in range(K)]
for i in range(I):
for k in range(K):
c[k].append(pm.Categorical('c_k{}i{}', p=pi[k][t[i]], observed=c_train[k][t[i]]))
The code above, was giving me an error: TypeError: list indices must be integers or slices, not FreeRV
.
I attempted to solve that by inserting a t_sample = t.random()
line inside the model, like this:
IBCC = pm.Model()
with IBCC:
p_vec = pm.Dirichlet(name='p_vec', a=nu_vec)
t = pm.Categorical(name='t', p=p_vec, shape=I)
alpha = [pm.Exponential('alpha_{}'.format(k), lam=lambda_mat, shape=(J, J)) for k in range(K)]
pi = [[pm.Dirichlet('pi_j{}k{}'.format(j, k), a=alpha[k][j], shape=3) for j in range(J)] for k in range(K)]
c = [[] for k in range(K)]
t_sample = t.random()
for i in range(I):
for k in range(K):
c[k].append(pm.Categorical('c_k{}i{}'.format(k, i), p=pi[k][t_sample[i]], observed=c_train[k][i]))
which, seemed to work. However, I am not sure if that is a correct way to do it?
I followed by doing inference:
with IBCC:
step1 = pm.sampling.CategoricalGibbsMetropolis([t]+[c[k][i] for i in range(I) for k in range(K)])
step2 = pm.sampling.Metropolis([alpha[k] for k in range(K)] + [pi[k][j] for j in range(J) for k in range(K)]+
[p_vec])
trace = pm.sample(50000, step=[step1, step2])
which continues, to work however in the end does not produce the correct results. I have also tried to use default pm.sample()
without specifying the samplers, it did not produce correct results either. Both cases, in the end estimate equal probabilities for all labels for every instance. Would appreciate any suggestion or help! Thank you!