Persentase wilayah yang tumpang tindih dari dua distribusi normal

46

Saya bertanya-tanya, mengingat dua distribusi normal dengan σ1, μ1 dan σ2, μ2

  • bagaimana saya bisa menghitung persentase daerah yang tumpang tindih dari dua distribusi?
  • Saya kira masalah ini memiliki nama tertentu, apakah Anda mengetahui adanya nama tertentu yang menjelaskan masalah ini?
  • Apakah Anda mengetahui adanya implementasi ini (misalnya, kode Java)?
Ali Salehi
sumber
2
Apa yang Anda maksud dengan wilayah yang tumpang tindih? Apakah maksud Anda area yang di bawah kedua kurva kepadatan?
Nick Sabbe
Maksud saya persimpangan dua area
Ali Salehi
4
fgmin(f(x),g(x))dx

Jawaban:

41

Ini juga sering disebut "koefisien tumpang tindih" (OVL). Googling untuk ini akan memberi Anda banyak hits. Anda dapat menemukan nomogram untuk kasus bi-normal di sini . Makalah yang bermanfaat mungkin:

  • Henry F. Inman; Edwin L. Bradley Jr (1989). Koefisien yang tumpang tindih sebagai ukuran kesepakatan antara distribusi probabilitas dan estimasi titik tumpang tindih dua kepadatan normal. Komunikasi dalam Statistik - Teori dan Metode, 18 (10), 3851-3874. ( Tautan )

Sunting

Sekarang Anda membuat saya lebih tertarik pada ini, jadi saya melanjutkan dan membuat kode R untuk menghitung ini (ini adalah integrasi sederhana). Saya melemparkan sebidang dari dua distribusi, termasuk naungan wilayah yang tumpang tindih:

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)

Untuk contoh ini, hasilnya adalah: 0.6099324dengan kesalahan absolut < 1e-04. Gambar di bawah ini.

Contoh

Wolfgang
sumber
10
(+1) Googling memunculkan setidaknya tiga definisi berbeda (Matsushita, Morisita, dan Weitzman). Implementasi Anda adalah Weitzman.
whuber
1
0,60993 24 adalah perkiraan untuk 0,60993 43398 78944 33895 ....
whuber
10

Ini diberikan oleh koefisien Bhattacharyya . Untuk distribusi lain, lihat juga versi umum, jarak Hellinger antara dua distribusi.

Saya tidak tahu ada perpustakaan untuk menghitung ini, tetapi mengingat formulasi eksplisit dalam hal jarak Mahalanobis dan penentu matriks varian, implementasi seharusnya tidak menjadi masalah.

pengguna603
sumber
3
Koefisien Bhattacharyya adalah ukuran tumpang tindih tetapi tidak sama, bukan?
Stéphane Laurent
7

Saya tidak tahu apakah ada cara standar yang jelas untuk melakukan ini, tetapi:

Pertama, Anda menemukan titik persimpangan antara dua kepadatan. Ini dapat dengan mudah dicapai dengan menyamakan kedua kepadatan, yang, untuk distribusi normal, harus menghasilkan persamaan kuadrat untuk x.

Sesuatu yang dekat dengan:

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

Ini dapat diselesaikan dengan kalkulus dasar.

Dengan demikian Anda memiliki nol, satu atau dua titik persimpangan. Sekarang, titik persimpangan ini membagi garis nyata menjadi 1, 2 atau tiga bagian, di mana salah satu dari dua kepadatan adalah yang terendah. Jika tidak ada yang lebih matematis yang terlintas dalam pikiran, coba saja titik mana saja dalam salah satu bagian untuk menemukan mana yang terendah.

Nilai bunga Anda sekarang adalah jumlah area di bawah kurva kepadatan terendah di setiap bagian. Area ini sekarang dapat ditemukan dari fungsi distribusi kumulatif (cukup kurangi nilai di kedua tepi 'bagian'.

Nick Sabbe
sumber
4
(+1) Sebenarnya, ketika , persamaan dapat diselesaikan dengan rumus kuadrat: tidak perlu untuk kalkulus. Jika kita mengatur (wlg) untuk , maka kerapatan kedua adalah yang terkecil di antara dua nol dan sebaliknya kerapatan pertama adalah yang terkecil. Ini mengurangi perhitungan menjadi empat evaluasi CDF Normal. Situasi dengan bahkan lebih sederhana, membutuhkan solusi persamaan linier dan hanya dua evaluasi CDF. μ 1μ 2 σ 1 = σ 2σ1σ2μ1μ2σ1=σ2
whuber
2
@whuber Bisakah Anda mengubah ini menjadi jawaban yang lengkap? Atau mungkin Nick bisa mengeditnya.
Aleksandr Dubinsky
@whuber Bukankah maksudmu daripada ? μ 1μ 2σ1σ2μ1μ2
Stéphane Laurent
@ Stéphane Saya pikir Anda benar bahwa SD menentukan urutan: kepadatan dengan SD yang lebih kecil pada akhirnya akan memiliki ekor yang lebih kecil di kedua arah positif dan negatif dan karena itu akan memiliki nilai yang lebih besar antara nol dan nilai yang lebih kecil di tempat lain.
whuber
@whuber Ya, dan memang mudah untuk melihat bahwa urutan SD menentukan tanda koefisien urutan kedua dari polinom yang diturunkan oleh Nick.
Stéphane Laurent
1

Sebagai anak cucu, solusi wolfgang tidak bekerja untuk saya — saya menemui bug dalam integratefungsi. Jadi saya mengombinasikannya dengan jawaban Nick Staubbe untuk mengembangkan fungsi kecil berikut. Seharusnya lebih cepat dan lebih tidak buggy daripada menggunakan integrasi numerik:

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
}
generic_user
sumber
tidakkah itu seharusnya kembali (l+r)/2?
RSHAP
0

Ini adalah versi Java, Perpustakaan Matematika Apache Commons :

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;

}
Vithun Venugopalan
sumber
0

Saya pikir sesuatu seperti ini bisa menjadi solusi di 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) 

Setidaknya saya bisa mereproduksi nilai 0,8026 yang diberikan di bawah ini Gambar 1 di pdf ini .

Anda hanya perlu menyesuaikan nilai awal dan akhir dan interval agar tepat karena ini hanya solusi numerik.

Danny K.
sumber