Bir çekirdek yoğunluğu tahmincisi (KDE), çekirdek dağılımının bir konum karışımı olan bir dağılım üretir, bu nedenle çekirdek yoğunluğu tahmininden bir değer çizmek için yapmanız gereken tek şey (1) çekirdek yoğunluğundan bir değer çizmek ve sonra (2) bağımsız olarak veri noktalarından birini rastgele seçin ve değerini (1) sonucuna ekleyin.
İşte bu prosedürün, sorudakine benzer bir veri kümesine uygulanan sonucu.
Soldaki histogram örneği gösterir. Referans için siyah eğri, numunenin çekildiği yoğunluğu çizer. Kırmızı eğri, numunenin KDE'sini çizer (dar bir bant genişliği kullanarak). (Kırmızı piklerin siyah piklerden daha kısa olması bir sorun, hatta beklenmedik bir şey değildir: KDE işleri dağıtır, bu nedenle pikler telafi etmek için daha düşük olur.)
Sağdaki histogram KDE'den (aynı boyutta) bir örneği gösterir . Siyah ve kırmızı eğriler öncekilerle aynıdır.
Açıkçası, yoğunluktan numune almak için kullanılan prosedür çalışır. Ayrıca son derece hızlı: R
Aşağıdaki uygulama herhangi bir KDE'den saniyede milyonlarca değer üretir. Ben Python veya diğer diller için taşıma yardımcı olmak için yorumladı. Örnekleme algoritmasının kendisi, rdens
çizgilerle fonksiyonda uygulanır
rkernel <- function(n) rnorm(n, sd=width)
sample(x, n, replace=TRUE) + rkernel(n)
rkernel
çeker n
iken çekirdek işlevinden IID örnekleri sample
çeken n
verilerden değiştirme ile örnekleri x
. "+" İşleci iki bileşen dizisini bileşene göre ekler.
KFKx =( x1, x2, … , Xn)
Fx^;K( x ) = 1nΣi = 1nFK( x - xben) .
Yukarıdaki tarif verilerin ampirik dağılımından (yani her i için 1 / n olasılığı olan x i değerini elde ettiğini ), bağımsız olarak çekirdek dağılımından rastgele bir Y değişkeni çektiğini ve topladığını söylüyor. X + Y'nin dağıtım işlevinin KDE'nin işlevi olduğuna dair bir kanıt borçluyum . Tanımla başlayalım ve nereye götürdüğünü görelim. Let x be gerçek sayı. Üzerinde Klima X verirXxben1 / nbenYX+ YxX
FX+ Y( x )= Pr ( X+ Y≤ x )= ∑i = 1nPr ( X+Y≤ x ∣ X= xben) Pr ( X= xben)= ∑i = 1nPr ( xben+Y≤ x ) 1n= 1nΣi = 1nPr ( Y≤ x - xben)= 1nΣi = 1nFK( x - xben)= Fx^;K( x ) ,
iddia edildiği gibi.
#
# Define a function to sample from the density.
# This one implements only a Gaussian kernel.
#
rdens <- function(n, density=z, data=x, kernel="gaussian") {
width <- z$bw # Kernel width
rkernel <- function(n) rnorm(n, sd=width) # Kernel sampler
sample(x, n, replace=TRUE) + rkernel(n) # Here's the entire algorithm
}
#
# Create data.
# `dx` is the density function, used later for plotting.
#
n <- 100
set.seed(17)
x <- c(rnorm(n), rnorm(n, 4, 1/4), rnorm(n, 8, 1/4))
dx <- function(x) (dnorm(x) + dnorm(x, 4, 1/4) + dnorm(x, 8, 1/4))/3
#
# Compute a kernel density estimate.
# It returns a kernel width in $bw as well as $x and $y vectors for plotting.
#
z <- density(x, bw=0.15, kernel="gaussian")
#
# Sample from the KDE.
#
system.time(y <- rdens(3*n, z, x)) # Millions per second
#
# Plot the sample.
#
h.density <- hist(y, breaks=60, plot=FALSE)
#
# Plot the KDE for comparison.
#
h.sample <- hist(x, breaks=h.density$breaks, plot=FALSE)
#
# Display the plots side by side.
#
histograms <- list(Sample=h.sample, Density=h.density)
y.max <- max(h.density$density) * 1.25
par(mfrow=c(1,2))
for (s in names(histograms)) {
h <- histograms[[s]]
plot(h, freq=FALSE, ylim=c(0, y.max), col="#f0f0f0", border="Gray",
main=paste("Histogram of", s))
curve(dx(x), add=TRUE, col="Black", lwd=2, n=501) # Underlying distribution
lines(z$x, z$y, col="Red", lwd=2) # KDE of data
}
par(mfrow=c(1,1))