วิธีง่ายๆคือการแรสเตอร์โดเมนของการรวมและคำนวณการประมาณที่ไม่ต่อเนื่องกับอินทิกรัล
มีบางสิ่งที่ต้องระวังคือ:
ตรวจสอบให้แน่ใจว่าครอบคลุมมากกว่าจุดต่าง ๆ :คุณต้องรวมตำแหน่งที่ตั้งทั้งหมดที่การประมาณความหนาแน่นของเคอร์เนลจะมีค่าที่เห็นได้ ซึ่งหมายความว่าคุณต้องขยายขอบเขตของคะแนนด้วยแบนด์วิธเคอร์เนลสามถึงสี่เท่า (สำหรับเคอร์เนล Gaussian)
ผลลัพธ์จะแตกต่างกันบ้างตามความละเอียดของภาพแรสเตอร์ ความละเอียดต้องเป็นส่วนเล็ก ๆ ของแบนด์วิดท์ เนื่องจากเวลาในการคำนวณเป็นสัดส่วนกับจำนวนเซลล์ในแรสเตอร์จึงไม่ต้องใช้เวลาเพิ่มในการคำนวณแบบอนุกรมโดยใช้ความละเอียดที่หยาบกว่าที่ตั้งใจไว้: ตรวจสอบว่าผลลัพธ์ของการ coarser นั้นมาบรรจบกับผลลัพธ์สำหรับ ความละเอียดที่ดีที่สุด หากไม่เป็นเช่นนั้นอาจจำเป็นต้องมีการแก้ไขที่ละเอียดยิ่งขึ้น
นี่คือภาพประกอบสำหรับชุดข้อมูล 256 คะแนน:
คะแนนจะแสดงเป็นจุดสีดำที่ซ้อนทับบนการประมาณความหนาแน่นของเคอร์เนลสองตัว จุดสีแดงขนาดใหญ่หกจุดคือ "โพรบ" ซึ่งอัลกอริทึมได้รับการประเมิน สิ่งนี้ทำสำหรับสี่แบนด์วิดท์ (ค่าเริ่มต้นระหว่าง 1.8 (แนวตั้ง) และ 3 (แนวนอน), 1/2, 1 และ 5 ยูนิต) ที่ความละเอียด 1000 ถึง 1,000 เซลล์ เมทริกซ์ scatterplot ต่อไปนี้แสดงให้เห็นว่าผลลัพธ์ยิ่งขึ้นอยู่กับแบนด์วิดท์สำหรับจุดโพรบทั้งหกจุดซึ่งครอบคลุมความหนาแน่นที่หลากหลาย:
การเปลี่ยนแปลงที่เกิดขึ้นด้วยเหตุผลสองประการ เห็นได้ชัดว่าการประเมินความหนาแน่นแตกต่างกันแนะนำรูปแบบหนึ่งของการเปลี่ยนแปลง ที่สำคัญกว่านั้นความแตกต่างของการประมาณความหนาแน่นสามารถสร้างความแตกต่างได้มากณ จุดใดจุดหนึ่ง ("โพรบ") รูปแบบหลังนั้นยิ่งใหญ่ที่สุดรอบ "ความหนาแน่น" ของกลุ่มจุดที่มีความหนาแน่นปานกลาง - สถานที่เหล่านั้นที่การคำนวณนี้น่าจะถูกใช้มากที่สุด
สิ่งนี้แสดงให้เห็นถึงความจำเป็นในการใช้ความระมัดระวังอย่างมากในการใช้และตีความผลลัพธ์ของการคำนวณเหล่านี้เนื่องจากอาจมีความอ่อนไหวต่อการตัดสินใจโดยพลการ (แบนด์วิดท์ที่ใช้)
รหัส R
อัลกอริทึมนั้นมีอยู่ในครึ่งโหลของฟังก์ชันแรก, f
. เพื่อแสดงให้เห็นถึงการใช้งานส่วนที่เหลือของรหัสสร้างตัวเลขก่อนหน้า
library(MASS) # kde2d
library(spatstat) # im class
f <- function(xy, n, x, y, ...) {
#
# Estimate the total where the density does not exceed that at (x,y).
#
# `xy` is a 2 by ... array of points.
# `n` specifies the numbers of rows and columns to use.
# `x` and `y` are coordinates of "probe" points.
# `...` is passed on to `kde2d`.
#
# Returns a list:
# image: a raster of the kernel density
# integral: the estimates at the probe points.
# density: the estimated densities at the probe points.
#
xy.kde <- kde2d(xy[1,], xy[2,], n=n, ...)
xy.im <- im(t(xy.kde$z), xcol=xy.kde$x, yrow=xy.kde$y) # Allows interpolation $
z <- interp.im(xy.im, x, y) # Densities at the probe points
c.0 <- sum(xy.kde$z) # Normalization factor $
i <- sapply(z, function(a) sum(xy.kde$z[xy.kde$z < a])) / c.0
return(list(image=xy.im, integral=i, density=z))
}
#
# Generate data.
#
n <- 256
set.seed(17)
xy <- matrix(c(rnorm(k <- ceiling(2*n * 0.8), mean=c(6,3), sd=c(3/2, 1)),
rnorm(2*n-k, mean=c(2,6), sd=1/2)), nrow=2)
#
# Example of using `f`.
#
y.probe <- 1:6
x.probe <- rep(6, length(y.probe))
lims <- c(min(xy[1,])-15, max(xy[1,])+15, min(xy[2,])-15, max(xy[2,]+15))
ex <- f(xy, 200, x.probe, y.probe, lim=lims)
ex$density; ex$integral
#
# Compare the effects of raster resolution and bandwidth.
#
res <- c(8, 40, 200, 1000)
system.time(
est.0 <- sapply(res,
function(i) f(xy, i, x.probe, y.probe, lims=lims)$integral))
est.0
system.time(
est.1 <- sapply(res,
function(i) f(xy, i, x.probe, y.probe, h=1, lims=lims)$integral))
est.1
system.time(
est.2 <- sapply(res,
function(i) f(xy, i, x.probe, y.probe, h=1/2, lims=lims)$integral))
est.2
system.time(
est.3 <- sapply(res,
function(i) f(xy, i, x.probe, y.probe, h=5, lims=lims)$integral))
est.3
results <- data.frame(Default=est.0[,4], Hp5=est.2[,4],
H1=est.1[,4], H5=est.3[,4])
#
# Compare the integrals at the highest resolution.
#
par(mfrow=c(1,1))
panel <- function(x, y, ...) {
points(x, y)
abline(c(0,1), col="Red")
}
pairs(results, lower.panel=panel)
#
# Display two of the density estimates, the data, and the probe points.
#
par(mfrow=c(1,2))
xy.im <- f(xy, 200, x.probe, y.probe, h=0.5)$image
plot(xy.im, main="Bandwidth=1/2", col=terrain.colors(256))
points(t(xy), pch=".", col="Black")
points(x.probe, y.probe, pch=19, col="Red", cex=.5)
xy.im <- f(xy, 200, x.probe, y.probe, h=5)$image
plot(xy.im, main="Bandwidth=5", col=terrain.colors(256))
points(t(xy), pch=".", col="Black")
points(x.probe, y.probe, pch=19, col="Red", cex=.5)