1

我正在尝试在 RStan 中拟合潜在空间模型,这是一种成熟的(社交)网络模型。(这意味着这可能是 CrossValidated 的一个问题,但我有理由相信它还不是。)我知道包是可用的,但我正在努力构建一些没有包实现的东西,并且想首先确保我可以制作一个可验证的模型工作。

为了快速直观,LSM 采用一个网络,并尝试找到节点的布局,这样靠近的节点有边,而相距较远的节点没有。节点的位置是模型试图估计的潜在变量(连同截距,对应于形成边缘的总体倾向)。

我的代码(全部在下面,在两个文件中)从 LSM 假定类型的数据生成过程生成一个简单而小的杠铃图(两端密集,中间稀疏)。然后,它将这些数据传递给 RStan,它找到了一个无限的梯度,以及包 latentnet,它工作得很好。

该错误表明我从一个良好的初始化开始,所以我提供了 TRUE 生成值,并且采样器仍然找到一个无限梯度。它还建议尽可能放宽对变量的约束,但我的约束只是方差参数的下限。这让我相信我的问题出在其他地方,但我对 Stan 还不够熟悉,无法看到哪里。任何帮助,包括运行测试的建议,将不胜感激。

首先,R:

# GENERATING LSM DATA #
# The sparse path connecting the dense ends
w <- cbind(0.5*0:8-2, rep(0,9))
# The two dense barbell ends
x <- mvrnorm(10, mu=c(-2,0), Sigma=array(c(.2,0,0,.2),dim=c(2,2)))
y <- mvrnorm(10, mu=c(2,0), Sigma=array(c(.2,0,0,.2),dim=c(2,2)))
z <- rbind(w,x,y)

d <- as.matrix(dist(z))
a <- 1

logit <- function(x) 1/(1+exp(-x))

for(i in 1:N){
    for(j in 1:N){
        # This is what a LSM assumes
        X[i,j] <- (logit(a - d[i,j]) > .5)+0
    }
}
mean(X)

N <- nrow(X)

lsm.data <- list(N=N,
                 edges=X,
                 sigma_alpha=10,
                 mu_z=c(0,0),
                 sigma_z=array(c(1,0,0,1),dim=c(2,2)))

# This initialization provides the TRUE values of the parameters
lsm.init <- function(){
    list(alpha=a, z=z)
}

library(rstan)
lsm.fit <- stan("lsm.stan",
                model_name="lsm",
                data=lsm.data,
                init=lsm.init,
                verbose=T)

# Here is an independent verification of the data -- this model fits fine,
# and a plot of the result looks exactly as I think it should (a barbell).
library(latentnet)
lsm.ergmm <- ergmm(X ~ euclidean(d=2))
plot(lsm.ergmm)

在这里,斯坦的模型:

data {
    int<lower=0> N;   // number of nodes
    int<lower=0> edges[N,N]; //for now non-blank => 1
    real<lower=0> sigma_alpha; // alpha is the density
    vector[2] mu_z;             // mean of the latent positions
    matrix<lower=0>[2,2] sigma_z; // variance of the latent positions
}

parameters {
    real alpha;     // density intercept
    vector[2] z[N]; // latent positions
}


model {

    real d; // just a convenience variable, to split up a long line

    // prior on alpha
    alpha ~ normal(0, sigma_alpha);

    // latent variables
    for (i in 1:N) {
        z[i] ~ multi_normal(mu_z, sigma_z);
    }

    for(i in 1:N){
        for(j in 1:N){
            d = sqrt(pow(z[i,1]-z[j,1],2) + pow(z[i,2]-z[j,2],2));
            edges[i,j] ~ bernoulli_logit(alpha - d);
        }
    }
}
4

0 回答 0