如何向这个 stan 模型添加随机效果?
How can I add a random effect to this stan model?
我有一个模型,用于根据 N_subjects
上的 N_items
观察值估计类内相关性(下面的 rho
参数)。每个项目都有一个固定效果(均值向量 mu
),但我还想为每个人添加一个随机效果。我不是 100% 确定如何执行此操作,但我有一个猜测,如果有人可以确认或更正它,我将不胜感激。我是否只需要将最后一行更改为以下内容:
y[i]' ~ multi_normal(mu + gamma[i],Sigma)
其中 gamma[i]
是对人 i
的随机影响? (此外,在 parameters
块中声明一个实数列向量,然后在 model block
中给它一个先验值。)还是我做错了?
顺便说一下,如果有人对提高此模型的效率有任何建议,我将永远感激不已。
data {
int N_subjects;
int N_items;
matrix[N_subjects,N_items] y;
}
parameters {
vector[N_items] mu;
real<lower=0> sigma;
real<lower=0,upper=1> rho;
}
transformed parameters {
cov_matrix[N_items] Sigma;
for (j in 1:N_items)
for (k in 1:N_items)
Sigma[j,k] <- pow(sigma,2)*pow(rho,step(abs(j-k)-0.5));
}
model {
sigma ~ uniform(0,100);
rho ~ uniform(0,1);
for (i in 1:N_items)
mu[i] ~ normal(0,100);
for (i in 1:N_subjects)
y[i]' ~ multi_normal(mu,Sigma);
}
关于计算效率的问题,改
for (i in 1:N_items)
mu[i] ~ normal(0,100);
到
mu ~ normal(0,100);
因为这将 mu 的内存分配数量从 N_items 减少到 1。同样,您可以替换
for (i in 1:N_subjects)
y[i]' ~ multi_normal(mu,Sigma);
和
y ~ multi_normal(mu,Sigma); # or mu + gamma
如果您在 data
块中将 y
声明为 row_vector
的数组,例如
row_vector[N_items] y[N_subjects];
此外,如果您之前的信念是 sigma
在 0 和 100 之间均匀分布,那么在 parameters
块中声明这些边界在计算上更有效
real<lower=0,upper=100> sigma;
并在 model
块中注释掉它的先验
// sigma ~ uniform(0,100);
这样做效率更高,因为它避免了为 sigma
生成大于 100 的建议,这将被自动拒绝并且没有哈密顿 Monte Carlo.[=24 所需的明确定义的偏导数=]
关于模型规范问题,您可以根据需要指定多元正态似然的期望。在您的情况下,最好将 y
声明为 row_vector
的数组,例如
row_vector[N_items] y[N_subjects];
然后在 parameters
块中
vector[N_subjects] unit;
row_vector[N_items] item;
然后在 model
块中,建立 mu
以用于可能性
row_vector[N_items] mu[N_subjects];
for (i in 1:N_subjects) mu[i] <- unit[i] + item;
y ~ multi_normal(mu, Sigma);
您将需要 unit
和 item
.
的适当先验
我有一个模型,用于根据 N_subjects
上的 N_items
观察值估计类内相关性(下面的 rho
参数)。每个项目都有一个固定效果(均值向量 mu
),但我还想为每个人添加一个随机效果。我不是 100% 确定如何执行此操作,但我有一个猜测,如果有人可以确认或更正它,我将不胜感激。我是否只需要将最后一行更改为以下内容:
y[i]' ~ multi_normal(mu + gamma[i],Sigma)
其中 gamma[i]
是对人 i
的随机影响? (此外,在 parameters
块中声明一个实数列向量,然后在 model block
中给它一个先验值。)还是我做错了?
顺便说一下,如果有人对提高此模型的效率有任何建议,我将永远感激不已。
data {
int N_subjects;
int N_items;
matrix[N_subjects,N_items] y;
}
parameters {
vector[N_items] mu;
real<lower=0> sigma;
real<lower=0,upper=1> rho;
}
transformed parameters {
cov_matrix[N_items] Sigma;
for (j in 1:N_items)
for (k in 1:N_items)
Sigma[j,k] <- pow(sigma,2)*pow(rho,step(abs(j-k)-0.5));
}
model {
sigma ~ uniform(0,100);
rho ~ uniform(0,1);
for (i in 1:N_items)
mu[i] ~ normal(0,100);
for (i in 1:N_subjects)
y[i]' ~ multi_normal(mu,Sigma);
}
关于计算效率的问题,改
for (i in 1:N_items)
mu[i] ~ normal(0,100);
到
mu ~ normal(0,100);
因为这将 mu 的内存分配数量从 N_items 减少到 1。同样,您可以替换
for (i in 1:N_subjects)
y[i]' ~ multi_normal(mu,Sigma);
和
y ~ multi_normal(mu,Sigma); # or mu + gamma
如果您在 data
块中将 y
声明为 row_vector
的数组,例如
row_vector[N_items] y[N_subjects];
此外,如果您之前的信念是 sigma
在 0 和 100 之间均匀分布,那么在 parameters
块中声明这些边界在计算上更有效
real<lower=0,upper=100> sigma;
并在 model
块中注释掉它的先验
// sigma ~ uniform(0,100);
这样做效率更高,因为它避免了为 sigma
生成大于 100 的建议,这将被自动拒绝并且没有哈密顿 Monte Carlo.[=24 所需的明确定义的偏导数=]
关于模型规范问题,您可以根据需要指定多元正态似然的期望。在您的情况下,最好将 y
声明为 row_vector
的数组,例如
row_vector[N_items] y[N_subjects];
然后在 parameters
块中
vector[N_subjects] unit;
row_vector[N_items] item;
然后在 model
块中,建立 mu
以用于可能性
row_vector[N_items] mu[N_subjects];
for (i in 1:N_subjects) mu[i] <- unit[i] + item;
y ~ multi_normal(mu, Sigma);
您将需要 unit
和 item
.