I created a relatively simple code implementing a parametric weighted stochastic block model to kind of play around and get familiar with Nimble. The model code is the following
model_code_param_ext <- nimbleCode({
## Prior for probability for vertices to be in blocks
r[1:nB] ~ ddirch(pc[1:nB])
## Prior for connectivity within blocks + edges parameter distr.
for (a in 1:nB){
for (b in 1:nB){
B[a,b] ~ dbeta(beta1, beta2)
## We assume same hyperparameters for shapes and rates.
shapes[a,b] ~ dgamma(nu, beta)
rates[a,b] ~ dgamma(nu, beta)
}
}
###### Vertex block membership
for (i in 1:N){
Z[i] ~ dcat(r[1:nB])
}
##### Now we go to the likelihood of the adiecency matrix and of the weights.
for (i in 1:N){
for(j in 1:N){
#for(j in 1:i-1){
A[i,j] ~ dbinom(size=1, prob=B[Z[i], Z[j]])
W[i,j] ~ dweigthbm_gamma(shapes[Z[i], Z[j]], rates[Z[i], Z[j]], A[i,j])
}
}
})
with dweigthbm_gamma
dweigthbm_gamma <- nimbleFunction(
run=function(x=double(0), shape_ij=double(0), rate_ij=double(0), A_ij=integer(0), log=integer(0, default=0)){
returnType(double(0))
if (A_ij != 0){
val <- dgamma(x, shape=shape_ij, rate=rate_ij)
}
else{
if (x != 0){
val <- 0.0
}
else{
val <- 1.0
}
}
if (log) return(log(val))
else return(log)
}
)
rweigthbm_gamma <- nimbleFunction(
run=function(n=integer(0,default=1), shape_ij=double(0), rate_ij=double(0), A_ij=integer(0)){
returnType(double(0))
if (A_ij != 0){
return (rgamma(n=1, shape=shape_ij, rate=rate_ij))
}
else{
return(0)
}
}
)
I then create a slightly misspecified dataset to test the sample in the following way:
K <- 2
## Number of blocks
nB <- 2
## Number of vertices in the graph
n <- 50
B = matrix(0,nrow=nB, ncol=nB)
B[1,1] = 0.5
B[2,2] = 0.7
B[1,2] = 0.2
B[2,1] = B[1,2]
shapes <- array(c(100.0,50.0))
rates <- array(c(100.0, 10.0))
pi_0 <- array(c(0.75, 0.25))
pi_1 <- array(c(0.25, 0.75))
## Generate the data according to the model
Z_true = array(0, n)
for (i in 1:n){
Z_true[i] = rcat(prob=r)
}
A = matrix(0, nrow=n, ncol=n)
W = matrix(0, nrow=n, ncol=n)
s_true = matrix(nrow=n, ncol=n)
for (i in 2:n){
for (j in 1:(i-1)){
if (Z_true[i]==Z_true[j]){
s_true[i,j] = rcat(prob=pi_0)
s_true[j,i] = s_true[i,j]
}
else{
s_true[i,j] = rcat(prob=pi_1)
s_true[j,i] = s_true[i,j]
}
A[i,j] = rbinom(n=1, size=1, prob=B[Z_true[i], Z_true[j]])
A[j,i] = A[i,j]
if (A[i,j] == 1){
W[i,j] = rgamma(n=1, shape=shapes[s_true[i,j]], rate=rates[s_true[i,j]])
W[j,i] = W[i,j]
}
}
}
where the misspecification is in the weights. I then compile the model and sample
Hence most of the latent variables have not moved during the sampling, which seems very very odd. Does anyone have an idea of what could cause this behaviour?
Hello to everyone!
I created a relatively simple code implementing a parametric weighted stochastic block model to kind of play around and get familiar with Nimble. The model code is the following
with
dweigthbm_gamma
I then create a slightly misspecified dataset to test the sample in the following way:
where the misspecification is in the weights. I then compile the model and sample
During the sampling I get no error messages/warnings, and when I look at the output I get:
Hence most of the latent variables have not moved during the sampling, which seems very very odd. Does anyone have an idea of what could cause this behaviour?