我在一组我想要聚类的对象上尝试R包apcluster
,但是我遇到了性能/内存问题,我怀疑我做得不对。我想听听你的意见。
简而言之:我有一组约13000个对象。每个对象与一组2到5个“特征”相关联。任何两个对象i和j之间的相似性(最终我希望聚类)等于它们共有的特征数除以它们“跨越”的不同特征的总数。例如。如果i = {a,b,c}且j = {c,d},那么sim [i,j] = 1/4 = 0.25,因为它们只有一个共同的特征({c}),总的来说它们描述了4个不同的特征({a,b,c,d})。
计算我的NxN相似性矩阵在理论上不是问题:如果每个对象的特征都存储为列表,则可以使用集合操作来完成;或者可以将特征旋转到1和0的矩阵,其中每列都是一个特征,然后R的函数dist
和method="binary"
就可以了。
在实践中然而,第一个问题是这种相似性计算非常慢。对于13 K物体,计算有大约84.5 M个相似度,但这对于现代计算机来说听起来并不那么糟糕。我不明白为什么要花几个小时这么做。而且据我所知,设置操作版本应该更快,实际上比dist
慢得多。 [另一个名为fingerprint
的软件包应该更有效地处理这种情况,但到目前为止我还没能使它工作,它在尝试制作他们称之为'featvec'的对象时会产生很多错误]
要考虑的另一件事是每个对象的2-5特征不是很重复。可能存在一组100个左右的对象,它们之间至少有一个共同特征,但是其他12.9个K对象中没有一个具有与这100个对象相同的任何特征。结果是旋转的特征矩阵非常稀疏(如果我们认为0是空的)。在旋转矩阵中有大约4000列,每行最多有5个1。我想知道这是否会对dist
的性能产生负面影响,因为它必须乘以大量的0才能被忽略。
您觉得应该花几个小时将
dist
应用到我所描述的矩阵中似乎是正常的吗?你能否提出一种不同的方法来计算利用矩阵稀疏性的相似性?
无论如何,我设法得到dist
的输出,然而它有'dist'类,并且是 distance 矩阵,而不是相似的矩阵,所以我不得不使用{ {1}}能够将相似性矩阵1 - as.matrix(distance_matrix)
作为输入。
那是我遇到第一个“记忆”问题的时候。 R表示由于其大小而无法分配矢量。我尝试了常用的技巧,但最终我得不到超过4 GB,而且我的矩阵(显然)更大。
我通过将新矩阵分配给旧的“自我”来克服这一点。
然后当我将这种相似性矩阵提交到apcluster
时,再次出现了矢量大小错误,好像apcluster
做的第一件事就是从我拥有的东西中创建了一些其他的大对象喂它。
我查看了apcluster
中的as.Sparse...
,但考虑到你必须首先计算完整矩阵,它似乎没什么帮助。
最后,唯一有效的方法是apcluster
的“杠杆亲和力传播”,然而这是近似值。
有人知道我是否以及如何做得更好?例如。首先转动数据是明智的,还是应该坚持列表并设置操作?或者,初始矩阵稀疏的事实是否可以用于直接计算稀疏相似性矩阵,而不是完全计算它并将其减少到稀疏?
任何建议都将不胜感激。谢谢!
是的,是的,我看到了这个帖子:Cluster Analysis in R on large sparse matrix;这似乎没有得到最终的回答。答案 0 :(得分:0)
R解释器真的很慢。
所以你应该使用R主要来“驱动”你的程序,但是在C或FORTRAN中实现所有计算重量。
您没有显示您正在使用的代码,但我想它涉及嵌套for循环?尝试在R中没有任何for循环重写它,或者在C中重写它。
但无论如何,AP群集将始终保持非常缓慢。它涉及O(n²)矩阵上的许多遍历,即它非常严重。