R中大数据的轮廓计算

silhouette calculation in R for a large data

我想计算轮廓以进行聚类评估。 R 中有一些包,例如 cluster 和 clValid。这是我使用集群包的代码:

# load the data
# a data from the UCI website with 434874 obs. and  3 variables
data <- read.csv("./data/spatial_network.txt",sep="\t",header =  F)

# apply kmeans
km_res <- kmeans(data,20,iter.max = 1000,
               nstart=20,algorithm="MacQueen")

# calculate silhouette
library(cluster)   
sil <- silhouette(km_res$cluster, dist(data))

# plot silhouette
library(factoextra)
fviz_silhouette(sil)

该代码适用于较小的数据,比如具有 50,000 obs 的数据,但是当数据有点大时,我会收到类似 "Error: cannot allocate vector of size 704.5 Gb" 的错误。这可能是 Dunn 索引和大型数据集的其他内部索引的问题。

我的电脑有 32GB 内存。问题来自于计算 dist(data)。我想知道是否可以不预先计算 dist(data) ,并在轮廓公式中需要时计算相应的距离。

非常感谢您就此问题以及我如何计算大型和超大型数据集的剪影提供的帮助。

您可以自己实现 Silhouette。

它只需要每个距离两次,所以不需要存储整个距离矩阵。它可能 运行 有点慢,因为它计算了两次距离,但同时更好的内存效率可能会弥补这一点。

虽然还需要很长时间。

您应该考虑仅使用子样本(您真的需要考虑 所有 点吗?)以及简化剪影等替代方案,尤其是 KMeans...使用此类方法的额外数据,您只会获得很少的收益。所以你可以只使用一个子样本。

A​​nony-Mousse 的回答很完美,尤其是子采样。由于计算成本的增加,这对于非常大的数据集非常重要。

这是另一种计算轮廓和邓恩指数等内部指标的解决方案,使用 clusterCrit 的 R 包。 clusterCrit 用于计算聚类验证指标,不需要预先输入完整的距离矩阵。但是,正如 Anony-Mousse 所讨论的那样,它可能会很慢。请参阅下面 link 的 clusterCrit 文档: https://www.rdocumentation.org/packages/clusterCrit/versions/1.2.8/topics/intCriteria

clusterCrit 还计算大多数用于集群验证的内部度量。

示例:

intCriteria(data,km_res$cluster,c("Silhouette","Calinski_Harabasz","Dunn"))

如果可以在不使用距离矩阵的情况下计算 Silhouette 指数,或者您可以使用 clues 包,优化 cluster 包使用的时间和内存。这是一个例子:

library(rbenchmark)
library(cluster)
library(clues)

set.seed(123)
x = c(rnorm(1000,0,0.9), rnorm(1000,4,1), rnorm(1000,-5,1))
y = c(rnorm(1000,0,0.9), rnorm(1000,6,1), rnorm(1000, 5,1))
cluster = rep(as.factor(1:3),each = 1000)

df <- cbind(x,y)
head(df)
               x           y
[1,] -0.50442808 -0.13527673
[2,] -0.20715974 -0.29498142
[3,]  1.40283748 -1.30334876
[4,]  0.06345755 -0.62755613
[5,]  0.11635896  2.33864121
[6,]  1.54355849 -0.03367351

两个函数的运行时比较

 benchmark(f1 = silhouette(as.integer(cluster), dist = dist(df)),
           f2 = get_Silhouette(y = df, mem = cluster))
  test replications elapsed relative user.self sys.self user.child sys.child
1   f1          100   15.16    1.902     13.00     1.64         NA        NA
2   f2          100    7.97    1.000      7.76     0.00         NA        NA

两个函数在内存使用上的比较

library(pryr)
object_size(silhouette(as.integer(cluster), dist = dist(df)))
73.9 kB
object_size(get_Silhouette(y = df, mem = cluster))
36.6 kB

作为结论clues::get_Silhouette,它减少了使用的时间和内存。