Una misura di "uniformità" standard, potente, ben compresa, teoricamente ben consolidata e frequentemente implementata è la funzione di Ripley K e il suo parente stretto, la funzione di L. Sebbene questi siano tipicamente utilizzati per valutare configurazioni di punti spaziali bidimensionali, l'analisi necessaria per adattarli a una dimensione (che di solito non è indicata nei riferimenti) è semplice.
Teoria
La funzione K stima la proporzione media di punti entro una distanza da un punto tipico. Per una distribuzione uniforme sull'intervallo [ 0 , 1 ] , la proporzione reale può essere calcolata e (asintoticamente nella dimensione del campione) uguale a 1 - ( 1 - d ) 2 . La versione unidimensionale appropriata della funzione L sottrae questo valore da K per mostrare deviazioni dall'uniformità. Potremmo quindi considerare di normalizzare qualsiasi lotto di dati per avere un intervallo di unità ed esaminare la sua funzione L per deviazioni intorno allo zero.d[0,1]1−(1−d)2
Esempi lavorati
Per illustrare , Ho simulato campioni indipendenti di dimensioni 64 da una distribuzione uniforme e tramato loro (normalizzata) funzioni L per brevi distanze (da 0 a 1 / 3 ), creando così una busta per stimare la distribuzione di campionamento della funzione L. (I punti tracciati bene all'interno di questo inviluppo non possono essere significativamente distinti dall'uniformità.) Oltre a ciò ho tracciato le funzioni L per campioni della stessa dimensione da una distribuzione a forma di U, una distribuzione della miscela con quattro componenti ovvi e una distribuzione normale standard. Gli istogrammi di questi campioni (e delle loro distribuzioni principali) sono mostrati come riferimento, usando i simboli di linea per abbinare quelli delle funzioni L.9996401/3
I picchi netti e separati della distribuzione a forma di U (linea rossa tratteggiata, istogramma più a sinistra) creano gruppi di valori ravvicinati. Ciò si riflette in una pendenza molto grande nella funzione L a . La funzione L quindi diminuisce, diventando infine negativa per riflettere gli spazi vuoti a distanze intermedie.0
Il campione della distribuzione normale (linea blu continua, istogramma più a destra) è abbastanza vicino alla distribuzione uniforme. Di conseguenza, la sua funzione L non si discosta rapidamente da . Tuttavia, a distanze di circa 0,10 , è aumentato sufficientemente al di sopra dell'inviluppo per segnalare una leggera tendenza a raggrupparsi. Il continuo aumento su distanze intermedie indica che il clustering è diffuso e diffuso (non limitato ad alcuni picchi isolati).00.10
La grande pendenza iniziale per il campione dalla distribuzione della miscela (istogramma medio) rivela il raggruppamento a piccole distanze (meno di ). Scendendo a livelli negativi, segnala la separazione a distanze intermedie. Confrontarlo con la funzione L della distribuzione a forma di U è rivelatore: le pendenze a 0 , gli importi con cui queste curve salgono al di sopra di 0 e le velocità con cui alla fine scendono di nuovo a 0 forniscono tutte informazioni sulla natura del raggruppamento presente in i dati. Ognuna di queste caratteristiche potrebbe essere scelta come singola misura di "uniformità" per adattarsi a una particolare applicazione.0.15000
Questi esempi mostrano come una funzione L può essere esaminata per valutare le partenze dei dati dall'uniformità ("uniformità") e come le informazioni quantitative sulla scala e sulla natura delle partenze possono essere estratte da esso.
(Si può effettivamente tracciare l'intera funzione L, estendendosi alla distanza completamente normalizzata di , per valutare le deviazioni su larga scala dall'uniformità. Di solito, tuttavia, valutare il comportamento dei dati a distanze minori è di maggiore importanza.)1
Software
R
segue il codice per generare questa cifra. Inizia definendo le funzioni per calcolare K e L. Crea una capacità di simulare da una distribuzione della miscela. Quindi genera i dati simulati e crea i grafici.
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")