在 dbscan 结果中查找 k-最大的集群

Finding the k-largest clusters in dbscan result

我有一个数据框 df,由两列组成:xy 坐标. 每行代表一个点。 我将其输入 dbscan 函数以获得 df.

中的点簇
library("fpc")
db = fpc::dbscan(df, eps = 0.08, MinPts = 4)
plot(db, df, main = "DBSCAN", frame = FALSE)

通过使用 print(db),我可以看到 return 由 dbscan 编辑的结果。

> print(db)
dbscan Pts=13131 MinPts=4 eps=0.08
         0    1    2  3  4   5  6 7  8  9 10 11 12 13 14 15 16 17 18 19 20 21
border 401   38   55  5  2   3  0 0  0  8  0  6  1  3  1  3  3  2  1  2  4  3
seed     0 2634 8186 35 24 561 99 7 22 26  5 75 17  9  9 54  1  2 74 21  3 15
total  401 2672 8241 40 26 564 99 7 22 34  5 81 18 12 10 57  4  4 75 23  7 18
       22 23 24 25 26 27 28  29 30 31 32 33  34 35 36 37 38 39 40 41 42 43 44
border  4  1  2  6  2  1  3   7  2  1  2  3  11  1  3  1  3  2  5  5  1  4  3
seed   14  9  4 48  2  4 38 111  5 11  5 14 111  6  1  5  1  8  3 15 10 15  6
total  18 10  6 54  4  5 41 118  7 12  7 17 122  7  4  6  4 10  8 20 11 19  9
       45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68
border  2  4  2  1  3  2  1  1  3  1  0  2  2  3  0  3  3  3  3  0  0  2  3  1
seed   15  2  9 11  4  8 12  4  6  8  7  7  3  3  4  3  3  4  2  9  4  2  1  4
total  17  6 11 12  7 10 13  5  9  9  7  9  5  6  4  6  6  7  5  9  4  4  4  5
       69 70 71
border  3  3  3
seed    1  1  1
total   4  4  4

从上面的总结,我可以看到聚类2由8186个种子点(核心点)组成,聚类1由2634个种子点组成,聚类5由561个点组成。

我将最大的簇定义为包含最多种子点的簇。因此,在这种情况下,最大的集群是集群 2。第一、第二、第三大集群是 2、1 和 5。

它们是否可以直接return 最大集群或一般 k-最大集群中的行(点)?

我可以用间接的方式来做。

  1. 我可以通过 db$集群.
  2. 因此,我可以用 db$cluster 创建一个新的数据框 df2 除了原始 x 列和 y 之外的新附加列 列。
  3. 然后,我可以根据簇号聚合df2 第三列并找出每个簇中的点数。
  4. 之后,我可以找到k-最大的组,分别是2、1和5 再次.
  5. 最后,我可以 select df2 中第三列值等于 2 的行到 return 最大簇中的点。

但是上述方法重新计算了 print(db).

摘要中所述的许多已知结果

dbscan 函数似乎没有保留数据。

library(fpc)
set.seed(665544)
n <- 600
df <- data.frame(x=runif(10, 0, 10)+rnorm(n, sd=0.2), y=runif(10, 0, 10)+rnorm(n,sd=0.2))
(dbs <- dbscan(df, 0.2))
#dbscan Pts=600 MinPts=5 eps=0.2
#        0  1  2  3  4  5  6  7  8  9 10 11
#border 28  4  4  8  5  3  3  4  3  4  6  4
#seed    0 50 53 51 52 51 54 54 54 53 51  1
#total  28 54 57 59 57 54 57 58 57 57 57  5

attributes(dbs)
#$names
#[1] "cluster" "eps"     "MinPts"  "isseed" 

#$class
#[1] "dbscan"

你的间接步骤不是那么间接(只需要两行),这些命令不会重新计算集群。所以只需 运行 这些命令,或者将它们放在一个函数中,然后在一个命令中调用该函数。

cluster_k <- function(dbs, data, k){
  kth <- names(rev(sort(table(dbs$cluster)))[k])
  data[dbs$cluster == kth,]
}

cluster_k(dbs=dbs, data=df, k=1)
##            x        y
## 3   6.580695 8.715245
## 13  6.704379 8.528486
## 23  6.809558 8.160721
## 33  6.375842 8.756433
## 43  6.603195 8.640206
## 53  6.728533 8.425067

## a data frame with 59 rows