Una medida de "uniformidad" estándar, poderosa, bien entendida, teóricamente bien establecida y frecuentemente implementada es la función Ripley K y su pariente cercano, la función L. Aunque normalmente se usan para evaluar configuraciones de puntos espaciales bidimensionales, el análisis necesario para adaptarlas a una dimensión (que generalmente no se da en las referencias) es simple.
Teoría
La función K estima la proporción media de puntos dentro de una distancia de un punto típico. Para una distribución uniforme en el intervalo [ 0 , 1 ] , la proporción real se puede calcular y (asintóticamente en el tamaño de la muestra) es igual a 1 - ( 1 - d ) 2 . La versión unidimensional apropiada de la función L resta este valor de K para mostrar desviaciones de la uniformidad. Por lo tanto, podríamos considerar normalizar cualquier lote de datos para tener un rango de unidades y examinar su función L para detectar desviaciones alrededor de cero.d[0,1]1−(1−d)2
Ejemplos trabajados
Para ilustrar , he simulado muestras independientes de tamaño 64 a partir de una distribución uniforme y tracé sus funciones L (normalizadas) para distancias más cortas (desde99964 a 1 / 3 ), creando así un sobre para estimar la distribución de muestreo de la función L. (Los puntos trazados dentro de este sobre no se pueden distinguir significativamente de la uniformidad). Sobre esto, he trazado las funciones L para muestras del mismo tamaño de una distribución en forma de U, una distribución de mezcla con cuatro componentes obvios y una distribución Normal estándar. Los histogramas de estas muestras (y de sus distribuciones principales) se muestran como referencia, utilizando símbolos de línea para que coincidan con los de las funciones L.01/3
Los agudos picos separados de la distribución en forma de U (línea roja discontinua, histograma más a la izquierda) crean grupos de valores muy cercanos. Esto se refleja en una pendiente muy grande en la función L en . La función L luego disminuye, llegando a ser negativa para reflejar los espacios a distancias intermedias.0
La muestra de la distribución normal (línea azul continua, histograma de la derecha) está bastante cerca de la distribución uniforme. En consecuencia, su función L no se aparta de rápidamente. Sin embargo, por distancias de 0,1000.10 aproximadamente, se ha elevado lo suficiente por encima de la envolvente como para indicar una ligera tendencia a agruparse. El aumento continuo a través de distancias intermedias indica que el agrupamiento es difuso y generalizado (no limitado a algunos picos aislados).
La gran pendiente inicial para la muestra de la distribución de la mezcla (histograma medio) revela la agrupación a pequeñas distancias (menos de ). Al caer a niveles negativos, señala la separación a distancias intermedias. Comparar esto con la función L de la distribución en forma de U es revelador: las pendientes en 00.150 , las cantidades en que estas curvas se elevan por encima de y las tasas a las que finalmente descienden de nuevo a 0 proporcionan información sobre la naturaleza del agrupamiento presente en los datos. Cualquiera de estas características podría elegirse como una medida única de "uniformidad" para adaptarse a una aplicación particular.00
Estos ejemplos muestran cómo se puede examinar una función L para evaluar las desviaciones de los datos de la uniformidad ("uniformidad") y cómo se puede extraer de ella información cuantitativa sobre la escala y la naturaleza de las desviaciones.
(De hecho, se puede trazar la función L completa, extendiéndose a la distancia normalizada completa de , para evaluar las desviaciones a gran escala de la uniformidad. Sin embargo, ordinariamente, evaluar el comportamiento de los datos a distancias más pequeñas es de mayor importancia).1
Software
R
código para generar esta figura sigue. Comienza definiendo funciones para calcular K y L. Crea una capacidad para simular a partir de una distribución de mezcla. Luego genera los datos simulados y hace los gráficos.
Ripley.K <- function(x, scale) {
# Arguments:
# x is an array of data.
# scale (not actually used) is an option to rescale the data.
#
# Return value:
# A function that calculates Ripley's K for any value between 0 and 1 (or `scale`).
#
x.pairs <- outer(x, x, function(a,b) abs(a-b)) # All pairwise distances
x.pairs <- x.pairs[lower.tri(x.pairs)] # Distances between distinct pairs
if(missing(scale)) scale <- diff(range(x.pairs))# Rescale distances to [0,1]
x.pairs <- x.pairs / scale
#
# The built-in `ecdf` function returns the proportion of values in `x.pairs` that
# are less than or equal to its argument.
#
return (ecdf(x.pairs))
}
#
# The one-dimensional L function.
# It merely subtracts 1 - (1-y)^2 from `Ripley.K(x)(y)`.
# Its argument `x` is an array of data values.
#
Ripley.L <- function(x) {function(y) Ripley.K(x)(y) - 1 + (1-y)^2}
#-------------------------------------------------------------------------------#
set.seed(17)
#
# Create mixtures of random variables.
#
rmixture <- function(n, p=1, f=list(runif), factor=10) {
q <- ceiling(factor * abs(p) * n / sum(abs(p)))
x <- as.vector(unlist(mapply(function(y,f) f(y), q, f)))
sample(x, n)
}
dmixture <- function(x, p=1, f=list(dunif)) {
z <- matrix(unlist(sapply(f, function(g) g(x))), ncol=length(f))
z %*% (abs(p) / sum(abs(p)))
}
p <- rep(1, 4)
fg <- lapply(p, function(q) {
v <- runif(1,0,30)
list(function(n) rnorm(n,v), function(x) dnorm(x,v), v)
})
f <- lapply(fg, function(u) u[[1]]) # For random sampling
g <- lapply(fg, function(u) u[[2]]) # The distribution functions
v <- sapply(fg, function(u) u[[3]]) # The parameters (for reference)
#-------------------------------------------------------------------------------#
#
# Study the L function.
#
n <- 64 # Sample size
alpha <- beta <- 0.2 # Beta distribution parameters
layout(matrix(c(rep(1,3), 3, 4, 2), 2, 3, byrow=TRUE), heights=c(0.6, 0.4))
#
# Display the L functions over an envelope for the uniform distribution.
#
plot(c(0,1/3), c(-1/8,1/6), type="n",
xlab="Normalized Distance", ylab="Total Proportion",
main="Ripley L Functions")
invisible(replicate(999, {
plot(Ripley.L(x.unif <- runif(n)), col="#00000010", add=TRUE)
}))
abline(h=0, lwd=2, col="White")
#
# Each of these lines generates a random set of `n` data according to a specified
# distribution, calls `Ripley.L`, and plots its values.
#
plot(Ripley.L(x.norm <- rnorm(n)), col="Blue", lwd=2, add=TRUE)
plot(Ripley.L(x.beta <- rbeta(n, alpha, beta)), col="Red", lwd=2, lty=2, add=TRUE)
plot(Ripley.L(x.mixture <- rmixture(n, p, f)), col="Green", lwd=2, lty=3, add=TRUE)
#
# Display the histograms.
#
n.breaks <- 24
h <- hist(x.norm, main="Normal Sample", breaks=n.breaks, xlab="Value")
curve(dnorm(x)*n*mean(diff(h$breaks)), add=TRUE, lwd=2, col="Blue")
h <- hist(x.beta, main=paste0("Beta(", alpha, ",", beta, ") Sample"),
breaks=n.breaks, xlab="Value")
curve(dbeta(x, alpha, beta)*n*mean(diff(h$breaks)), add=TRUE, lwd=2, lty=2, col="Red")
h <- hist(x.mixture, main="Mixture Sample", breaks=n.breaks, xlab="Value")
curve(dmixture(x, p, g)*n*mean(diff(h$breaks)), add=TRUE, lwd=2, lty=3, col="Green")