Відсоток областей перекриття двох нормальних розподілів


46

Мені було цікаво, враховуючи два звичайних розподілу з таσ1, μ1σ2, μ2

  • як я можу обчислити відсоток перекриваються областей двох розподілів?
  • Я думаю, ця проблема має конкретну назву, чи знаєте ви якесь конкретне ім’я, що описує цю проблему?
  • Чи знаєте ви про будь-яку реалізацію цього (наприклад, Java-коду)?

2
Що ви маєте на увазі під регіоном, що перекривається? Ви маєте на увазі площу, що знаходиться нижче обох кривих щільності?
Нік Саббе

Я маю на увазі перехрестя двох районів
Алі Салехі

4
Коротше кажучи, записуючи два pdfs як і , ви дійсно хочете обчислити ? Не могли б ви просвітити нас про контекст, в якому це виникає, і як це було б трактуватися? fgmin(f(x),g(x))dx
whuber

Відповіді:


41

Це також часто називають "коефіцієнтом перекриття" (OVL). Гугл для цього дасть вам безліч влучень. Ви можете знайти номограму для бі-нормального випадку тут . Корисним документом може бути:

  • Генрі Ф. Інман; Едвін Л. Бредлі-молодший (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.6099324з абсолютною помилкою < 1e-04. Малюнок нижче.

Приклад


10
(+1) Гуглінг містить як мінімум три чіткі визначення (Мацусіта, Морісіта та Вайцман). Ваша реалізація - Вайцман.
whuber

1
0.60993 24 - це наближення для 0.60993 43398 78944 33895 ....
whuber

10

Це дано коефіцієнтом Бхаттачарія . Для інших розподілів див. Також узагальнену версію відстані Хеллінгера між двома розподілами.

Я не знаю жодної бібліотеки, яка б це обчислила, але з огляду на чітке формулювання з точки зору відстаней Mahalanobis та детермінантних дисперсійних матриць реалізація не повинна бути проблемою.


3
Коефіцієнт Бхаттачарія - це міра перекриття, але це не однаково, чи не так?
Стефан Лоран

7

Я не знаю, чи існує очевидний стандартний спосіб цього зробити, але:

Спочатку ви знаходите точки перетину між двома густинами. Це можна легко досягти шляхом рівняння обох густин, що при нормальному розподілі має призвести до квадратичного рівняння для x.

Щось близьке до:

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

Це можна вирішити за допомогою базового обчислення.

Таким чином, у вас є або нуль, одна або дві точки перетину. Тепер ці точки перетину ділять дійсну пряму на 1, 2 або три частини, де будь-яка з двох густин є найнижчою. Якщо нічого більш математичного не спадає на думку, просто спробуйте будь-яку точку в одній із частин, щоб знайти, яка з них є найнижчою.

Ваша цінність зараз - це сума площ під кривою найменшої щільності в кожній частині. Цю область тепер можна знайти з функції кумулятивного розподілу (просто відніміть значення в обох краях 'частини').


4
(+1) Насправді, коли , рівняння можна вирішити за допомогою квадратичної формули: немає необхідності в обчисленні. Якщо ми організуємо (wlg) для , то друга щільність найменша між двома нулями, інакше перша щільність найменша. Це зводить обчислення до чотирьох оцінок Нормального КНД. Ситуація з ще простіша, вимагаючи рішення лінійного рівняння та лише двох оцінок CDF. σ1σ2μ1μ2σ1=σ2
whuber

2
@whuber Чи можете ви перетворити це на повну відповідь? А може, Нік може редагувати його.
Олександр Дубінський

@whuber Ви не мали на увазі а не ? σ1σ2μ1μ2
Стефан Лоран

@ Stéphane Я думаю, ви правильні, що SD визначають порядок: щільність з меншими SD з часом матиме менші хвости як у позитивному, так і в негативному напрямках, і тому буде більше значень між нулями та меншими значеннями в інших місцях.
whuber

@whuber Так, і дійсно легко помітити, що порядок SD визначає ознаку коефіцієнта 2-го порядку полінома, похідного Ніком.
Стефан Лоран

1

Для нащадків рішення вольфганга не спрацювало для мене - я зіткнувся з помилками у integrateфункції. Тож я поєднав це з відповіддю Ніка Стаубе, щоб розробити наступну маленьку функцію. Має бути швидше і менш баггі, ніж використання числової інтеграції:

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 :

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) 

Принаймні, я міг би відтворити значення 0.8026, наведене нижче на фіг.1, у цьому PDF .

Вам потрібно просто адаптувати значення початку та кінця та інтервалу, щоб бути точними, оскільки це лише числове рішення.

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.