我有一个相当大的数据集,包含约75,000个观察值和7列,其中包含stats:hclust
无法支持的警报数据详细信息(崩溃RStudio
)。通过几次搜索,我发现Rclusterpp.hclust
据报道可以降低层次集群的复杂性和资源分配,因此我尝试了一下。它大约需要5分钟左右的时间,并且确实提供了树状图,但是如果我尝试使用cutree
并指定高度或多个簇,则会得到奇怪的结果。当使用如下所示的38个观察值的小样本时,我看到了相同的问题。我是在做错什么还是Rclusterpp.hclust包有问题吗? (在R 3.4.1中运行软件包3.4.1)
样本数据集如下所示:
dataset
# DAY COUNT LOCATION M1 M2 HOURS SOURCE
#1 238 2 222307 1 1 5437 1008
#2 238 1 222307 2 1 5437 1008
#3 238 5 222307 3 2 5437 1008
#4 238 2 222307 4 3 5437 1008
#5 238 14 222307 5 1 5437 1008
#6 238 4 222307 5 1 5437 1008
#7 238 14 222307 6 2 5437 1008
#8 238 3 222307 1 1 5437 1008
#9 238 1 222307 2 1 5437 1008
#10 238 1 222307 4 3 5437 1008
#11 238 2 222307 4 3 5437 1008
#12 238 2 222307 4 3 5437 1008
#13 238 5 222307 5 1 5437 1008
#14 238 11 222307 5 1 5437 1008
#15 238 1 222307 5 1 5437 1008
#16 238 3 222307 5 1 5437 1008
#17 238 18 222307 6 2 5437 1008
#18 238 2 222307 7 4 5437 9
#19 238 2 222307 8 4 5437 10
#20 238 3 222307 9 5 5437 1008
#21 238 2 222307 10 6 5437 865
#22 238 9 222307 11 7 5437 10
#23 238 2 222307 12 7 5437 10
#24 238 1 222307 12 7 5437 10
#25 238 5 222307 11 7 5437 10
#26 238 2 222307 8 4 5437 10
#27 238 3 222307 13 8 5437 864
#28 238 3 222307 14 8 5437 864
#29 238 1 222307 11 7 5437 10
#30 238 3 222307 11 7 5437 10
#31 238 2 222307 15 7 5437 10
#32 238 5 222307 11 7 5437 10
#33 238 2 222307 16 7 5437 10
#34 238 2 222307 17 7 5437 10
#35 238 3 222307 18 7 5437 10
#36 238 2 222307 15 7 5437 10
#37 238 6 222307 11 7 5437 10
#38 238 3 222307 19 7 5437 10
DAY
,HOURS
和COUNT
是实数值,而LOCATION
,M1
,M2
和SOURCE
是数字编码的分类值。使用stats:hclust,我可以得到一个群集,该群集确实很好地表示了数据,并且确实按预期的那样在该样本的所有观测值之间区分了两个主要的警报事件群集(即树状图中的观测编号是应该分组的警报):
d1 <- dist((as.matrix(scale(dataset))))
hc1 <- hclust(d1, method = "single")
cutree(hc1,2)
# 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 #27 28 29 30 31 32 33 34 35 36 37 38
# 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 2 2 1 1 2 2 2 2 2 #1 1 2 2 2 2 2 2 2 2 2 2
plot(hc1)
但是,如果在
Rclusterpp:hclust
中执行相同的操作,则会得到比我指定的集群更多的集群(在这种情况下,如本小样本所示,当我要求2时,我得到了3)。当我在大型数据集上运行时,仅需要几个,便得到将近20,000个群集。d2 <- dist((as.matrix(scale(dataset))))
hc2 <- Rclusterpp.hclust(d2, method = "single")
cutree(hc2,2)
# 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 #27 28 29 30 31 32 33 34 35 36 37 38
# 1 1 1 1 1 1 1 1 1 1 2 2 1 1 1 1 1 3 3 1 1 3 3 3 3 3 #1 1 3 3 3 3 3 3 3 3 3 3
plot(hc2)
知道为什么会这样吗?谢谢。
最佳答案
我研究了一下,看来Rclusterpp.hclust
的返回值与merge
stats'
并不完全对齐(写成hclust
矩阵)。
从hclust
文档中,返回列表的merge
组件为:
一个n-1 x 2矩阵。合并的第i行描述了在群集的第i步中群集的合并。如果行中的元素j为负,则在此阶段将观察值-j合并。如果j为正,则合并是与在算法的(较早)阶段j形成的群集进行的。因此,合并中的否定条目表示单例的聚集,而积极的条目表示非单例的聚集。
对于C
的cutree
实现,似乎括号(earlier
)中的单词很重要。
查看head(hc2$merge)
,我们看到以下内容:
[,1] [,2]
[1,] -2 -9
[2,] -25 -32
[3,] -31 -36
[4,] -19 -26
[5,] -4 6
[6,] -11 -12
因此,在第五行上,有一个指向第六步的“指针”,它朝着意外的方向前进。
相反,如果我们重新安排
merge
组件(交换行和“指针”),事情看起来还不错:# non-generic replacements for specific data example
hc3 <- hc2
hc3$merge[5, ] <- c(-11,-12)
hc3$merge[6, ] <- c(-4,5)
hc3$merge[13, ] <- c(-10,6)
cutree(hc3, 2)
您可以编写一个函数来处理
merge
矩阵的这种重组,以使事情始终如您所愿地工作(可能是cutree
的包装器)。最后请注意,Github上存在一个与此相关的问题,您可以在其中找到一些讨论和跨包比较:
https://github.com/nolanlab/Rclusterpp/issues/4