Một tiêu chuẩn, mạnh mẽ, được hiểu rõ, được thiết lập tốt về mặt lý thuyết và được thực hiện thường xuyên về "tính đồng đều" là hàm Ripley K và hàm tương đối gần của nó, hàm L. Mặc dù chúng thường được sử dụng để đánh giá các cấu hình điểm không gian hai chiều, nhưng phân tích cần thiết để điều chỉnh chúng theo một chiều (thường không được đưa ra trong tài liệu tham khảo) là đơn giản.
Học thuyết
Hàm K ước tính tỷ lệ trung bình của các điểm trong khoảng cách của một điểm điển hình. Đối với phân phối đồng đều trên khoảng [ 0 , 1 ] , tỷ lệ thực có thể được tính và (không có triệu chứng trong cỡ mẫu) bằng 1 - ( 1 - d ) 2 . Phiên bản một chiều thích hợp của hàm L sẽ trừ giá trị này khỏi K để hiển thị độ lệch so với tính đồng nhất. Do đó, chúng tôi có thể xem xét bình thường hóa bất kỳ lô dữ liệu nào để có phạm vi đơn vị và kiểm tra chức năng L của nó để tìm độ lệch quanh 0.d[0,1]1−(1−d)2
Ví dụ làm việc
Để minh họa , tôi đã mô phỏng mẫu độc lập với kích thước 64 từ một phân bố đều và vẽ (bình thường) chức năng L của họ cho khoảng cách ngắn (từ 0 đến 1 / 3 ), qua đó tạo ra một phong bì để ước tính sự phân bố lấy mẫu của hàm L. (Điểm được thể hiện rõ trong phong bì này có thể được phân biệt rõ rệt với tính đồng nhất.) Về điều này tôi đã vẽ các hàm L cho các mẫu có cùng kích thước từ phân bố hình chữ U, phân phối hỗn hợp với bốn thành phần rõ ràng và phân phối chuẩn. Biểu đồ của các mẫu này (và của các bản phân phối chính của chúng) được hiển thị để tham khảo, sử dụng các ký hiệu dòng để khớp với các mẫu của hàm L.9996401/3
Các gai nhọn tách biệt của phân bố hình chữ U (đường màu đỏ nét đứt, biểu đồ ngoài cùng bên trái) tạo ra các cụm giá trị cách đều nhau. Điều này được phản ánh bởi độ dốc rất lớn trong hàm L ở 0 . Hàm L sau đó giảm dần, cuối cùng trở thành âm để phản ánh các khoảng trống ở khoảng cách trung gian.
Mẫu từ phân phối chuẩn (đường màu xanh lam đặc, biểu đồ ngoài cùng bên phải) khá gần với phân bố đồng đều. Theo đó, chức năng L của nó không khởi hành từ một cách nhanh chóng. Tuy nhiên, bằng khoảng cách 0,1000.10 hoặc hơn, nó đã tăng đủ trên đường bao để báo hiệu một xu hướng nhỏ cụm. Sự gia tăng liên tục trên các khoảng cách trung gian cho thấy sự phân cụm là khuếch tán và lan rộng (không giới hạn ở một số đỉnh bị cô lập).
Độ dốc lớn ban đầu cho mẫu từ phân bố hỗn hợp (biểu đồ giữa) cho thấy phân cụm ở khoảng cách nhỏ (nhỏ hơn ). Bằng cách giảm xuống mức âm, nó báo hiệu sự phân tách ở khoảng cách trung gian. So sánh điều này với hàm L của phân phối hình chữ U đang tiết lộ: độ dốc bằng 0 , số lượng các đường cong này tăng lên trên 0 và tốc độ cuối cùng chúng giảm xuống 0 đều cung cấp thông tin về bản chất của cụm hiện diện trong dữ liệu. Bất kỳ đặc điểm nào trong số này có thể được chọn làm thước đo "đồng đều" cho phù hợp với một ứng dụng cụ thể.0.15000
Các ví dụ này cho thấy cách chức năng L có thể được kiểm tra để đánh giá sự khởi hành của dữ liệu từ tính đồng nhất ("tính đồng đều") và cách thông tin định lượng về quy mô và tính chất của các lần khởi hành có thể được trích xuất từ nó.
(Người ta thực sự có thể vẽ toàn bộ hàm L, mở rộng đến khoảng cách chuẩn hóa hoàn toàn là , để đánh giá các lần khởi hành quy mô lớn từ tính đồng nhất. Tuy nhiên, thông thường, việc đánh giá hành vi của dữ liệu ở khoảng cách nhỏ hơn có tầm quan trọng lớn hơn.)1
Phần mềm
R
mã để tạo ra con số này sau đây. Nó bắt đầu bằng cách xác định các hàm để tính K và L. Nó tạo ra khả năng mô phỏng từ phân phối hỗn hợp. Sau đó, nó tạo ra dữ liệu mô phỏng và thực hiện các ô.
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")