Porcentaje de regiones superpuestas de dos distribuciones normales

46

Me preguntaba, dadas dos distribuciones normales con y \ sigma_2, \ \ mu_2σ1, μ1σ2, μ2

  • ¿Cómo puedo calcular el porcentaje de regiones superpuestas de dos distribuciones?
  • Supongo que este problema tiene un nombre específico, ¿conoce algún nombre en particular que describa este problema?
  • ¿Conoce alguna implementación de esto (por ejemplo, código Java)?
Ali Salehi
fuente
2
¿Qué quieres decir con región superpuesta? ¿Te refieres al área que está debajo de ambas curvas de densidad?
Nick Sabbe
Me refiero a la intersección de dos áreas
Ali Salehi
44
En resumen, escribiendo los dos archivos PDF como f y g , ¿realmente quieres calcular min(f(x),g(x))dx ? ¿Podría aclararnos sobre el contexto en el que surge y cómo se interpretaría?
whuber

Respuestas:

41

Esto también se llama a menudo el "coeficiente de superposición" (OVL). Buscar en Google esto te dará muchos éxitos. Puede encontrar un nomograma para el caso bi-normal aquí . Un documento útil puede ser:

  • Henry F. Inman; Edwin L. Bradley Jr (1989). El coeficiente de superposición como una medida de acuerdo entre las distribuciones de probabilidad y la estimación puntual de la superposición de dos densidades normales. Comunicaciones en Estadística - Teoría y Métodos, 18 (10), 3851-3874. ( Enlace )

Editar

Ahora me interesó más en esto, así que seguí adelante y creé el código R para calcular esto (es una integración simple). Incluí una trama de las dos distribuciones, incluido el sombreado de la región superpuesta:

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)

Para este ejemplo, el resultado es: 0.6099324con error absoluto < 1e-04. La siguiente figura.

Ejemplo

Wolfgang
fuente
10
(+1) Google muestra al menos tres definiciones distintas (Matsushita, Morisita y Weitzman). Su implementación es de Weitzman.
whuber
1
0.60993 24 es una aproximación para 0.60993 43398 78944 33895 ....
whuber
10

Esto viene dado por el coeficiente Bhattacharyya . Para otras distribuciones, vea también la versión generalizada, la distancia de Hellinger entre dos distribuciones.

No conozco ninguna biblioteca para calcular esto, pero dada la formulación explícita en términos de distancias de Mahalanobis y matrices determinantes de la varianza, la implementación no debería ser un problema.

usuario603
fuente
3
El coeficiente Bhattacharyya es una medida de superposición, pero no es lo mismo, ¿verdad?
Stéphane Laurent
7

No sé si hay una forma estándar obvia de hacer esto, pero:

Primero, encuentra los puntos de intersección entre las dos densidades. Esto se puede lograr fácilmente igualando ambas densidades, que, para la distribución normal, deberían dar como resultado una ecuación cuadrática para x.

Algo cercano a:

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

Esto se puede resolver con cálculo básico.

Por lo tanto, tiene cero, uno o dos puntos de intersección. Ahora, estos puntos de intersección dividen la línea real en 1, 2 o tres partes, donde cualquiera de las dos densidades es la más baja. Si no le viene a la mente nada más matemático, simplemente pruebe cualquier punto dentro de una de las partes para encontrar cuál es el más bajo.

Su valor de interés es ahora la suma de las áreas bajo la curva de densidad más baja en cada parte. Esta área ahora se puede encontrar a partir de la función de distribución acumulativa (solo resta el valor en ambos bordes de la 'parte'.

Nick Sabbe
fuente
44
(+1) En realidad, cuando , la ecuación se puede resolver con la fórmula cuadrática: no hay necesidad de cálculo. Si organizamos (wlg) para , entonces la segunda densidad es más pequeña entre los dos ceros y, de lo contrario, la primera densidad es más pequeña. Esto reduce el cálculo a cuatro evaluaciones de un CDF normal. La situación con es aún más simple, ya que requiere la solución de una ecuación lineal y solo dos evaluaciones de un CDF. σ1σ2μ1μ2σ1=σ2
whuber
2
@whuber ¿Podría convertir esto en una respuesta completa? O tal vez Nick pueda editar el suyo.
Aleksandr Dubinsky
@whuber ¿No quisiste decir lugar de ? σ1σ2μ1μ2
Stéphane Laurent
@ Stéphane Creo que tiene razón en que las SD determinan el orden: la densidad con una SD más pequeña eventualmente tendrá colas más pequeñas en las direcciones positiva y negativa y, por lo tanto, tendrá los valores más grandes entre los ceros y los valores más pequeños en otros lugares.
whuber
@whuber Sí, y de hecho es fácil ver que el orden de las SD determina el signo del coeficiente de segundo orden del polinom derivado de Nick.
Stéphane Laurent
1

Para la posteridad, la solución de wolfgang no funcionó para mí: me encontré con errores en la integratefunción. Así que lo combiné con la respuesta de Nick Staubbe para desarrollar la siguiente pequeña función. Debería ser más rápido y con menos errores que usar la integración numérica:

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
}
genérico_usuario
fuente
¿No debería volver (l+r)/2?
RSHAP
0

Aquí está la versión de 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;

}
Vithun Venugopalan
fuente
0

Creo que algo como esto podría ser la solución en 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) 

Al menos podría reproducir el valor 0.8026 dado debajo de la Fig.1 en este pdf .

Solo necesita adaptar los valores de inicio y final e intervalo para ser precisos ya que esto es solo una solución numérica.

Danny K
fuente