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)
が
に非対称分布の場合には非対称分布
を与え、このようにそれを使用して、我々はその2点を検索する必要が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は実際にはdgammaではなく複雑なpdfです)。
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)に設定していますが、明確に間隔がどこかにある必要があるためです。 integrate
はゼロに近い長いシーケンスに問題があるため、(0,1E05)のような非常に大きな値を使用すると機能しないことに注意してください。あなたの状況に合わせて、ドメインを調整する必要があります(誰かが良いアイデアを持っていない限り!)。ここで
境界が問題です:ドメイン全体(自分の場合は0-1)を検索すると、関数が0または1で定義されていないため問題が発生しますが、近くにあります。関数dはモードからの距離です。これは、(モード-d)から(モード+ d)までの積分が要求された確率(あなたの場合は0.95)と等しいdを見つけるように変化します。したがって、これは対称関数でのみ機能し、そうでなければ2つのパラメータを最適化する必要があります。 –
私はそれが非対称であるならば、この問題の単一の解決策にはならないと思います!あなたは、ある確率に統合されたpdfのための多くの間隔を見つけることができます。あるいは、実際に2.5%と97%の分位数を探していますか(それらの間に95%に統合されます)?もしそうなら、それはできます。 –
これはできますが、あなたが尋ねた元の質問とは全く異なることに気をつけてください!私は自分の投稿を編集するのをためらっています。私は別の答えを加えるかもしれない。 –