Une fonction standard, puissante, bien comprise, théoriquement bien établie et fréquemment mise en œuvre de la «régularité» est la fonction Ripley K et son proche parent, la fonction L. Bien que ceux-ci soient généralement utilisés pour évaluer les configurations de points spatiaux bidimensionnels, l'analyse nécessaire pour les adapter à une dimension (qui n'est généralement pas donnée dans les références) est simple.
Théorie
La fonction K estime la proportion moyenne de points à une distance d'un point typique. Pour une distribution uniforme sur l'intervalle [ 0 , 1 ] , la vraie proportion peut être calculée et (asymptotiquement dans la taille de l'échantillon) égale 1 - ( 1 - d ) 2 . La version unidimensionnelle appropriée de la fonction L soustrait cette valeur de K pour montrer les écarts par rapport à l'uniformité. Nous pourrions donc envisager de normaliser tout lot de données pour avoir une plage d'unités et d'examiner sa fonction L pour les écarts autour de zéro.d[0,1]1−(1−d)2
Exemples travaillés
Pour illustrer , j'ai simulé échantillons indépendants de la taille 64 d'une distribution uniforme et tracer leur (normalisé) des fonctions de L pour des distances plus courtes (de 0 à une / 3 ), créant ainsi une enveloppe pour estimer la distribution d'échantillonnage de la fonction L. (Les points tracés bien à l'intérieur de cette enveloppe ne peuvent pas être distingués de manière significative de l'uniformité.) Sur ce point, j'ai tracé les fonctions L pour des échantillons de la même taille à partir d'une distribution en U, d'une distribution de mélange avec quatre composants évidents et d'une distribution normale standard. Les histogrammes de ces échantillons (et de leurs distributions parentes) sont présentés à titre de référence, en utilisant des symboles linéaires pour correspondre à ceux des fonctions L.9996401/3
Les pointes fortement séparées de la distribution en forme de U (ligne rouge en pointillés, histogramme le plus à gauche) créent des groupes de valeurs étroitement espacées. Cela se traduit par une très grande pente de la fonction L à . La fonction L diminue ensuite, devenant finalement négative pour refléter les écarts à des distances intermédiaires.0
L'échantillon de la distribution normale (ligne bleue continue, histogramme le plus à droite) est assez proche de la distribution uniforme. En conséquence, sa fonction L ne s'écarte pas rapidement de . Cependant, par des distances de 0,10 environ, il s'est élevé suffisamment au-dessus de l'enveloppe pour signaler une légère tendance à se regrouper. L'augmentation continue sur des distances intermédiaires indique que le regroupement est diffus et répandu (non limité à certains pics isolés).00.10
La grande pente initiale de l'échantillon à partir de la distribution du mélange (histogramme central) révèle un regroupement à de petites distances (moins de ). En tombant à des niveaux négatifs, il signale une séparation à des distances intermédiaires. La comparaison avec la fonction L de la distribution en U est révélatrice: les pentes à 0 , les montants par lesquels ces courbes montent au-dessus de 0 et les taux auxquels elles finissent par revenir à 0 fournissent toutes des informations sur la nature du regroupement présent dans les données. Chacune de ces caractéristiques pourrait être choisie comme une seule mesure de "régularité" pour convenir à une application particulière.0.15000
Ces exemples montrent comment une fonction L peut être examinée pour évaluer les écarts des données par rapport à l'uniformité («uniformité») et comment on peut en extraire des informations quantitatives sur l'échelle et la nature des écarts.
(On peut en effet tracer la fonction L entière, s'étendant jusqu'à la distance normalisée complète de , pour évaluer les écarts à grande échelle par rapport à l'uniformité. Cependant, l'évaluation du comportement des données à de plus petites distances est généralement plus importante.)1
Logiciel
R
Le code pour générer cette figure suit. Il commence par définir des fonctions pour calculer K et L. Il crée une capacité à simuler à partir d'une distribution de mélange. Ensuite, il génère les données simulées et crée les tracés.
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")