Epanechnikov 核的计算效率真的比高斯核更高吗?

问题描述 投票:0回答:2

我正在实现一个函数来估计单变量和多变量情况下的核密度估计。就此而言,我使用的是高斯内核,即使对于大量数据集,它也能很好地工作。然而许多人声称我应该使用 Epanechnikov 内核,因为它的计算效率更高,并且支持紧凑。但我不同意,或者至少我还没有找到一种方法来实现它以使其击败高斯。 这是我的代码,用于对实数点 x_o 处的密度进行高斯估计,相对于值 x 的向量:

dens_point <- function(x_0, x, width){
  weights <- (1/sqrt(2*pi))*exp(-(1/2)*(((x_0-x)/width)^2))
  return((1/(length(x)*width))*sum(weights))
}

甚至更高效,

dens_point <- function(x_0, x, width){
  constant <- (1/sqrt(2*pi)
  weights <- constant*exp(-0.5*(((x_0-x)/width)^2)))
  return((1/(length(x)*width))*sum(weights))
}

或者更进一步,以牺牲可读性为代价:

dens_point <- function(x_0, x, width){
  constant <- (1/sqrt(2*pi)
  return(
     (1/(length(x)*width))*sum(constant*exp(-0.5*(((x_0-x)/width)^2))))
  )
}

为了获得间隔上的线,我只需对参数

x_0
上的函数进行向量化,并给它一个值序列。这已经是我能做到的最有效的了。相比之下,Epanechnikov 内核要慢得多。我尝试过以下代码:

epanechnikov <- function(u){
  if (u <= 1){
    return(0)
  } else {
    return( (1-u^2)*0.75 )
  }
}
epanechnikov <- Vectorize(epanechnikov)

dens_point <- function(x0, x, width){
  weights <- epanechnikov( (x0-x)/width )
  return( (1/(length(x)*width)*sum(weights) )
}

但是这个解与高斯解相比是极其逊色的,但却是我能想到的最精致的表达方式。 For 循环和应用甚至更慢。我想说高斯函数非常快,因为它使用基本 R 向量运算,这是 Vectorize() 无法与之竞争的。你能想出更快的代码吗?

r statistics kernel-density
2个回答
0
投票

确实,

Vectorize
无法与矢量化函数竞争。因此,只需利用基本函数即可:

epanechnikov2 <- function(u) {
  k <- (1-u^2) * 0.75
  k[u <= 1] <- 0
  k
}

或者稍微快一点[编辑:并且使用更少的内存]:

epanechnikov3 <- function(u) {
  k <- (1-u^2) * 0.75
  (abs(k) + k) / 2
}

0
投票

我不熟悉R的语法,但我相信提问者提到的更高效的场景只有当(x_0)规则排列时才会出现,比如在算术序列中。在这种情况下,根据 (x) 和宽度的值将 (x_0) 限制为一个窗口是非常方便的。

© www.soinside.com 2019 - 2024. All rights reserved.