¿Cómo calcular la superposición entre densidades de probabilidad empírica?


14

Estoy buscando un método para calcular el área de superposición entre dos estimaciones de densidad del núcleo en R, como una medida de similitud entre dos muestras. Para aclarar, en el siguiente ejemplo, necesitaría cuantificar el área de la región superpuesta púrpura:

library(ggplot2)
set.seed(1234)
d <- data.frame(variable=c(rep("a", 50), rep("b", 30)), value=c(rnorm(50), runif(30, 0, 3)))
ggplot(d, aes(value, fill=variable)) + geom_density(alpha=.4, color=NA)

ingrese la descripción de la imagen aquí

Aquí se discutió una pregunta similar , la diferencia es que necesito hacer esto para datos empíricos arbitrarios en lugar de distribuciones normales predefinidas. El overlappaquete aborda esta pregunta, pero aparentemente solo para datos de marca de tiempo, que no funciona para mí. El índice Bray-Curtis (como se implementa en veganla vegdist(method="bray")función del paquete ) también parece relevante, pero nuevamente para datos algo diferentes.

Estoy interesado tanto en el enfoque teórico como en las funciones R que podría emplear para implementarlo.


2
"cuantificar el área púrpura" es un problema en la estimación, no en la prueba de hipótesis, por lo que no puede esperar "lograr esto usando una prueba estadística citable estándar ". Te contradices a ti mismo. Por favor aclare lo que realmente quiere. Si todo lo que desea es una estimación del área de superposición de dos KDE, es un cálculo simple.
Glen_b -Reinstale a Monica

@Glen_b gracias por el comentario, ayudó a aclarar mi pensamiento no estadístico. Creo que el área de superposición entre KDEs es lo que estoy buscando, he editado la pregunta para reflejar eso.
mmk

2
Me preocuparía mucho el riesgo de arbitrariedad en este método. Dependiendo del ancho de banda del núcleo, el solapamiento calculada entre los dos conjuntos de datos se podría hacer para igualar cualquier valor elegido en el intervalo . Los anchos de banda predeterminados no están optimizados para este propósito y, por lo tanto, posiblemente podrían dar resultados sorprendentes, arbitrarios o inconsistentes. Los conjuntos de datos con límites naturales (como datos o proporciones no negativas, etc.) introducirían aún más efectos de borde no deseados. ¿Qué hacer en su lugar? Comience con la razón de este cálculo: ¿qué significa esta "similitud"? (0 0,1)
whuber

La misma pregunta apareció unos meses más tarde, pero se refería a los puntos de intersección, sin embargo, hubo algunas notas válidas que podrían tenerse en cuenta. En la pregunta referida se trata de dos distribuciones empíricas. Agrego el enlace ya que esta publicación solo responde esto a través de la estimación de densidad del kernel y para distribuciones normales. El siguiente enlace, creo, se extiende sobre la cuestión de los pares de distribuciones empíricas. stats.stackexchange.com/questions/122857/… - Barnaby Hace 7 horas
Barnaby

Respuestas:


9

El área de superposición de dos estimaciones de densidad de grano puede aproximarse a cualquier grado de precisión deseado.

1) Dado que los KDE originales probablemente se han evaluado en alguna cuadrícula, si la cuadrícula es la misma para ambos (o se puede hacer fácilmente lo mismo), el ejercicio podría ser tan fácil como simplemente tomar en cada punto y luego usando la regla trapezoidal, o incluso una regla de punto medio.min(K1(X),K2(X))

Si los dos están en cuadrículas diferentes y no se pueden volver a calcular fácilmente en la misma cuadrícula, se podría utilizar la interpolación.

2) Puede encontrar el punto (o puntos) de intersección e integrar el más bajo de los dos KDE en cada intervalo donde cada uno es más bajo. En su diagrama anterior, integraría la curva azul a la izquierda de la intersección y la rosa a la derecha por cualquier medio que desee / tenga disponible. Esto puede hacerse esencialmente exactamente considerando el área debajo de cada componente del núcleo a la izquierda o derecha de ese punto de corte.1hK(X-Xyoh)

Sin embargo , los comentarios anteriores de Whuber deben tenerse claramente en cuenta; esto no es necesariamente algo muy significativo.


¿Cómo se calcula el error asociado con el método uno y el método 2?
olliepower

En circunstancias normales, ambos serán minúsculos en comparación con el error en las estimaciones de densidad del núcleo, por lo que no me preocuparía demasiado. Los límites de error se pueden calcular con métodos trapezoidales y otras integraciones numéricas, por supuesto, tales cálculos son bastante estándar, pero no tiene sentido preocuparse dado que los KDE tienen grandes incertidumbres. El método 2 será exacto al error de redondeo acumulado de los cálculos.
Glen_b -Reinstale a Monica

