–update
The issue was resolved after I went into the data simulation and added a positive value to the item 8 that previously had zero loading on any latent factor in the generating model. This seems to be an issue of the sampler trying to figure out parameters for which the dataset did not provide any information…This was curious because it was not a problem if the model were to model the covariance structure.
-----original post
Hello Stan users,
I have a linear confirmatory factor analysis model using the continuous specification (same as an IRT model without the Bernoulli link). It has the sign indeterminacy issue that has been discussed on this forum before; I addressed it by constraining all factor loadings to positive for now. The model should have proper non-centering and using mostly standard normal prior now.
It works fine with simple model specifications such as one factor and 10 items, but as the dimensions and the number of parameters increase, the model no longer fit well. I am puzzled as to what to do. Does this suggest that the model is only valid within in certain dimensions?
For example, the model accompanying the first path diagram works almost marginally fine, as seen in the output below, but this is not true for the second case.
Inference for Stan model: fa - alt.
4 chains, each with iter=1500; warmup=750; thin=1;
post-warmup draws per chain=750, total post-warmup draws=3000.
mean se_mean sd 2.5% 50% 97.5% n_eff Rhat
L[1,1] 0.86 0.00 0.06 0.74 0.86 0.98 830 1.00
L[1,2] 0.00 NaN 0.00 0.00 0.00 0.00 NaN NaN
L[1,3] 0.00 NaN 0.00 0.00 0.00 0.00 NaN NaN
L[2,1] 0.00 NaN 0.00 0.00 0.00 0.00 NaN NaN
L[2,2] 0.81 0.00 0.05 0.71 0.81 0.92 728 1.00
L[2,3] 0.00 NaN 0.00 0.00 0.00 0.00 NaN NaN
L[3,1] 0.00 NaN 0.00 0.00 0.00 0.00 NaN NaN
L[3,2] 0.20 0.00 0.03 0.15 0.20 0.26 2899 1.00
L[3,3] 0.00 NaN 0.00 0.00 0.00 0.00 NaN NaN
L[4,1] 0.00 NaN 0.00 0.00 0.00 0.00 NaN NaN
L[4,2] 0.00 NaN 0.00 0.00 0.00 0.00 NaN NaN
L[4,3] 0.83 0.00 0.05 0.74 0.83 0.92 646 1.00
L[5,1] 0.82 0.00 0.06 0.71 0.82 0.93 669 1.01
L[5,2] 0.00 NaN 0.00 0.00 0.00 0.00 NaN NaN
L[5,3] 0.00 NaN 0.00 0.00 0.00 0.00 NaN NaN
L[6,1] 0.00 NaN 0.00 0.00 0.00 0.00 NaN NaN
L[6,2] 0.00 NaN 0.00 0.00 0.00 0.00 NaN NaN
L[6,3] 0.77 0.00 0.04 0.69 0.77 0.85 662 1.00
L[7,1] 0.51 0.00 0.04 0.42 0.51 0.59 823 1.00
L[7,2] 0.00 NaN 0.00 0.00 0.00 0.00 NaN NaN
L[7,3] 0.71 0.00 0.05 0.62 0.71 0.80 819 1.00
L[8,1] 0.00 NaN 0.00 0.00 0.00 0.00 NaN NaN
L[8,2] 0.67 0.00 0.04 0.59 0.67 0.75 585 1.00
L[8,3] 0.00 NaN 0.00 0.00 0.00 0.00 NaN NaN
L[9,1] 0.00 NaN 0.00 0.00 0.00 0.00 NaN NaN
L[9,2] 0.24 0.00 0.04 0.17 0.24 0.32 2171 1.00
L[9,3] 0.85 0.00 0.05 0.76 0.85 0.94 692 1.00
L[10,1] 0.00 NaN 0.00 0.00 0.00 0.00 NaN NaN
L[10,2] 0.27 0.00 0.04 0.19 0.27 0.35 2211 1.00
L[10,3] 0.79 0.00 0.05 0.70 0.79 0.89 760 1.00
psi[1] 0.72 0.00 0.05 0.63 0.72 0.82 646 1.00
psi[2] 0.54 0.00 0.05 0.44 0.54 0.63 360 1.00
psi[3] 0.42 0.00 0.02 0.39 0.42 0.46 5030 1.00
psi[4] 0.51 0.00 0.03 0.46 0.51 0.56 2314 1.00
psi[5] 0.58 0.00 0.05 0.47 0.59 0.68 341 1.01
psi[6] 0.44 0.00 0.02 0.39 0.44 0.48 2445 1.00
psi[7] 0.48 0.00 0.03 0.42 0.48 0.55 748 1.00
psi[8] 0.39 0.00 0.04 0.29 0.39 0.47 341 1.01
psi[9] 0.49 0.00 0.03 0.43 0.48 0.54 2313 1.00
psi[10] 0.54 0.00 0.03 0.49 0.54 0.60 3147 1.00
mu_theta_fix[1] 0.00 NaN 0.00 0.00 0.00 0.00 NaN NaN
mu_theta_fix[2] 0.00 NaN 0.00 0.00 0.00 0.00 NaN NaN
mu_theta_fix[3] 0.00 NaN 0.00 0.00 0.00 0.00 NaN NaN
sigma_phi[1] 0.10 0.00 0.04 0.03 0.10 0.17 875 1.00
sigma_phi[2] 0.06 0.00 0.03 0.01 0.06 0.13 756 1.00
sigma_phi[3] 0.05 0.00 0.03 0.00 0.05 0.12 617 1.00
nu[1] 0.08 0.00 0.06 -0.05 0.07 0.20 931 1.01
nu[2] -0.01 0.00 0.06 -0.12 -0.01 0.10 671 1.00
nu[3] -0.02 0.00 0.03 -0.08 -0.02 0.03 1817 1.00
nu[4] 0.00 0.00 0.06 -0.11 0.00 0.12 355 1.00
nu[5] 0.06 0.00 0.06 -0.05 0.06 0.18 929 1.00
nu[6] -0.01 0.00 0.05 -0.12 -0.01 0.10 332 1.00
nu[7] -0.02 0.00 0.06 -0.14 -0.02 0.11 394 1.01
nu[8] 0.02 0.00 0.04 -0.07 0.02 0.11 678 1.00
nu[9] 0.02 0.00 0.06 -0.11 0.02 0.14 357 1.01
nu[10] 0.00 0.00 0.06 -0.12 0.00 0.12 393 1.00
phi[1,1] 1.00 NaN 0.00 1.00 1.00 1.00 NaN NaN
phi[1,2] 0.10 0.00 0.04 0.03 0.10 0.17 875 1.00
phi[1,3] 0.06 0.00 0.03 0.01 0.06 0.13 756 1.00
phi[2,1] 0.10 0.00 0.04 0.03 0.10 0.17 875 1.00
phi[2,2] 1.00 NaN 0.00 1.00 1.00 1.00 NaN NaN
phi[2,3] 0.05 0.00 0.03 0.00 0.05 0.12 617 1.00
phi[3,1] 0.06 0.00 0.03 0.01 0.06 0.13 756 1.00
phi[3,2] 0.05 0.00 0.03 0.00 0.05 0.12 617 1.00
phi[3,3] 1.00 NaN 0.00 1.00 1.00 1.00 NaN NaN
lp__ 104.08 1.68 36.48 33.49 103.82 176.06 472 1.01
Second model specification:
Output pair plot. This is produced after I already increased the treepath to 15 and adapt delta to 0.9
Stan code is below. Any opinions on this would be much appreciated!
data {
int<lower=1> N; // sample size
int<lower=1> P; // number of items
matrix[N,P] Y; // data matrix of order [N,P]
int<lower=1> D; // number of latent dimensions
matrix[P,D] Ldes; // design matrix for factor loadings
int<lower=1> M; // number of non-zero factor loadings
}
parameters {
vector<lower=0>[D] Lp; // first factor loading
vector<lower=0>[M-D] Lr; // rest of non-zero factor loading
vector[P] nu; // item intercepts
vector<lower=0>[P] psi; // vector of residual variances
vector<lower=0>[D*(D-1)/2] sigma_phi; // factor correlation
matrix[D,N] fac_dist_helper; // helper for non-centered multivariate sampling
vector[D] mu_theta;
}
transformed parameters{
matrix[D,N] fac_scor_helper; // helper for phi
matrix[D,N] fac_scor; //person factor scores
matrix[P,D] L; // constrained factor loading matrix
cov_matrix[D] phi; // factor covariance matrix fixed
vector[D] mu_theta_fix; // vector of factor means
...code partially omitted to save space
// non-centered factor score multi-norm dist.
fac_scor_helper <- phi * fac_dist_helper;
for (k in 1:N){
fac_scor[,k] <- mu_theta_fix + fac_scor_helper[,k];
}
}
model {
// the priors
Lp ~ lognormal(0,1);
Lr ~ lognormal(0,1);
sigma_phi ~ student_t(9,0,1);
psi ~ student_t(9,0,5);
to_vector(fac_dist_helper) ~ normal(0,1);
nu ~ normal(0,1);
mu_theta ~ normal(0,1);
//The likelihood
for(j in 1:N){
for(i in 1:P){
Y[j,i] ~ normal( nu[i] + L[i,] * fac_scor[,j], psi[i] );
}
}
}