對稱分佈
儘管OP的例子是不完全對稱,這是足夠接近 - 並從那裏開始有用的,因爲該解決方案是簡單得多。可以使用integrate
和optimize
的組合。我將其作爲自定義函數編寫,但請注意,如果在其他情況下使用此函數,則可能需要重新考慮搜索分位數的界限。
# For a distribution with a single peak, find the symmetric!
# interval that contains probs probability. Search over 'range'.
f_quan <- function(fun, probs, range=c(0,1)){
mode <- optimize(fun, interval = range, maximum = TRUE, tol = 1e-12)[[1]]
total_area <- integrate(fun, range[1], range[2])[[1]]
O <- function(d){
parea <- integrate(fun, mode-d, mode+d)[[1]]/total_area
(probs - parea)^2
}
# Bounds for searching may need some adjustment depending on the problem!
o <- optimize(O, c(0,range[2]/2 - 1E-02))[[1]]
return(c(mode-o, mode+o))
}
使用它像這樣,
f <- f_quan(posterior, 0.95)
curve(posterior, n = 1e4)
abline(v=f, col="blue", lwd=2, lty=3)
給
不對稱分佈
在非對稱分佈的情況下,我們必須尋找兩點符合標準P(a < x < b)= Prob,其中Prob是一些期望的概率。由於存在無限多的間隔(a,b),OP建議找到最短的一個。
解決方案中重要的是我們要搜索的區域domain
的定義(我們不能使用-Inf, Inf
,因此用戶必須將其設置爲合理的值)。
# consider interval (a,b) on the x-axis
# integrate our function, normalize to total area, to
# get the total probability in the interval
prob_ab <- function(fun, a, b, domain){
totarea <- integrate(fun, domain[1], domain[2])[[1]]
integrate(fun, a, b)[[1]]/totarea
}
# now given a and the probability, invert to find b
invert_prob_ab <- function(fun, a, prob, domain){
O <- function(b, fun, a, prob){
(prob_ab(fun, a, b, domain=domain) - prob)^2
}
b <- optimize(O, c(a, domain[2]), a = a, fun=fun, prob=prob)$minimum
return(b)
}
# now find the shortest interval by varying a
# Simplification: don't search past the mode, otherwise getting close
# to the right-hand side of domain will give serious trouble!
prob_int_shortest <- function(fun, prob, domain){
mode <- optimize(fun, interval = domain, maximum = TRUE, tol = 1e-12)[[1]]
# objective function to be minimized: the width of the interval
O <- function(a, fun, prob, domain){
b <- invert_prob_ab(fun, a, prob, domain)
b - a
}
# shortest interval that meets criterium
abest <- optimize(O, c(0,mode), fun=fun, prob=prob, domain=domain)$minimum
# now return the interval
b <- invert_prob_ab(fun, abest, prob, domain)
return(c(abest,b))
}
現在使用上面的代碼。我使用非常不對稱的函數(假設mydist實際上是一些複雜的pdf,而不是dgamma)。
mydist <- function(x)dgamma(x, shape=2)
curve(mydist(x), from=0, to=10)
abline(v=prob_int_shortest(mydist, 0.9, c(0,10)), lty=3, col="blue", lwd=2)
在這個例子中我設置域至(0,10),由於顯然的間隔必須在某處。請注意,使用非常大的值(例如(0,1E05))不起作用,因爲integrate
在接近零的長序列時遇到問題。再次,對於你的情況,你將不得不調整域名(除非有人有更好的主意!)。
界限是問題:如果你搜索整個域(在你的案例中爲0-1),我們會遇到問題,因爲函數沒有定義在0或1(但它在附近)。在函數d中,距離模式的距離是變化的,以便找到(模式-d)到(模式+ d)的積分等於請求的概率(在你的情況下爲0.95)的d。因此,這隻適用於對稱函數,否則你必須優化兩個參數。 –
我認爲如果它是不對稱的,這個問題不會有單一的解決方案!你可以找到許多可以整合到一定概率的pdf的間隔。或者,你實際上是在尋找2.5%和97.%的分位數(這些分位數會整合到95%之間)?如果是這樣,那可以做到。 –
這是可以做到的 - 但請注意,與您提出的原始問題完全不同!我毫不猶豫地編輯我的帖子,因爲這本身就是有用的。我可能會添加另一個答案。 –