两个正态分布的重叠区域的百分比

机器算法验证 正态分布 相似之处 公制 巴塔查亚
2022-02-08 09:36:03

我想知道,给定两个正态分布与σ1, μ1σ2, μ2

  • 如何计算两个分布的重叠区域的百分比?
  • 我想这个问题有一个特定的名称,你知道描述这个问题的任何特定名称吗?
  • 你知道这个的任何实现(例如,Java 代码)吗?
4个回答

这通常也称为“重叠系数”(OVL)。谷歌搜索这个会给你很多点击。您可以在此处找到双法线情况的列线图有用的论文可能是:

  • 亨利·英曼;小埃德温·L·布拉德利 (1989)。重叠系数作为概率分布和两个正态密度重叠的点估计之间一致性的度量。统计通讯 - 理论和方法,18(10),3851-3874。链接

编辑

现在你让我对这个更感兴趣了,所以我继续创建 R 代码来计算这个(这是一个简单的集成)。我加入了两个分布的图,包括重叠区域的阴影:

min.f1f2 <- function(x, mu1, mu2, sd1, sd2) {
    f1 <- dnorm(x, mean=mu1, sd=sd1)
    f2 <- dnorm(x, mean=mu2, sd=sd2)
    pmin(f1, f2)
}

mu1 <- 2;    sd1 <- 2
mu2 <- 1;    sd2 <- 1

xs <- seq(min(mu1 - 3*sd1, mu2 - 3*sd2), max(mu1 + 3*sd1, mu2 + 3*sd2), .01)
f1 <- dnorm(xs, mean=mu1, sd=sd1)
f2 <- dnorm(xs, mean=mu2, sd=sd2)

plot(xs, f1, type="l", ylim=c(0, max(f1,f2)), ylab="density")
lines(xs, f2, lty="dotted")
ys <- min.f1f2(xs, mu1=mu1, mu2=mu2, sd1=sd1, sd2=sd2)
xs <- c(xs, xs[1])
ys <- c(ys, ys[1])
polygon(xs, ys, col="gray")

### only works for sd1 = sd2
SMD <- (mu1-mu2)/sd1
2 * pnorm(-abs(SMD)/2)

### this works in general
integrate(min.f1f2, -Inf, Inf, mu1=mu1, mu2=mu2, sd1=sd1, sd2=sd2)

对于这个例子,结果是:0.6099324with absolute error < 1e-04下图。

例子

这是由Bhattacharyya 系数给出的。对于其他分布,另请参见广义版本,即两个分布之间的 Hellinger 距离。

我不知道有任何库可以计算这个,但考虑到马氏距离和方差矩阵行列式的明确表述,实现应该不是问题。

我不知道是否有明显的标准方法可以做到这一点,但是:

首先,您找到两个密度之间的交点。这可以通过使两个密度相等来轻松实现,对于正态分布,这应该导致 x 的二次方程。

接近于:

(xμ2)22σ22(xμ1)22σ12=logσ1σ2

这可以用基本的微积分来解决。

因此,您有零个、一个或两个交点。现在,这些交点将实线分成 1、2 或三个部分,其中两个密度中的任何一个是最低的。如果没有更多的数学概念浮现在脑海中,只需尝试其中一个部分中的任何一点,找出哪一个是最低的。

您感兴趣的值现在是每个部分中最低密度曲线下面积的总和。现在可以从累积分布函数中找到该区域(只需减去“部分”两侧的值。

对于后人来说,wolfgang 的解决方案对我不起作用——我在integrate函数中遇到了错误。因此,我将其与 Nick Staubbe 的答案结合起来开发了以下小功能。应该比使用数值积分更快且错误更少:

get_overlap_coef <- function(mu1, mu2, sd1, sd2){
  xs  <- seq(min(mu1 - 4*sd1, mu2 - 4*sd2), 
             max(mu1 + 4*sd1, mu2 + 4*sd2), 
             length.out = 500)
  f1  <- dnorm(xs, mean=mu1, sd=sd1)
  f2  <- dnorm(xs, mean=mu2, sd=sd2)
  int <- xs[which.max(pmin(f1, f2))]
  l   <- pnorm(int, mu1, sd1, lower.tail = mu1>mu2)
  r   <- pnorm(int, mu2, sd2, lower.tail = mu1<mu2)
  l+r
}