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

为了快速直观,LSM采用网络,并尝试为节点找到布局,使得近端节点具有边缘,而远距离节点则不具有边缘 . 节点的位置是潜在变量,模型试图估计(与截距一起,对应于形成边缘的总体倾向) .

我的代码(以下所有,在两个文件中)从LSM假定的类型的数据生成过程生成一个简单的小杠铃图(两端密集,中间稀疏) . 然后它将这些数据传递给RStan,它发现了一个无限的渐变,而包裹潜在网,它工作正常 .

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

首先,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);
        }
    }
}