我目前正在尝试用R实现DBSCAN算法来查找数据中的异常值。为了初始化参数(尤其是epsilon),我必须在我的样本中绘制到第k个邻居(我选择k = 3
)的距离的升序排序序列,并查看肘部在哪里为epsilon选择正确的值。
正如我所说我使用的是R统计语言,我找到了两个不同的函数来计算到第k个邻居nndist()
和kNNdist()
的距离。如果我在默认情况下理解得很好,它会使用欧几里德距离。但是在我的数据中,函数不会显示相同的结果。为了说明我的问题,我在着名的iris
数据集上实现了两个函数,你可以看到结果完全不同:
data(iris)
iris <- as.matrix(iris[,1:4])
distance_third_neighbour_iris = iris %>% nndist(k = 3)
as.vector(quantile(distance_third_neighbour_iris, probs = 0.99))
### gives 0.68
distance_third_neighbour_iris = iris %>% kNNdist(k = 3)
as.vector(quantile(distance_third_neighbour_iris, probs = 0.99))
### gives 0.81
显然,默认情况下两个函数似乎都没有使用相同的距离或计算方法。
答案 0 :(得分:0)
这里有几个问题:
当nndist
将矩阵作为输入时,它假定它只是二维的。为了接受iris
数据集的四列作为四维点并触发nndist
的多维版本 - nndist.ppx
- 您首先需要转换iris
到这样的ppx
点:ppx(iris)
即使在照顾到1之后,结果仍然会有所不同。那是因为kNNdist
不仅仅产生到k = 3邻居的距离,而是一个数据帧,其中包含一个列,所有距离都高达k = 3(即k = 1,k = 2和k) = 3)。因此,当您尝试仅为k = 3获取值并且想要将其与nndist
的结果进行比较时,您应该只使用第三列,如下所示:distance_third_neighbour_iris_knndist[,3]
您修改的代码应该是:
library(dbscan)
library(spatstat)
data(iris)
iris <- as.matrix(iris[,1:4])
distance_third_neighbour_iris_nndist = ppx(iris) %>% nndist(k = 3)
as.vector(quantile(distance_third_neighbour_iris_nndist, probs = 0.99))
### gives 0.8776718
distance_third_neighbour_iris_knndist = iris %>% kNNdist(k = 3)
as.vector(quantile(distance_third_neighbour_iris_knndist[,3], probs = 0.99))
### gives 0.8776718