我遇到了以下问题:
想象一下,我们有一组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),因为它是唯一在所有输出中被分类相同的对。
答案 0 :(得分:0)
对于每个样本,将M个聚类算法的输出视为字符串的M个字符。现在你有n个长度为M的字符串,你需要找到重复的字符串。这样做的一种实用方法是为每个字符串计算哈希代码 - 事实上,您可以构建一个表,将哈希代码映射到具有该哈希代码的字符串列表。具有不同哈希码的字符串必须不同。如果您有一组具有相同哈希码的字符串,请首先将每个字符串与具有该哈希码的第一个字符串进行比较。如果它们都是相同的,那么您已经确认哈希码不会很快产生误导性冲突。如果它们不完全相同,则您有一个与第一个字符串相同的子集合,以及另一个您必须重复比较的子集合。
如果哈希码不会产生误导性冲突,您可以在线性时间内将字符串分成簇。如果是,您可以按上述方式进行二次时间。
可能不切实际的线性时间解决方案是连接字符串,用到目前为止看不到的字符将它们分开,然后运行线性时间后缀树或后缀数组创建程序。这会将字符串排序为树或数组顺序,然后您可以通过遍历字符串来查找集群之间的划分,以便按顺序将每个字符串与下一个字符串进行比较。
答案 1 :(得分:0)
Min-Hash可用于有效估计两个聚类之间的相似性。它的时间是元素数量的线性,因此它将你的运行时间降低到O(n * k ^ 2 * j)(其中j是Min-Hash使用的散列函数的数量,而更高的值给出更准确的结果)。
答案 2 :(得分:0)
分析群集,而不是数据点,例如通过计算列联表。
如果你没有对它们进行预先排序(为了有效交叉),这将很容易让你到O(M*k*k*n)
加上O(n log n)
来对你的群集内容进行排序。
我认为分析k-means结果并不值得。在相当复杂的数据上,它们只能与随机凸分区一样好。
答案 3 :(得分:0)
从我得到的是你需要检查任何两个输出是否实际上在结构上相似,但你只能想到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
时间复杂度: -
比较功能访问arr1&amp;中的所有元素。 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))