Ein standardmäßiges, leistungsfähiges, gut verstandenes, theoretisch gut etabliertes und häufig implementiertes Maß für "Ebenheit" ist die Ripley-K-Funktion und deren enger Verwandter, die L-Funktion. Obwohl diese normalerweise zur Bewertung zweidimensionaler räumlicher Punktkonfigurationen verwendet werden, ist die Analyse, die erforderlich ist, um sie an eine Dimension anzupassen (was normalerweise nicht in Referenzen angegeben ist), einfach.
Theorie
Die K-Funktion schätzt den mittleren Anteil von Punkten innerhalb eines Abstands von einem typischen Punkt. Für eine gleichmäßige Verteilung auf das Intervall [ 0 , 1 ] kann der wahre Anteil berechnet werden und (asymptotisch in der Stichprobengröße) gleich 1 - ( 1 - d ) 2 sein . Die entsprechende eindimensionale Version der L-Funktion subtrahiert diesen Wert von K, um Abweichungen von der Homogenität zu zeigen . Wir könnten daher in Betracht ziehen, einen Datenstapel auf einen Einheitenbereich zu normieren und seine L-Funktion auf Abweichungen um Null zu untersuchen.d[0,1]1−(1−d)2
Arbeitsbeispiele
Zur Veranschaulichung , ich habe simuliert unabhängige Proben der Größe 64 von einer gleichförmigen Verteilung und aufgetragen ihre (normalisierte) L - Funktionen für kürzere Entfernungen (von 0 bis 1 / 3 ), um dadurch eine Hülle zu schaffen , die Stichprobenverteilung der L Funktion zu schätzen. (In diesem Umschlag gut eingezeichnete Punkte können nicht signifikant von der Gleichmäßigkeit unterschieden werden.) Darüber habe ich die L-Funktionen für Proben gleicher Größe aus einer U-förmigen Verteilung, einer Mischungsverteilung mit vier offensichtlichen Komponenten und einer Standardnormalverteilung eingezeichnet. Die Histogramme dieser Stichproben (und ihrer übergeordneten Verteilungen) werden als Referenz gezeigt, wobei Liniensymbole verwendet werden, um mit denen der L-Funktionen übereinzustimmen.9996401/3
Die scharf getrennten Spitzen der U-förmigen Verteilung (gestrichelte rote Linie, Histogramm ganz links) erzeugen Cluster mit eng beieinander liegenden Werten. Dies zeigt sich an einer sehr großen Steigung in der L-Funktion bei . Die L-Funktion nimmt dann ab und wird schließlich negativ, um die Lücken bei Zwischenabständen wiederzugeben.0
Die Probe aus der Normalverteilung (durchgezogene blaue Linie, Histogramm ganz rechts) ist ziemlich gleichmäßig verteilt. Dementsprechend weicht seine L-Funktion nicht schnell von . Bei Abständen von etwa 0,10 ist sie jedoch ausreichend über die Hüllkurve gestiegen, um eine leichte Tendenz zur Clusterbildung zu signalisieren. Der fortgesetzte Anstieg über mittlere Entfernungen zeigt, dass die Clusterbildung diffus und weit verbreitet ist (nicht auf einige isolierte Peaks beschränkt).00.10
Die anfänglich große Steigung der Probe aus der Gemischverteilung (mittleres Histogramm) zeigt eine Häufung bei kleinen Entfernungen (weniger als ). Durch Absinken auf negative Werte wird eine Trennung in Zwischenabständen signalisiert. Der Vergleich mit der L-Funktion der U-förmigen Verteilung zeigt: Die Steigungen bei 0 , die Beträge, um die diese Kurven über 0 ansteigen , und die Raten, mit denen sie schließlich wieder auf 0 abfallen, geben Auskunft über die Art der Clusterbildung in die Daten. Jedes dieser Merkmale könnte als einzelnes Maß für die "Gleichmäßigkeit" ausgewählt werden, um einer bestimmten Anwendung zu entsprechen.0.15000
Diese Beispiele zeigen, wie eine L-Funktion untersucht werden kann, um Abweichungen der Daten von der Gleichmäßigkeit ("Gleichmäßigkeit") zu bewerten, und wie quantitative Informationen über den Maßstab und die Art der Abweichungen daraus extrahiert werden können.
(Man kann tatsächlich die gesamte L-Funktion aufzeichnen, die sich auf den gesamten normalisierten Abstand von , um Abweichungen von der Homogenität in großem Maßstab zu beurteilen. Normalerweise ist es jedoch von größerer Bedeutung, das Verhalten der Daten in kleineren Abständen zu beurteilen.)1
Software
R
Code zum Generieren dieser Figur folgt. Zunächst werden Funktionen zur Berechnung von K und L definiert. Es wird eine Simulationsfunktion für eine Gemischverteilung erstellt. Dann werden die simulierten Daten generiert und die Diagramme erstellt.
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")