二参数贝叶斯可信区间
Two-parameter Bayesian credibility Interval
如何确定多参数模型后验估计的 confidence/credibility 区间?
我可以分别得到每个参数的置信区间。
(目前正在使用 bayestestR
,但我不介意使用其他东西)
library(dplyr)
library(ggplot2)
library(bayestestR)
N <- 10000
#Posterior samples (random example)
p1 <- rnorm(N)
p2 <- p1 + rnorm(N)
df_post <- tibble(p1,p2)
describe_posterior(
df_post,
centrality = "median",
test = c("p_direction", "p_significance")
)
##Yields:
# Summary of Posterior Distribution
#
# Parameter | Median | 95% CI | pd | ps
# -----------------------------------------------------
# p1 | 0.02 | [-1.85, 2.08] | 50.64% | 0.46
# p2 | -2.24e-03 | [-2.82, 2.78] | 50.04% | 0.47
我可以生成一个包含点和 2D 等高线的图,这为我提供了后验分布的视觉指示(尽管我不知道每个等高线代表什么百分比):
ggplot(df_post, aes(x=p1, y=p2)) +
geom_density_2d(size=1) +
geom_point(size=0.1)
我的问题是,我如何实际计算(and/or 绘图)二维 X% 可信区间?
这是一个 base-R 绘图解决方案,它根据二维核密度估计绘制了 95% 的最高后验密度区域:
library(emdbook)
library(coda)
HPDregionplot(as.mcmc(df_post))
with(df_post, points(p1, p2, col = adjustcolor("black", alpha.f = 0.2)))
更多 smoothly/within ggplot
:
library(ggplot2); theme_set(theme_bw())
## see function definition below
L <- with(df_post, get_hpd2d_levels(p1, p2))
gg0 <- ggplot(df_post, aes(p1, p2)) + geom_point(alpha=0.1) +
geom_density_2d(breaks = L, colour="red")
print(gg0)
后验密度最高的区域是经典贝叶斯方法。如果您想深入探索,可以看看一些参数较少的方法来计算中心集(包图、功能深度等)。这类似于最高后验密度区域和基于分位数的可信区间之间的差异。
##' Get 2D highest posterior density levels corresponding to probability regions
##' @param x x-coordinate of samples
##' @param y y-coordinate
##' @param probs vector of probability levels
##' @param ... arguments for MASS::kde2d
##' @examples
##' dd <- data.frame(x=rnorm(1000), y=rnorm(1000))
##' get_hpd2d_levels(dd$x,dd$y)
##' gg2 <- ggplot(dd, aes(x,y)) + geom_density_2d(breaks=get_hpd2d_levels(dd$x,dd$y), colour="red")
##' print(gg2)
get_hpd2d_levels <- function(x, y, prob=c(0.9,0.95), ...) {
post1 <- MASS::kde2d(x, y)
dx <- diff(post1$x[1:2])
dy <- diff(post1$y[1:2])
sz <- sort(post1$z)
c1 <- cumsum(sz) * dx * dy
## remove duplicates
## dups <- duplicated(sz)
## sz <- sz[!dups]
## c1 <- c1[!dups]
levels <- sapply(prob, function(x) {
approx(c1, sz, xout = 1 - x, ties = mean)$y
})
return(levels)
}
works well, but here's another suggestion (based on ) 也有效:
car::dataEllipse(p1, p2, levels=0.95)
如何确定多参数模型后验估计的 confidence/credibility 区间?
我可以分别得到每个参数的置信区间。
(目前正在使用 bayestestR
,但我不介意使用其他东西)
library(dplyr)
library(ggplot2)
library(bayestestR)
N <- 10000
#Posterior samples (random example)
p1 <- rnorm(N)
p2 <- p1 + rnorm(N)
df_post <- tibble(p1,p2)
describe_posterior(
df_post,
centrality = "median",
test = c("p_direction", "p_significance")
)
##Yields:
# Summary of Posterior Distribution
#
# Parameter | Median | 95% CI | pd | ps
# -----------------------------------------------------
# p1 | 0.02 | [-1.85, 2.08] | 50.64% | 0.46
# p2 | -2.24e-03 | [-2.82, 2.78] | 50.04% | 0.47
我可以生成一个包含点和 2D 等高线的图,这为我提供了后验分布的视觉指示(尽管我不知道每个等高线代表什么百分比):
ggplot(df_post, aes(x=p1, y=p2)) +
geom_density_2d(size=1) +
geom_point(size=0.1)
我的问题是,我如何实际计算(and/or 绘图)二维 X% 可信区间?
这是一个 base-R 绘图解决方案,它根据二维核密度估计绘制了 95% 的最高后验密度区域:
library(emdbook)
library(coda)
HPDregionplot(as.mcmc(df_post))
with(df_post, points(p1, p2, col = adjustcolor("black", alpha.f = 0.2)))
更多 smoothly/within ggplot
:
library(ggplot2); theme_set(theme_bw())
## see function definition below
L <- with(df_post, get_hpd2d_levels(p1, p2))
gg0 <- ggplot(df_post, aes(p1, p2)) + geom_point(alpha=0.1) +
geom_density_2d(breaks = L, colour="red")
print(gg0)
后验密度最高的区域是经典贝叶斯方法。如果您想深入探索,可以看看一些参数较少的方法来计算中心集(包图、功能深度等)。这类似于最高后验密度区域和基于分位数的可信区间之间的差异。
##' Get 2D highest posterior density levels corresponding to probability regions
##' @param x x-coordinate of samples
##' @param y y-coordinate
##' @param probs vector of probability levels
##' @param ... arguments for MASS::kde2d
##' @examples
##' dd <- data.frame(x=rnorm(1000), y=rnorm(1000))
##' get_hpd2d_levels(dd$x,dd$y)
##' gg2 <- ggplot(dd, aes(x,y)) + geom_density_2d(breaks=get_hpd2d_levels(dd$x,dd$y), colour="red")
##' print(gg2)
get_hpd2d_levels <- function(x, y, prob=c(0.9,0.95), ...) {
post1 <- MASS::kde2d(x, y)
dx <- diff(post1$x[1:2])
dy <- diff(post1$y[1:2])
sz <- sort(post1$z)
c1 <- cumsum(sz) * dx * dy
## remove duplicates
## dups <- duplicated(sz)
## sz <- sz[!dups]
## c1 <- c1[!dups]
levels <- sapply(prob, function(x) {
approx(c1, sz, xout = 1 - x, ties = mean)$y
})
return(levels)
}
car::dataEllipse(p1, p2, levels=0.95)