1
Estas sugerencias metodológicas tienen sentido, muchas gracias por su respuesta. Trabajaré para implementar esto en R, pero como novato me interesarían sugerencias sobre cómo codificar esto limpiamente.
mmk

10

En aras de la exhaustividad, así es como terminé haciendo esto en R:

# simulate two samples
a <- rnorm(100)
b <- rnorm(100, 2)

# define limits of a common grid, adding a buffer so that tails aren't cut off
lower <- min(c(a, b)) - 1 
upper <- max(c(a, b)) + 1

# generate kernel densities
da <- density(a, from=lower, to=upper)
db <- density(b, from=lower, to=upper)
d <- data.frame(x=da$x, a=da$y, b=db$y)

# calculate intersection densities
d$w <- pmin(d$a, d$b)

# integrate areas under curves
library(sfsmisc)
total <- integrate.xy(d$x, d$a) + integrate.xy(d$x, d$b)
intersection <- integrate.xy(d$x, d$w)

# compute overlap coefficient
overlap <- 2 * intersection / total

Como se señaló, existe una incertidumbre y subjetividad inherentes en la generación de KDE y también en la integración.


2
Ahora hay un paquete en CRAN llamado overlappingque estima el área de la superposición de 2 (o más) distribuciones empíricas. Consulte la documentación aquí: rdocumentation.org/packages/overlapping/versions/1.5.0/topics/…
Stefan Avey

Total debe ser: total = integrar.xy (d a) + integrar.xy (d b) --integra.xy (d w), que puede confirmarse mediante la superposición del paquete. X,reX,reX,re
Rafael

@mmk, ¿puedes hacer esto para densidades 2D?
No Lie

4

Primero, podría estar equivocado, pero creo que su solución no funcionaría en caso de que haya múltiples puntos en los que se cruzan las Estimaciones de densidad del núcleo (KDE). En segundo lugar, aunque el overlappaquete se creó para usar con datos de marca de tiempo, aún puede usarlo para estimar el área de superposición de dos KDE. Simplemente tiene que reescalar sus datos para que oscilen entre 0 y 2π.
Por ejemplo :

# simulate two sample    
 a <- rnorm(100)
 b <- rnorm(100, 2)

# To use overplapTrue(){overlap} the scale must be in radian (i.e. 0 to 2pi)
# To keep the *relative* value of a and b the same, combine a and b in the
# same dataframe before rescaling. You'll need to load the ‘scales‘ library.
# But first add a "Source" column to be able to distinguish between a and b
# after they are combined.
 a = data.frame( value = a, Source = "a" )
 b = data.frame( value = b, Source = "b" )
 d = rbind(a, b)
 library(scales) 
 d$value <- rescale( d$value, to = c(0,2*pi) )

# Now you can created the rescaled a and b vectors
 a <- d[d$Source == "a", 1]
 b <- d[d$Source == "b", 1]

# You can then calculate the area of overlap as you did previously.
# It should give almost exactly the same answers.
# Or you can use either the overlapTrue() and overlapEst() function 
# provided with the overlap packages. 
# Note that with these function the KDE are fitted using von Mises kernel.
 library(overlap)
  # Using overlapTrue():
   # define limits of a common grid, adding a buffer so that tails aren't cut off
     lower <- min(d$value)-1 
     upper <- max(d$value)+1
   # generate kernel densities
     da <- density(a, from=lower, to=upper, adjust = 1)
     db <- density(b, from=lower, to=upper, adjust = 1)
   # Compute overlap coefficient
     overlapTrue(da$y,db$y)


  # Using overlapEst():            
    overlapEst(a, b, kmax = 3, adjust=c(0.8, 1, 4), n.grid = 500)

# You can also plot the two KDEs and the region of overlap using overlapPlot()
# but sadly I haven't found a way of changing the x scale so that the scale 
# range correspond to the initial x value and not the rescaled value.
# You can only change the maximum value of the scale using the xscale argument 
# (i.e. it always range from 0 to n, where n is set with xscale = n).
# So if some of your data take negative value, you're probably better off with
# a different plotting method. You can change the x label with the xlab
# argument.  
  overlapPlot(a, b, xscale = 10, xlab= "x metrics", rug=T)
Al usar nuestro sitio, usted reconoce que ha leído y comprende nuestra Política de Cookies y Política de Privacidad.
Licensed under cc by-sa 3.0 with attribution required.