当 window 宽度变化时如何找到核密度曲线上的所有转折点

How to find all the turning points on a kernel density curve when window width varies

我想使用内核密度对数据系列进行分区。这是我的计划:

  1. 使用具有变体 window 宽度的核密度函数(如 density())来计算该系列的密度。
  2. 在每条不同 window 宽度的内核曲线上,我找到所有的转折点(包括最小和最大)来划分数据。

所以,我需要知道那些转折点在原始数据系列中的位置。我阅读了一些信息,例如 https://stats.stackexchange.com/questions/30750/finding-local-extrema-of-a-density-function-using-splines。但是我真的不明白这个方法。在该方法中,d$x[tp$tppos] 看起来不是原始索引。那么如何根据核密度曲线找到原始数据中所有转折点的位置呢?

另一个相关问题是:如何找到所有 minimal/maximal 个点?

数据系列的样本是:

a <- c(21.11606, 15.22204, 16.27281, 15.22204, 15.22204, 21.11606, 19.32840, 15.22204, 20.25594, 15.22204, 14.28352, 15.22195, 19.32840, 19.32840, 15.22204, 14.28352, 21.11606, 21.19069, 15.22204, 25.26564, 15.22204, 19.32840, 21.11606, 15.22204, 15.22204, 19.32840, 15.22204, 19.32840, 15.22204, 15.22204, 21.13656, 15.22204, 15.22204, 19.32840, 15.22204, 17.98954, 15.22204, 15.22204, 15.22204, 15.22204, 15.22204, 19.32840, 15.22204, 14.28352, 15.22204, 19.32840, 15.22204, 19.32840, 25.42281, 21.19069)

当您计算 a 的密度时: Da = density(a) 结果的 y 值与许多 x 相关联。这就是情节的来源。要找到"turning points",你需要找到导数改变符号的地方。由于 Da$x 中给定的 x 值在递增,因此 Each
Da$y[i] - Da$y[i-1] 与第 i 点的导数同号。您可以通过查找连续值的乘积为负的位置来找到这些更改符号的位置。因此,将所有这些放在一起,我们得到:

Da = density(a)
DeltaY = diff(Da$y)
Turns = which(DeltaY[-1] * DeltaY[-length(DeltaY)] < 0) + 1

plot(Da, xlab="", ylab="", main="")
points(Da$x[Turns], Da$y[Turns], pch=16, col="red")

您可以使用 densityadjust 参数得到不同的 "window widths"。但是,您会发现随着 adjust 变小,密度图将出现 许多 个最大值和最小值。