我有一个不透明对象列表。我只能计算它们之间的距离(不是真的,只是设置问题的条件):
class Thing {
public double DistanceTo(Thing other);
}
我想聚集这些对象。我想控制集群的数量,我希望“关闭”对象在同一个集群中:
List<Cluster> cluster(int numClusters, List<Thing> things);
任何人都可以建议(并链接到;-))一些聚类算法(更简单,更好!)或可以帮助我的库吗?
澄清大多数聚类算法都要求在一些N维空间中布置对象。该空间用于查找聚类的“质心”。就我而言,我不知道N是什么,也不知道如何从对象中提取坐标系。 我所知道的是两个对象相距多远。我想找到一个只使用该信息的良好聚类算法。
想象一下,基于对象的“气味”进行聚类。你不知道如何在2D平面上“闻出来”,但你知道两种气味是否相似。
答案 0 :(得分:6)
我认为您正在寻找K-Medoids。它就像K-means,因为你预先指定了簇的数量 K ,但它并不要求你有一个“平均”你正在聚类的对象的概念,比如K-意思是。
相反,每个群集都有一个代表性的 medoid ,它是最接近中间的群集的成员。您可以将其视为K-means的一个版本,它可以找到“中间人”而不是“手段”。您所需要的只是一个用于聚类事物的距离度量,我在我自己的一些工作中使用它的原因与您引用的原因完全相同。
Naive K-medoids不是最快的算法,但有一些快速的变种可能足以满足您的需要。以下是算法的说明以及R中实现文档的链接:
如果您需要更多信息,请here's a paper概述这些和其他K-medoids方法。
答案 1 :(得分:3)
这是一个聚类算法的大纲,它没有找到质心的K-means要求。
该算法肯定会聚集对象。但它的运行时是 O(n ^ 2)。此外,它还受到所选择的第一个 n 点的指导。
任何人都可以改进吗(更好的运行时性能,更少依赖于初始选择)?我很想看到你的想法。
答案 2 :(得分:2)
这是一个快速算法。
While (points_left > 0) {
Select a random point that is not already clustered
Add point and all points within x distance
that aren't already clustered to a new cluster.
}
或者,阅读the wikipedia page。 K-means聚类是一个不错的选择:
K-means算法将每个点分配给其中心(也称为质心)最近的聚类。中心是群集中所有点的平均值 - 也就是说,其坐标是群集中所有点上每个维度的算术平均值。
算法步骤为:
* Choose the number of clusters, k. * Randomly generate k clusters and determine the cluster centers, or directly generate k random points as cluster centers. * Assign each point to the nearest cluster center. * Recompute the new cluster centers. * Repeat the two previous steps until some convergence criterion is met (usually that the assignment hasn't changed).
这种算法的主要优点 是它的简单性和速度 允许它在大型数据集上运行。 它的缺点是它没有 每次运行产生相同的结果, 因为产生的集群依赖于 最初的随机分配。它 最小化群内方差,但是 不能确保结果有 全局最小方差。另一个 缺点是要求 可定义的概念 情况并非总是如此。对于这样 数据集k-medoids变体是 合适的。
答案 3 :(得分:1)
这种方法怎么样:
我认为这个算法应该会给你一个相当不错的聚类,尽管效率可能非常糟糕。为了提高效率,您可以更改步骤3,以便找到仅启动群集的原始对象的最小距离,而不是到群集中已有的所有对象的平均距离。
答案 4 :(得分:1)
系统发育DNA序列分析通常在文本字符串上使用层次聚类,具有[比对]距离矩阵。这是一个很好的R群集教程:
(捷径:直接进入“Hierarchical Agglomerative”部分......)
以下是其他一些[语言]库:
这种方法可以帮助确定有多少[k]个“自然”聚类,以及哪些对象可用作上述k-means方法的根。