【发布时间】:2012-02-06 11:24:46
【问题描述】:
编辑:像 casperOne 向我指出这个问题是重复的。无论如何,这里有一个更笼统的问题,涵盖了这个问题:https://stats.stackexchange.com/questions/8744/clustering-procedure-where-each-cluster-has-an-equal-number-of-points
我的要求
在一个项目中,我需要将 n 个点 (x,y) 分组到 k 个大小相等 (n / k) 的集群中。其中 x 和 y 是双浮点数,n 的取值范围为 100 到 10000,k 的取值范围为 2 到 100。在算法运行之前 k 也是已知的。
我的实验
我开始使用http://en.wikipedia.org/wiki/K-means_clustering 算法来解决这个问题,该算法可以很好地快速生成大小大致相同的 k 个集群。
但我的问题是,K-means 产生大小大致相同的集群,我需要集群的大小完全相同(或更准确地说:我需要它们的大小在 floor(n / k) 和 ceil(n / k))。
在您向我指出之前,是的,我在这里尝试了第一个答案K-means algorithm variation with equal cluster size,这听起来是个好主意。
主要思想是通过K-means对簇产生的数组进行后处理。从最大的集群到最小的集群。我们通过将额外的点移动到另一个最近的集群来减小具有超过 n / k 个成员的集群的大小。更不用说已经减少的集群了。
这是我实现的伪代码:
n is the number of point
k is the number of cluster
m = n / k (the ideal cluster size)
c is the array of cluster after K-means
c' = c sorted by size in descending order
for each cluster i in c' where i = 1 to k - 1
n = size of cluster i - m (the number of point to move)
loop n times
find a point p in cluster i with minimal distance to a cluster j in c' where j > i
move point p from cluster i to cluster j
end loop
recalculate centroids
end for each
这个算法的问题是在接近过程结束时(当 i 接近 k 时),我们必须在 c' 中选择一个簇 j(其中 j > i 因为我们需要不理会已经处理过的簇),但是我们发现的这个簇 j 可能离簇 i 很远,从而打破了簇的概念。
我的问题
是否有可以满足我要求的后 K-means 算法或 K-means 变体,还是我从一开始就错了,我需要寻找其他聚类算法?
PS:我不介意自己实现解决方案,但如果我可以使用库,最好是在 JAVA 中。
【问题讨论】:
-
如何选择初始集群?
-
簇的数量和它们的初始质心由用户(人类)选择。
-
@casperOne,您将此问题作为重复问题关闭了吗?我实际上在我的问题中说过,我在stackoverflow.com/questions/5452576/… 中尝试了建议的解决方案但没有成功,我试图在这里更进一步,询问是否有其他解决方案。但是,如果您决定将其关闭,我不会生您的气 :) 我只是不认为它是重复的。
-
@Pierre-DavidBelanger:您的问题没有很好地将自己与其他问题区分开来。如果您可以进行重大更改以指出差异(在问题中,而不是 cmets),那么它可以重新打开。另外,您是否考虑过在stats.stackexchange.com 上提问?鉴于该网站的存在,这个问题有点离题。
-
您是否尝试了现有问题的所有答案?例如elki-project.github.io/tutorial/same-size_k_means 的教程?是java,看来满足你的要求了?
标签: algorithm cluster-analysis k-means