50 votos

Porcentaje de regiones superpuestas de dos distribuciones normales

Me preguntaba, dadas dos distribuciones normales con $\sigma_1,\ \mu_1$ y $\sigma_2, \ \mu_2$

  • ¿cómo puedo calcular el porcentaje de regiones superpuestas de dos distribuciones?
  • Supongo que este problema tiene un nombre específico, ¿conoces algún nombre concreto que describa este problema?
  • ¿Conoce alguna implementación de esto (por ejemplo, código Java)?

2 votos

¿A qué se refiere con lo de la región superpuesta? ¿Se refiere a la zona que está por debajo de ambas curvas de densidad?

0 votos

Me refiero a la intersección de dos áreas

5 votos

En resumen, escribir los dos pdfs como $f$ y $g$ ¿realmente quieres calcular $\int \min(f(x),g(x))dx$ ? ¿Podría aclararnos el contexto en el que surge y cómo se interpretaría?

44voto

Derek Swingley Puntos 3851

También se suele llamar "coeficiente de solapamiento" (OVL). Si buscas esto en Google, encontrarás muchos resultados. Puedes encontrar un nomograma para el caso binario aquí . Un documento útil puede ser:

  • Henry F. Inman; Edwin L. Bradley Jr (1989). The overlapping coefficient as a measure of agreement between probability distributions and point estimation of the overlap of two normal densities. Communications in Statistics - Theory and Methods, 18(10), 3851-3874. ( Enlace )

Editar

Ahora me has hecho interesarme más por esto, así que me he adelantado y he creado un código en R para calcular esto (es una integración sencilla). He puesto un gráfico de las dos distribuciones, incluyendo 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.6099324 con error absoluto < 1e-04 . Figura inferior.

Example

11voto

Patrick Puntos 183

Esto viene dado por el Coeficiente Bhattacharyya . Para otras distribuciones, véase 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 determinantes de matrices de varianza, la implementación no debería ser un problema.

3 votos

El coeficiente de Bhattacharyya es una medida de solapamiento, pero no es lo mismo, ¿verdad?

7voto

pkaeding Puntos 12935

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

En primer lugar, se encuentran los puntos de intersección entre las dos densidades. Esto se puede conseguir fácilmente igualando ambas densidades, lo que, para la distribución normal, debería dar como resultado una ecuación cuadrática para x.

Algo parecido: $$ \frac{(x-\mu_2)^2}{2\sigma_2^2} - \frac{(x-\mu_1)^2}{2\sigma_1^2} = \log{\frac{\sigma_1}{\sigma_2}} $$

Esto se puede resolver con un 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 se te ocurre nada más matemático, simplemente prueba con cualquier punto dentro de una de las partes para encontrar cuál es la más baja.

Su valor de interés es ahora la suma de las áreas bajo la curva de menor densidad en cada parte. Esta área se puede encontrar ahora a partir de la función de distribución acumulativa (sólo hay que restar el valor en ambos bordes de la "parte".

1voto

generic_user Puntos 2269

Para la posteridad, la solución de wolfgang no me funcionó, me encontré con errores en el integrate función. Así que la combiné con la respuesta de Nick Staubbe para desarrollar la siguiente pequeña función. Debería ser más rápida 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
}

0 votos

No debería volver (l+r)/2 ?

0voto

futureelite7 Puntos 6247

Creo que algo así 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 he podido reproducir el valor 0,8026 que aparece en la Fig.1 en este pdf .

Sólo hay que adaptar los valores de inicio y final y el intervalo para que sean precisos, ya que sólo se trata de una solución numérica.

i-Ciencias.com

I-Ciencias es una comunidad de estudiantes y amantes de la ciencia en la que puedes resolver tus problemas y dudas.
Puedes consultar las preguntas de otros usuarios, hacer tus propias preguntas o resolver las de los demás.

Powered by:

X