寻找共同的聚类

3

我遇到了以下问题:

假设我们有一组 n 个样本,我们想将其分类为标记为 1-kk 类。我们运行 M 种不同的聚类算法,得到 M 种不同的输出结果。问题是,在不同的输出结果中,相同的聚类可能会被赋予不同的标签。

如何找到所有输出结果之间的共同聚类?我认为显而易见的解决方案是对所有可能的样本对进行遍历,检查它们在每个输出结果中是否被归类为同一类别。这会带来 O(n^2*M) 的复杂度。

我们能否做得更好(也许可以加入一些假设)?

谢谢。

编辑

下面以一个例子说明。我们有4个样本,k=2,并得到以下输出结果:

A 1 1 2
B 1 1 2
C 2 2 1
D 1 1 1

在所有输出中,唯一常见的聚类是(A,B),因为它是唯一一个在所有输出中都被分类相同的一对。


请定义“常见集群”是什么意思? - David Mahone
@DavidMahone:请查看示例。 - Roy
将每个簇中的样本进行排序,然后对每个算法的输出中的簇进行排序。 - n. m.
@Roy 抱歉,我的回答完全是胡说八道。我没有理解你的意思。样本中有多少个元素?样本是否包含相同的元素?如果样本中的元素比样本数量少得多,您可以对输出矩阵进行排序并检查重复行。 - AbcAeffchen
4个回答

2

据我所知,您需要检查任何两个输出是否实际上具有相似的结构,但您只能想到使用O(n^2)算法来完成。如果您的问题是以上问题,则可以进行以下优化:

伪代码:

int arr1 = [1 1 2 2];
int arr2 = [2 2 1 1]; 

list sets1[k];
list sets2[k]; 

for(int i=0;i<n;i++) {
  sets1[arr1[i]-1].add(i);
  sets2[arr2[i]-1].add(i);
}
boolean flag = true;
for(int i=0;i<k;i++) {
  flag = flag && compare(sets1[arr1[i]-1],sets2[arr2[i]-1]);
  if(flag == false)
      return flag
}

return flag

时间复杂度 :-

比较函数最多只访问arr1和arr2中的所有元素一次,因此总体时间复杂度为O(n)

编辑 :-

如果你需要评估是否所有类似于小于O(M^2*n)的输出,则:

1. calculate sets for all M
2. Calculate hash for each set using standard hash functions.
3. if two set are equal then their hashes are also equal with high probability
4. Sort k hash for each output in O(logk)
5. Get all equivalent set using hash map in O(M*logM)

总体复杂度:计算集合的时间复杂度为O(n*M),获取相似输出的时间复杂度为O(M*logM),因此总时间复杂度为O(M*(n+logM))


我的问题是找到在所有输出中结构相同的样本。理论上可能没有这样的样本。你的代码能做到吗?谢谢。 - Roy
@Roy,如果您所说的“结构相同”是指在两个输出中,任何元素的分组都是由相同的元素完成的,那么该代码会找到这种相似之处。 - Vikram Bhat

0
对于每个样本,将M个聚类算法的输出视为字符串的M个字符。现在您有n个长度为M的字符串,需要查找重复项。一种实用的方法是为每个字符串计算哈希码-实际上,您可以构建一个表,将哈希码映射到具有该哈希码的字符串列表。具有不同哈希码的字符串必须不同。如果您有一组具有相同哈希码的字符串,请从将它们与具有该哈希码的第一个字符串进行比较开始。如果它们全部相同,则已确认哈希码没有快速产生误导性碰撞。如果它们不都相同,则您有一个子集合与第一个字符串相同,另一个子集合中您将不得不重复比较。
如果哈希码不会产生误导性碰撞,则可以在线性时间内将字符串分成簇。如果它产生,则可能像上面那样花费平方时间。
一种可能不切实际的线性时间解决方案是将字符串连接起来,用迄今未见过的字符分隔它们,然后运行线性时间后缀树或后缀数组创建程序。这将把字符串按树或数组顺序排序,您可以通过按顺序浏览字符串,并将每个字符串与下一个字符串进行比较,以找到集群之间的分割点。

谢谢,但如果我理解正确的话,我的示例中第1行和第3行将产生不同的哈希值,然而我们希望它们相似。 - Roy
你能解释一下第1行和第3行是什么意思,以及为什么你希望它们相同吗?在问题中,你将示例标记为A、B、C和D,并且说唯一的共同集合是A和B。我的解决方案会告诉你A是"112",B是"112",所以它们是相同的,但C是"221",D是"111",所以它们是不同的。 - mcdowella
这些代码行表示,在所有输出中,A、B被归类为同一聚类,尽管它们被分配了不同的标签。 - Roy

0

Min-Hash 可以用于高效地估计两个聚类之间的相似度。它的时间复杂度与元素数量成线性关系,因此可以将运行时间降至 O(n*k^2*j)(其中 j 是 Min-Hash 使用的哈希函数数量,较高的值会给出更准确的结果)。


谢谢。我对这些方法有点熟悉,但是我希望能找到一个准确的算法。 - Roy

0

分析聚类,而不是数据点,例如通过计算列联表。

这将使您轻松降至O(M*k*k*n)加上O(n log n),一旦对您的聚类内容进行排序(以实现高效交集),如果您没有预先对它们进行排序。

我认为分析k-means结果并不划算。在相当复杂的数据上,它们只能像随机凸分割一样好。


谢谢。不过我不太确定你所说的“分析聚类”的意思。我也对你的其他评论很好奇,尽管我并没有在分析k-means的结果。 - Roy
通过列联表比较聚类,不要比较单个数据点。 - Has QUIT--Anony-Mousse

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接