有没有办法保存MCMClogit使用的MCMC算法的接受率?

时间:2017-09-28 15:36:13

标签: r mcmc

RMCMCpack通过MCMClogit提供贝叶斯逻辑回归。如果verbose=TRUE,此函数会打印MCMC(Metropolis-Hastings)算法的接受率,但它似乎不会在mcmc对象中返回它。有没有办法在对象中访问此信息?

测试用途:

    library(MCMCpack)
    set.seed(12345) 
    n = 1000 
    x = rnorm(n) 
    y = rbinom(n,1,1/(1+exp(-(1 + x))))
    m = MCMClogit(y ~ x, burnin = 5000, mcmc = 1000,
                         tune = 1.3, B0 = 0, verbose = TRUE)

打印的接受率为0.45533,但我在names(m)返回NULLnames(attributes(m))返回

中找不到此信息
[1] "dim"      "mcpar"    "class"    "dimnames" "title"    "y"        "call"

帮助文件建议coda包允许从mcmc个对象中提取信息(请参阅coda),但会搜索“接受”字样。在pdf中不会产生任何结果。

2 个答案:

答案 0 :(得分:1)

这是一个黑客......但仍然是一个解决方案:

output = capture.output(MCMClogit(y ~ x, burnin = 5000, mcmc = 1000,
                                  tune = 1.3, B0 = 0, verbose = TRUE))

library(stringr)
library(dplyr)

output %>%
  paste0(collapse = "") %>%
  str_extract("\\d+[.]\\d+(?=[@])") %>%
  as.numeric()

# [1] "0.45533"

这使用capture.outputMCMClogit中控件中打印的内容作为字符串存储在变量中,然后使用正则表达式提取接受率。正则表达式相对容易的原因是接受率被@包围。

OP提出了一个很好的观点,即使用这种方法,MCMClogit必须运行两次,如果模型需要很长时间才能运行,这是不可取的。可以做的一件事是使用<<-(可能很危险),并将模型分配到全局环境中的m

output = capture.output(m <<- MCMClogit(y ~ x, burnin = 5000, mcmc = 1000,
                                        tune = 1.3, B0 = 0, verbose = TRUE))

这样,模型对象将存储在m中,控制台输出将同时存储在output中。

另请注意,<<-实际上在父环境中分配变量。在这种情况下,只有一个函数,父环境是全局环境。但是,在存在嵌套函数的情况下,父环境将位于嵌套上方一级,因此应使用assign代替:

output = capture.output(assign("m", MCMClogit(y ~ x, burnin = 5000, mcmc = 1000,
                                              tune = 1.3, B0 = 0, verbose = TRUE),
                               envir = globalenv()))

答案 1 :(得分:1)

如果您不喜欢capture.output的行为,则可以改为使用sink,但仍会返回结果,但会将控制台输出重定向到文件中。

sink(file="test.txt")
m <- MCMClogit(y ~ x, burnin = 5000, mcmc = 1000,
               tune = 1.3, B0 = 0, verbose = TRUE)
sink()

out <- readLines("test.txt")
grep( "acceptance rate for beta was", out, value=T)
# [1] "The Metropolis acceptance rate for beta was 0.45533"

class(m)
# [1] "mcmc"

无需assign<<-

如果您想将其作为数值,则可以按如下方式提取它。

ar <- grep( "acceptance rate for beta was", out, value=T)
ar <- as.numeric( gsub("^.* was (.*)", "\\1", ar) )
ar
# [1] 0.45533