函数nndist和kNNdist有什么区别?

时间:2017-07-31 14:51:10

标签: r machine-learning statistics cluster-analysis nearest-neighbor

我目前正在尝试用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

显然,默认情况下两个函数似乎都没有使用相同的距离或计算方法。

1 个答案:

答案 0 :(得分:0)

这里有几个问题:

  1. nndist将矩阵作为输入时,它假定它只是二维的。为了接受iris数据集的四列作为四维点并触发nndist的多维版本 - nndist.ppx - 您首先需要转换iris到这样的ppx点:ppx(iris)

  2. 即使在照顾到1之后,结果仍然会有所不同。那是因为kNNdist不仅仅产生到k = 3邻居的距离,而是一个数据帧,其中包含一个列,所有距离都高达k = 3(即k = 1,k = 2和k) = 3)。因此,当您尝试仅为k = 3获取值并且想要将其与nndist的结果进行比较时,您应该只使用第三列,如下所示:distance_third_neighbour_iris_knndist[,3]

  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