确定多峰单变量数据核密度估计的模式位置

Determine mode locations of the kernel density estimate of multimodal univariate data

如果我有一个密度函数并用特定的带宽绘制它,我可以直观地确定有 7 个局部最大值。我只想知道如何在同一地块上绘制特定最大值的单独分布。 另外,是否有可能通过 运行 某些代码确切知道最大值出现在哪里?我可以使用绘图进行大概估计,但是否有 R 函数可用于获取准确点数?我想知道我确定的 7 个密度的均值和方差。 具体来说,我有以下内容:

plot(density(stamp, bw=0.0013,kernel = "gaussian"))  

确定核密度估计中哪些模式是真实的取决于您选择使用哪个带宽。这是一件复杂的事情,我不建议只选择一个带宽,因为即使是不同的最佳经验法则也会给你不同的答案。通常,kde 的模式数在过度平滑的情况下小于底层密度的数量,在平滑不足的情况下更是如此。有许多论文涵盖了这个主题,并为您提供了许多选项来帮助确定模式的准确性。例如,查看 Silverman 的高斯核模式测试、Friedman 和 Fisher 的 prim 算法、Marron 的 siZer 以及 Minnotte 和 Scott 的模式树都是很好的起点。

给定单个 KDE 带宽选择,您可以做的一件幼稚的事情是检查 运行 长度。

事实上,根据您选择的带宽,我找到了 9 种模式。只需计算级数差值的符号变化,计算运行s的累计长度,即可求出点。每隔一点将是模式或反模式,具体取决于哪个先出现。 (这个可以看标志判断)

library(BSDA)
dstamp <- density(Stamp$thickness, bw=0.0013, kernel = "gaussian")
chng <- cumsum(rle(sign(diff(dstamp$y)))$lengths)
plot(dstamp)
abline(v = dstamp$x[chng[seq(1,length(chng),2)]])

因为我只需要一些东西来获得最强的模式,所以我创建了一个极其简单的算法,允许您通过调整密度样本的数量(以减少局部噪声)来提高灵敏度,并设置一个最小密度阈值,与最大密度(以减少全局噪声)。

find_posterior_modes <- function(x, n.samples = 100, filter = .1) {
    d <- density(x, n = n.samples)
    x <- with(d, sapply(2:(n.samples - 1), function(i) if (y[i] > y[i - 1] & y[i] > y[i + 1] & y[i] > max(y) * filter) x[i]))
    unlist(x)
}