Hi,
I am trying to implement a hierarchical beta mixture model with fixed alphas and betas and prior on the components weights. I based my code off another post here and I added the copula on top. My aim is to get the cluster estimates for each observation. Could someone tell me whether this makes sense and whether there are smarter ways to go about it?
data {
int<lower=1> K; // number of mixture components
int<lower=1> N; // number of data points
int<lower=1> I;//number of individuals
real<lower=0,upper=1> y[N]; // observations
real<lower=0,upper=1> x[N]; // Observations
real<lower = 0> alphax[I,K];
real<lower = 0> betax[I,K];
real<lower = 0> alphay[I,K];
real<lower = 0> betay[I,K];
real<lower = 0, upper = 1> theta[I,K];
real<lower = -1, upper = 1> rho[I,K]
int<lower=0,upper=1> prior_only; // =1 to get data from prior predictive
}
parameters {
simplex[K] w[I];
}
transformed parameters {
vector[I] log_w[K];
for (i in 1:I) {
for (k in 1:K) {
log_w[k][i] = log(w[i][k]);
}
}
}
model {
// priors
for(i in 1:I){
w[i] ~ dirichlet(theta[i]);
}
// individual likelihoods, as sum of component contributions
for (n in 1:N) {
// contributions from each component
// these get overwritten for each observation
vector[K] lps; // contributions from each component
int i = participant[n]; // Retrieve participant index for nth data point
for(k in 1:K){
real beta_x = beta_lpdf(x[n] | alphax[i,k], betax[i,k]);
real beta_y = beta_lpdf(y[n] | alphay[i,k], betay[i,k]);
real u_x = beta_cdf(x[n] | alphax[i,k], betax[i,k]);
real u_y = beta_cdf(y[n] | alphay[i,k], betay[i,k]);
real copula_density = gaussian_copula_density(u_x, u_y, rho[i,k]);
lps[k] = log_w[i][k]+beta_x + beta_y+ log(copula_density);
}
target += log_sum_exp(lps);
}
}
generated quantities {
real x_rep[N];
real y_rep[N];
for (n in 1:N) {
int i = participant[n]; // Retrieve participant index for nth data point
vector[K] ps;
for (k in 1:K) {
real u_x = beta_cdf(x[n] | alphax[i, k], betax[i, k]);
real u_y = beta_cdf(y[n] | alphay[i, k], betay[i, k]);
real copula_density = gaussian_copula_density(u_x, u_y, rho[i, k]);
ps[k] = w[i][k] * copula_density;
}
int comp = categorical_rng(ps); // Sample a component
x_rep[n] = beta_rng(alphax[i, comp], betax[i, comp]); // Generate new x data
y_rep[n] = beta_rng(alphay[i, comp], betay[i, comp]); // Generate new y data
}
}
// Function to compute the Gaussian copula density
real gaussian_copula_density(real u_x, real u_y, real rho) {
real z_x = quantile(normal_cdf(u_x), 0.5); // Convert to normal scale
real z_y = quantile(normal_cdf(u_y), 0.5); // Convert to normal scale
real copula_density = normal_lpdf(z_x | 0, 1) + normal_lpdf(z_y | 0, 1)
- normal_lpdf(z_x, z_y | 0, rho); // Gaussian copula density
return exp(copula_density);
}