커널 밀도 추정기 (KDE)는 커널 분포의 위치 혼합 인 분포를 생성하므로 커널 밀도 추정값에서 값을 얻으려면 (1) 커널 밀도에서 값을 얻은 다음 (2) 독립적으로 데이터 포인트 중 하나를 임의로 선택하고 그 값을 (1)의 결과에 추가하십시오.
이 절차의 결과는 문제의 데이터 세트와 같은 데이터 세트에 적용됩니다.
왼쪽의 히스토그램은 샘플을 나타냅니다. 참고로 검은 색 곡선은 샘플이 추출 된 밀도를 나타냅니다. 빨간색 곡선은 좁은 대역폭을 사용하여 샘플의 KDE를 표시합니다. (빨간 피크가 검은 피크보다 짧다는 것은 문제가 아니거나 예기치 않은 일이 아닙니다. KDE가 사물을 퍼뜨 리므로 피크가 보상하기 위해 낮아집니다.)
오른쪽의 히스토그램 은 KDE 의 샘플 (동일한 크기) 을 나타냅니다. 검은 색과 빨간색 곡선은 이전과 동일합니다.
분명히, 밀도에서 샘플링하는 데 사용되는 절차가 작동합니다. 또한 매우 빠릅니다. R
아래 구현은 모든 KDE에서 초당 수백만 개의 값을 생성합니다. 나는 파이썬이나 다른 언어로의 포팅을 돕기 위해 크게 언급했다. 샘플링 알고리즘 자체는 다음과 같은 기능 rdens
으로 구현됩니다.
rkernel <- function(n) rnorm(n, sd=width)
sample(x, n, replace=TRUE) + rkernel(n)
rkernel
그리는 n
동안 커널 함수에서 IID 샘플을 sample
그립니다 n
데이터 관련으로 샘플을 x
. "+"연산자는 두 개의 샘플 배열을 구성 요소별로 추가합니다.
케이에프케이x =( x1, x2, … , x엔)
에프엑스^;케이( x ) = 1엔∑나는 = 1엔에프케이( x − x나는) .
엑스엑스나는1 / n나는와이엑스+ Y엑스엑스
에프엑스+ Y( x )= Pr ( X+ Y≤ x )= ∑나는 = 1엔Pr ( X+ Y≤ x ∣ X= x나는) Pr ( X= x나는)= ∑나는 = 1엔Pr ( x나는+ Y≤ x ) 1엔= 1엔∑나는 = 1엔Pr ( Y≤ x − x나는)= 1엔∑나는 = 1엔에프케이( x − x나는)= F엑스^;케이( X ) ,
주장대로.
#
# 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))