표준적이고 강력하며 잘 이해되고 이론적으로 잘 정립되고 자주 구현되는 "균일 성"척도는 Ripley K 함수 와 그에 가까운 L 함수입니다. 이들은 일반적으로 2 차원 공간 포인트 구성을 평가하는 데 사용되지만, 1 차원 (보통 참조에 제공되지 않음)에 적용하는 데 필요한 분석은 간단합니다.
이론
K 함수 는 일반적인 점 의 거리 내에서 점의 평균 비율을 추정합니다 . 구간 [ 0 , 1 에 균일 한 분포d , 실제 비율을 계산하고 (점근 샘플 크기)가 동일 할 수있다 (1) - ( 1 - D ) 2 . 적절한 1 차원 버전의 L 함수는이 값을 K에서 빼서균일 성과의 편차를 나타냅니다. 따라서 데이터 배치를 정규화하고 단위 범위를 갖도록 L 함수를 0으로 둘러싼 편차를 검사하는 것을 고려할 수 있습니다.[0,1]1−(1−d)2
작동 예
설명하기 위해 999를 시뮬레이션했습니다.999 크기의 독립 샘플 (로부터의 균일 한 분포로부터 짧은 거리에 대한 자신의 (정규화) L 함수를 플롯 0 에 1 / 3 함으로써, L 함수의 샘플링 분포를 추정 봉투를 생성). (이 엔벌 로프 내에서 잘린 점은 균일 성과 크게 구별 할 수 없습니다.) 이것에 대해 나는 U 자형 분포, 4 개의 명백한 성분이 포함 된 혼합 분포 및 표준 정규 분포에서 같은 크기의 표본에 대한 L 함수를 플로팅했습니다. 이러한 샘플 (및 모 분포)의 히스토그램은 L 기호와 일치하는 선 기호를 사용하여 참조 용으로 표시됩니다.6401/3
U 자형 분포 (빨간색 점선, 가장 왼쪽 막대 그래프) 의 날카로운 분리 된 스파이크 는 밀접한 간격의 값으로 구성된 군집을 만듭니다. 이것은 에서 L 함수의 매우 큰 기울기에 의해 반영됩니다 . 그런 다음 L 기능이 감소하여 중간 거리의 간격을 반영하여 음수가됩니다.0
정규 분포 (검은 색 선, 가장 오른쪽 막대 그래프) 의 표본은 균일하게 분포 된 것과 거의 비슷합니다. 따라서 L 기능은 빨리 벗어나지 않습니다 . 그러나, 0.10 정도의 거리 만큼, 그것은 약간의 경향을 나타 내기 위해 엔벨로프 위로 충분히 상승했다. 중간 거리에 걸친 지속적인 상승은 클러스터링이 확산되고 널리 퍼져 있음을 나타냅니다 (일부 고립 된 피크에 국한되지 않음).00.10
혼합물 분포 (중간 히스토그램) 에서 샘플의 초기 큰 기울기 는 작은 거리 ( 0.15 미만)에서 군집을 나타냅니다.0.15 . 음수 레벨로 떨어지면 중간 거리에서 분리 신호를 보냅니다. 이것을 U 자형 분포의 L 함수와 비교하면 다음과 같이 밝혀집니다 : 에서의 경사 , 이러한 곡선이 0 이상으로 상승하는 양 , 그리고 결국 0 으로 내려가는 속도는 모두에 존재하는 군집의 본질에 대한 정보를 제공합니다 자료. 이러한 특성은 특정 응용 분야에 적합한 단일 "균일 성"측정 기준으로 선택할 수 있습니다.000
이 예는 균일 성 ( "균일 성")으로부터 데이터의 이탈을 평가하기 위해 L 함수를 검사하는 방법 과 이탈의 규모 및 특성에 대한 정량적 정보를 추출 할 수있는 방법을 보여줍니다.
(실제로 대규모 이탈을 평가하기 위해 전체 정규화 된 거리 확장되는 전체 L 함수를 플로팅 할 수 있습니다 . 그러나 일반적으로 더 작은 거리에서 데이터의 동작을 평가하는 것이 더 중요합니다.)1
소프트웨어
R
이 그림을 생성하는 코드는 다음과 같습니다. K와 L을 계산하는 함수를 정의하는 것으로 시작합니다. 혼합 분포에서 시뮬레이션하는 기능을 만듭니다. 그런 다음 시뮬레이션 된 데이터를 생성하고 플롯을 만듭니다.
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")