2つの正規分布の重複領域の割合


46

と 2つの正規分布をσ 2μ 2σ1, μ1σ2, μ2

  • 2つの分布の重複領域の割合を計算するにはどうすればよいですか?
  • この問題には特定の名前があると思いますが、この問題を説明する特定の名前を知っていますか?
  • この実装(Javaコードなど)を知っていますか?

2
重複領域とはどういう意味ですか?両方の密度曲線の下にある面積を意味しますか?
ニックサブベ

2つのエリアの交差点
アリサレヒ

4
要するに、2つのpdfをととして記述して、本当にを計算しますか?これが発生するコンテキストと、それがどのように解釈されるかについて教えてください。fgmin(f(x),g(x))dx
whuber

回答:


41

これは「オーバーラップ係数」(OVL)とも呼ばれます。これをグーグルで検索すると、多くのヒットが得られます。ここで双正規の場合のノモグラムを見つけることができます。役に立つ論文は次のとおりです。

  • ヘンリー・F・インマン; エドウィン・L・ブラッドリー・ジュニア(1989)。確率分布と2つの正規密度の重なりの点推定間の一致の尺度としての重なり係数。統計におけるコミュニケーション-理論と方法、18(10)、3851-3874。(リンク

編集

今、あなたはこれにもっと興味を持ったので、先に進み、これを計算するためのRコードを作成しました(単純な統合です)。重複領域の陰影を含む2つの分布のプロットを投げました。

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.6099324なります:with absolute error < 1e-04。下の図。

例


10
(+1)グーグルは、少なくとも3つの異なる定義(松下、森下、およびワイツマン)になります。あなたの実装はWeitzmanのものです。
whuber

1
0.60993 24は、0.60993 43398 78944 33895 ...の近似値です。
whuber

10

これはBhattacharyya係数によって与えられます。他の分布については、一般化バージョンである2つの分布間のHellinger距離も参照してください。

これを計算するライブラリは知りませんが、マハラノビス距離と分散行列式に関する明示的な定式化を考えると、実装は問題になりません。


3
Bhattacharyya係数はオーバーラップの尺度ですが、同じではありませんか?
ステファンローラン

7

これを行うための明白な標準的な方法があるかどうかはわかりませんが、:

まず、2つの密度の交点を見つけます。これは、両方の密度を等しくすることで簡単に実現できます。これは、正規分布の場合、xの2次方程式になるはずです。

何かに近い:

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

これは基本的な計算で解決できます。

したがって、0、1、または2つの交点があります。現在、これらの交点は実際の線を1、2、または3つの部分に分割します。2つの密度のいずれかが最も低い密度です。これ以上数学的なことが思いつかない場合は、いずれかの部分内の任意のポイントを試して、どれが最も低いかを見つけてください。

関心のある値は、各部分の最低密度曲線の下の面積の合計です。この領域は、累積分布関数から見つけることができます(「パーツ」の両端の値を減算するだけです)。


4
(+1)実際、場合、方程式は二次式で解くことができます:計算の必要はありません。に(wlg)を配置すると、2番目の密度は2つのゼロの間で最小になり、それ以外の場合は最初の密度が最小になります。これにより、計算がNormal CDFの4つの評価に削減されます。の状況はさらに単純であり、線形方程式の解とCDFの2回の評価のみが必要です。σ1σ2μ1μ2σ1=σ2
whuber

2
@whuberこれを完全な答えに変えることができますか?または、ニックが編集することもできます。
アレクサンドルドゥビンスキー

@whuberではなく、を意味していませんか?σ1σ2μ1μ2
ステファンローラン

@StéphaneSDが順序を決定するのは正しいと思います:小さいSDの密度は、最終的に正と負の両方の方向に小さいテールを持ち、したがって、ゼロと他の小さな値の間の値が大きくなります。
whuber

@whuberはい、実際、SDの次数がニックによって導出された多項式の2次係数の符号を決定することは簡単にわかります。
ステファンローラン

1

後世のために、ウルフギャングのソリューションは私にとってはうまくいきませんでした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
}

戻らないの(l+r)/2
RSHAP

0

JavaバージョンのApache Commons Mathematics Libraryは次のとおりです。

import org.apache.commons.math3.distribution.NormalDistribution;

public static double overlapArea(double mean1, double sd1, double mean2, double sd2) {

    NormalDistribution normalDistribution1 = new NormalDistribution(mean1, sd1);
    NormalDistribution normalDistribution2 = new NormalDistribution(mean2, sd2);

    double min = Math.min(mean1 - 6 * sd1, mean2 - 6 * sd2);
    double max = Math.max(mean1 + 6 * sd1, mean2 + 6 * sd2);
    double range = max - min;

    int resolution = (int) (range/Math.min(sd1, sd2));

    double partwidth = range / resolution;

    double intersectionArea = 0;

    int begin = (int)((Math.max(mean1 - 6 * sd1, mean2 - 6 * sd2)-min)/partwidth);
    int end = (int)((Math.min(mean1 + 6 * sd1, mean2 + 6 * sd2)-min)/partwidth);

    /// Divide the range into N partitions
    for (int ii = begin; ii < end; ii++) {

        double partMin = partwidth * ii;
        double partMax = partwidth * (ii + 1);

        double areaOfDist1 = normalDistribution1.probability(partMin, partMax);
        double areaOfDist2 = normalDistribution2.probability(partMin, partMax);

        intersectionArea += Math.min(areaOfDist1, areaOfDist2);
    }

    return intersectionArea;

}

0

このような何かがMATLABの解決策になると思います:

[overlap] = calc_overlap_twonormal(2,2,0,1,-20,20,0.01)

% numerical integral of the overlapping area of two normal distributions:
% s1,s2...sigma of the normal distributions 1 and 2
% mu1,mu2...center of the normal distributions 1 and 2
% xstart,xend,xinterval...defines start, end and interval width
% example: [overlap] = calc_overlap_twonormal(2,2,0,1,-10,10,0.01)

function [overlap2] = calc_overlap_twonormal(s1,s2,mu1,mu2,xstart,xend,xinterval)

clf
x_range=xstart:xinterval:xend;
plot(x_range,[normpdf(x_range,mu1,s1)' normpdf(x_range,mu2,s2)']);
hold on
area(x_range,min([normpdf(x_range,mu1,s1)' normpdf(x_range,mu2,s2)']'));
overlap=cumtrapz(x_range,min([normpdf(x_range,mu1,s1)' normpdf(x_range,mu2,s2)']'));
overlap2 = overlap(end);

[overlap] = calc_overlap_twonormal(2,2,0,1,-10,10,0.01) 

少なくとも、このpdfの図1の下に示されている値0.8026を再現できました。

これは単なる数値解であるため、開始値と終了値、間隔値を正確に調整する必要があります。

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.