简体   繁体   English

Gibbs采样未产生预期结果

[英]Gibbs sampling is not producing expected results

I am attempting to learn the mechanics of Gibbs sampling . 我正在尝试学习吉布斯采样的机理。 I have 2 variables for which I am trying to conduct inference from. 我有2个变量,我试图从中进行推断。 This example assumes only Gaussian distributions. 本示例仅假设高斯分布。 My code in R looks like the following. 我在R代码如下所示。

library(condMVNorm)

rm(list=ls())

means <- c(0, 25)
cov <- matrix(c(1.09, 1.95, 1.95, 4.52), 2, 2)

k <- 10
initSample <- c(0, 0)
traceSamples <- matrix(, k, 2)

for (i in 1:k) {
    X <- initSample[1]
    c1 <- rcmvnorm(n=1, mean=means, sigma=cov, dep=2, given=1, X=X)

    X <- c1
    c2 <- rcmvnorm(n=1, mean=means, sigma=cov, dep=1, given=2, X=X)

    currentSample <- c(c1, c2)
    traceSamples[i, ] <- currentSample
    initSample <- currentSample
}

colMeans(traceSamples)

What I get as the output is the following. 我得到的输出如下。

[1] 2220.7619  947.3168

I would have expected that the first variable would be pretty close to 25 and the second one to 0. 我曾期望第一个变量非常接近25,第二个变量接近0。

I do not know if my understanding is wrong with Gibbs sampling because the literature invariably says you sample from the conditional distribution p(X1=x1|X2=x2) . 我不知道我对Gibbs采样的理解是否有误,因为文献总是指出您是从条件分布p(X1=x1|X2=x2)采样。 To me, p(X1=x1|X2=x2) is the density estimation of X1=x1 given X2=x2 , and one would map that to dcmvnorm and not rcmvnorm . 对我来说, p(X1=x1|X2=x2)是在给定X2=x2X1=x1的密度估计,并且可以将其映射到dcmvnorm而不是rcmvnorm

Printing the traceSamples matrix, I get the following. 打印traceSamples矩阵,得到以下结果。

[,1]         [,2]
 [1,]   22.0574   -0.7827272
 [2,]   63.6865   16.3375931
 [3,]  138.7078   49.2994688
 [4,]  272.0850  107.3952335
 [5,]  510.2272  208.3522406
 [6,]  940.7504  395.4438929
 [7,] 1708.2603  725.3048137
 [8,] 3080.5096 1317.7650679
 [9,] 5538.0734 2378.8674730
[10,] 9933.2615 4275.1848015

The values seem to be increasing (so this suggest something is wrong with my R code). 值似乎正在增加(因此这表明我的R代码有问题)。 Furthermore, I also do a very simple sampling without the for loop. 此外,我还做了一个非常简单的采样,没有for循环。

means <- c(0, 25)
cov <- matrix(c(1.09, 1.95, 1.95, 4.52), 2, 2)
x1 <- rcmvnorm(n=1, mean = means, sigma = cov, dep=2, given=1, X=c(0))
x2 <- rcmvnorm(n=1, mean = means, sigma = cov, dep=1, given=2, X=c(x1))

x1 <- rcmvnorm(n=1, mean = means, sigma = cov, dep=2, given=1, X=c(x2))
x2 <- rcmvnorm(n=1, mean = means, sigma = cov, dep=1, given=2, X=c(x1))

My x1 and x2 values for each of these are as follows. 我的每一个的x1和x2值如下。

23.40496 -0.01044726
22.67643 -0.6836546

Any ideas on what I am doing wrong? 关于我在做什么错的任何想法吗?

Note, I was able to get better expected results with the following code. 注意,使用以下代码可以获得更好的预期结果。

means <- c(0, 25)
cov <- matrix(c(1.09, 1.95, 1.95, 4.52), 2, 2)

k <- 9000
x1 <- 0
x2 <- 0
traceSamples <- matrix(, k, 2)

for (i in 1:k) {
    x1 <- rcmvnorm(n=1, mean=means, sigma=cov, dep=2, given=1, X=x2)
    x2 <- rcmvnorm(n=1, mean=means, sigma=cov, dep=1, given=2, X=x1)

    traceSamples[i, ] <- c(x1, x2)
}

colMeans(traceSamples)

Could someone tell me what I'm doing wrong with reusing and re-assigning initSample ? 有人可以告诉我重复使用和重新分配initSample我做错了什么吗?

Here I solved the problem of why Gibbs, was providing erroneous values in the simulation, but I think it is getting complicated when doing the code in that way, I think that some lines could be removed to structure the code in a more efficient way, which is also faster. 在这里,我解决了为什么Gibbs在仿真中提供错误值的问题,但是我认为以这种方式编写代码时变得越来越复杂,我认为可以删除一些行以更有效地构造代码,这也更快。 However, notice the changes I made in x <-initSample and X = X[1] and X = X[2] . 但是,请注意我在x <-initSample所做的更改,并且X = X[1]X = X[2]

library(condMVNorm)
rm(list=ls())

means <- c(0, 25)
cov <- matrix(c(1.09, 1.95, 1.95, 4.52), 2, 2)
k <- 9000
initSample <- c(0,0)
traceSamples <- matrix(, k, 2)
for (i in 1:k){
  X <- initSample
  c1 <- rcmvnorm(n=1, mean=means, sigma=cov, dep=2, given=1, X=X[2])
  X <- c1
  c2 <- rcmvnorm(n=1, mean=means, sigma=cov, dep=1, given=2, X=X[1])
  currentSample <- c(c1, c2)
  traceSamples[i, ] <- currentSample
  initSample <- currentSample
}
> head(traceSamples,10)
                  [,1]                [,2]
 [1,] 23.8233821520619 -0.9169596237697860
 [2,] 22.8293033255339 -1.6287517329781345
 [3,] 21.3923155517845 -1.9104909272586084
 [4,] 20.5331401021848 -2.3320921649401360
 [5,] 21.4287399563041 -1.1376683051591154
 [6,] 23.4335659872032 -0.4379604108831421
 [7,] 25.4074041761893 -0.0613743089436460
 [8,] 24.2471298284230  0.0764901351102767
 [9,] 24.7450703427834 -1.2443499508519478
[10,] 24.2193799579308 -0.4995919725966815
> cov.wt(traceSamples)
$cov
                 [,1]             [,2]
[1,] 4.54864368811939 1.96444834328156
[2,] 1.96444834328156 1.09723665614730

$center
[1] 24.9626145462517535 -0.0163323659130855

$n.obs
[1] 9000

Gibbs sampler is a Markov chain Monte Carlo (MCMC) algorithm. Gibbs采样器是马尔可夫链蒙特卡洛(MCMC)算法。 Therefore you should check the convergence of the chain. 因此,您应该检查链的收敛性。 The coda package provides some very useful tests. 尾声包提供了一些非常有用的测试。

library(coda)
MC <- mcmc(traceSamples)
plot(MC)
heidel.diag(MC)
Stationarity start     p-value
     test         iteration        
var1 passed       1         0.231  
var2 passed       1         0.193  

     Halfwidth Mean    Halfwidth
     test                       
var1 passed    24.9626 0.1228   
var2 failed    -0.0163 0.0598

在此处输入图片说明

Where accept the null hypothesis that the Markov chain is from a stationary distribution. 在哪里接受零假设,即马尔可夫链来自平稳分布。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM