免责声明:我在 Stackoverflow 上发布了这个问题,但我认为这可能更适合这个平台。
您如何测试自己的多维数据集的 k-means 实现?
我正在考虑在数据上运行一个已经存在的实现(即Matlab)并将结果与我的算法进行比较。但这需要两种算法的工作方式大致相同,并且两种结果之间的映射可能不是小菜一碟。
你有更好的主意吗?
免责声明:我在 Stackoverflow 上发布了这个问题,但我认为这可能更适合这个平台。
您如何测试自己的多维数据集的 k-means 实现?
我正在考虑在数据上运行一个已经存在的实现(即Matlab)并将结果与我的算法进行比较。但这需要两种算法的工作方式大致相同,并且两种结果之间的映射可能不是小菜一碟。
你有更好的主意吗?
k-means 包含一个随机分量,因此除非您具有完全相同的实现并使用相同的起始配置,否则您不太可能获得相同的结果。但是,您可以查看您的结果是否与众所周知的实现一致(不了解 Matlab,但 R 中 k-means 算法的实现已得到很好的解释,请参阅Hartigan & Wong,1979 年)。
至于比较两个系列的结果,如果要多次运行,标签切换仍然存在问题。同样,在e1071 R 包中,有一个非常方便的函数 (; matchClasses()
) 可用于在双向分类表中查找两个类别之间的“最佳”映射。基本上,这个想法是重新排列行以最大化它们与列的一致性,或者使用贪婪方法并置换行和列,直到对角线上的总和(原始一致性)最大。还提供了Kappa统计量等协议系数。
最后,关于如何对您的实现进行基准测试,有很多免费可用的数据,或者您可以模拟专用数据集(例如,通过有限混合模型,请参阅MixSim包)。
两组结果之间的映射很容易计算,因为您在测试中获得的信息可以表示为一组三元组:第一个分量是(多维)点,第二个是(任意)簇标签由您的算法提供,第三个是由参考算法提供的(任意)集群标签。用构造标签对的分类表:如果结果一致,则为置换矩阵的倍数。也就是说,每一行和每一列都必须恰好有一个非零单元格。这是一个简单的程序检查。将与该理想值的微小偏差跟踪回单个数据点也很简单,因此您可以准确地看到两个答案是否完全不同。我不会费心计算一致性的统计度量:要么有完美的一致性(直到排列),要么没有,在后一种情况下,您需要追踪所有的分歧点以了解它们是如何发生的。结果要么同意,要么不同意;任何数量的分歧,即使只是在某一点上,都需要检查。
您可能希望使用几种数据集进行测试:(1)具有已发布 k-means 结果的已发布数据集;(2) 具有明显强聚类的合成数据集;(3) 没有明显聚类的合成数据集。(1) 是在编写任何数学或统计程序时使用的好原则。(2)在很多方面很容易做到,例如通过生成一些随机点作为聚类中心,然后通过相对少量随机置换聚类中心来生成点云。(3) 提供一些可能发现意外行为的随机检查;同样,这是一个很好的通用测试规则。
此外,考虑创建数据集,通过位于极端解决方案之间的边界来强调算法。这需要创造力和对算法的深刻理解(大概你有!)。在任何情况下我都想检查的一个例子是形式的向量集,其中是一个没有零分量的向量,并且采用顺序整数值。我还想检查形成等边多边形的向量集的算法。在任何一种情况下,不是的倍数的情况都特别有趣,包括其中小于。_ _ 这些情况的共同点是(a)他们使用问题的所有维度,但是(b)正确的解决方案在几何上是显而易见的,并且(c)有多个正确的解决方案。
和维中形成随机等边多边形。(一个好方法是让它们的分量是独立的标准正态变量。)重新缩放它们有单位长度;让我们称这些和 。通过公式 }中删除组件
通过重新以获得单位长度来获得如果您愿意,可以随机和向量和维随机二维子空间的正交基。个顶点的等边多边形由的集合获得,因为整数的范围从通过。)
一种非常简单的“天真”方法是使用简单的合成数据,因为每个实现都应该产生相同的集群。
Python中的示例import numpy as np
:
test_data = np.zeros((40000, 4))
test_data[0:10000, :] = 30.0
test_data[10000:20000, :] = 60.0
test_data[20000:30000, :] = 90.0
test_data[30000:, :] = 120.0
因为n_clusters = 4
它应该给你一个排列[30, 60, 90, 120]
由于 k-means 包含随机选择的决策(仅限初始化部分),我认为尝试您的算法的最佳方法是选择初始点并先将它们固定在您的算法中,然后选择另一个算法的源代码和以同样的方式固定点。然后你可以比较真实的结果。