Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/svg/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Algorithm 寻找共同的集群_Algorithm_Cluster Analysis_Data Mining - Fatal编程技术网

Algorithm 寻找共同的集群

Algorithm 寻找共同的集群,algorithm,cluster-analysis,data-mining,Algorithm,Cluster Analysis,Data Mining,我遇到了以下问题: 假设我们有一组n样本,我们想将它们分类为k类,标记为1-k。我们运行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

我遇到了以下问题:

假设我们有一组
n
样本,我们想将它们分类为
k
类,标记为
1-k
。我们运行
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),因为它是唯一一对在所有输出中分类相同的聚类。

对于每个样本,将M个聚类算法的输出视为字符串的M个字符。现在有n个长度为M的字符串,需要找到重复的字符串。一种实用的方法是为每个字符串计算一个哈希代码——事实上,您可以构建一个表,将哈希代码映射到具有该哈希代码的字符串列表。具有不同哈希代码的字符串必须不同。如果您有一个具有相同哈希代码的字符串集合,请首先将每个字符串与第一个字符串与该哈希代码进行比较。如果它们都是相同的,那么您已经确认哈希代码不会很快产生误导性冲突。如果它们不完全相同,则有一个子集合与第一个字符串相同,另一个子集合需要重复比较

如果哈希代码不会产生误导性的冲突,则可以在线性时间内将字符串分成簇。如果是这样的话,您可能需要如上所述的二次时间


线性时间解决方案可能不切实际,它是将字符串连接起来,用迄今为止没有见过的字符将它们分开,然后运行线性时间后缀树或后缀数组创建程序。这将按树或数组顺序对字符串进行排序,然后通过按顺序遍历字符串,将每个字符串与下一个字符串按顺序进行比较,找到簇之间的划分。

可用于有效估计两个簇之间的相似性。它的时间在元素数量上是线性的,因此它会将您的运行时间降低到O(n*k^2*j)(其中j是最小哈希使用的哈希函数的数量,更高的值会给出更准确的结果)。

分析集群,而不是数据点,例如通过计算列联表

如果您还没有对集群内容进行预排序(以实现高效的交叉),那么这将很容易让您将集群内容排序到
O(M*k*k*n)
加上
O(n log n)


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

我得到的是,你需要检查任何两个输出在结构上是否确实相似,但你只能想到O(n^2)算法来实现这一点。如果您的问题是上述问题,则优化如下:-

Psuedo代码:-

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

总体复杂度:-
O(n*M)
用于集合计算,而
O(M*logM)
用于获得相似的输出,因此
O(M*(n+logM))

定义您所说的公共簇是什么意思?@DavidMahone:请参见示例对每个簇中的样本进行排序,然后在每个算法的输出中对聚类进行排序。@Roy sry我的回答完全是胡说八道。我没有正确地理解你。样品中有多少元素?样本是否包含相同的元素?如果元素比样本少很多,您可以对输出矩阵进行排序并检查重复行。谢谢,但如果我理解得很好,我的示例中的第1行和第3行将产生不同的哈希,但是我们希望它们相似。您能解释第1行和第3行是什么以及为什么希望它们相同吗。在问题中,你给示例A、B、C和D贴上标签,你说唯一通用的集群是A和B。我的解决方案是A是“112”,B是“112”,所以它们是相同的,但C是“221”,D是“111”,它们是不同的。这些线意味着A、B在所有输出中都在同一集群中进行了计算,虽然被分配了不同的标签。谢谢。我不太清楚你所说的“分析集群”是什么意思。我对你的其他评论也很好奇,尽管我并没有确切地分析k-means结果;不要比较单点。谢谢。我对这些方法有点熟悉,但是我希望找到一个精确的算法。我的问题是找到所有输出中结构相同的样本。理论上不可能有。你的代码就是这样做的吗?谢谢。@Roy如果你说的“结构相同”是指在两个输出中使用相同的元素对任何元素进行分组,那么代码就会发现这种相似性
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)