K-Means 聚类在一个聚类中有超过 50% 的点。如何优化它?

机器算法验证 聚类 k-均值 层次聚类 火花mllib
2022-04-10 13:12:24

我在 Spark 中运行聚类算法,我必须在 K-Means 和 Bisecting-Kmeans 之间进行选择。然而,两者之间唯一不同的是运行时,因为性能同样糟糕。我有一个包含大约 130 万个条目的数据集,并且它们都经过了适当的矢量化处理。当我对 150-200 个集群运行算法时,最终输出至少只包含具有超过 400k 个条目的集群。其余的分配给其他人。具有 400k 条目的大集群是一个大问题。有什么方法可以优化集群(我对 Spark 算法工作流程几乎没有控制权)?有什么方法可以迫使那个大集群分裂?不幸的是,我也限制了计算可以占用多少内存空间。超过 250 个集群是有风险的,因为我可能会遇到 Java 堆空间错误。有任何想法吗,

4个回答

当应用于非连续数据时,这是 k-means 的非常典型的行为。这不是 k-means 的设计目的,您实际上是在按照其规范操作它。此外,k-means 对噪声非常敏感。您可能也有很多单元素集群?

Spark 也是最糟糕的集群工具之一。考虑从 BaylorML / Greg Hamerly 获取 C 代码。你会惊讶于它的速度有多快人们总是认为 Spark 会是最快的,但实际上它唯一优于的是 Hadoop MapReduce。根据您的稀疏性,1.3 Mio 点仍应适合单台机器的主内存。然后像 BaylorML 和 ELKI 这样的工具将会大放异彩,并且比 Spark 快很多。

但这并不能真正帮助您解决聚类问题,因为它很可能是数据问题。

我建议您这样做 A)可视化您的数据和聚类结果(PCA 比 tSNE 更合适,因为它可以更好地保留距离,因此您可以看到异常值!) B)从样本开始,而不是一次全部 130 万!只有在您有工作方法后才能扩大规模。您可能需要使用除 k-means 之外的其他聚类算法...

我正在使用 K 表示从 Tf Idf 矩阵的 SVD 对“单词”矩阵进行聚类并得到类似的结果。我找到了这个大集群的特征平方和,发现它们都是低量级的词。也与您的情况相似,我得到了很多 1 词簇。为了解决这个问题,我只选择了幅度在 0.025 和 1 之间的数据点。(你可以尝试适合你的规模的幅度。我的基于具有 400 列的正交矩阵)。

我不能说这是最好的方法,但它有所帮助。

非常有趣的是,您使用二等分 k-means 获得了一个包含 400k 条目的巨型集群。

二等分 k-means 迭代地将具有最高差异的集群分解为更小的集群。由于您已经生成了 100 多个集群,因此在我看来,400k 条目集群可能具有非常高的相似性分数。

我会尝试通过分层抽样和 t-SNE 来可视化集群。这可能是 400k 条目比我们想象的更加同质化。

当您说“优化集群”时,我认为这意味着您希望以有效的方式划分集群。

在运行 k-means 或二等分 k-means 之前,建议对您的数据运行主成分分析 (PCA)PCA 生成聚类数和组内平方和的碎石图,组内 SSE 趋于平稳的点表示理想的聚类数。

以下链接也可能对您有用:

https://spark.apache.org/docs/1.2.1/mllib-dimensionality-reduction.html#principal-component-analysis-pca

运行这个测试,看看你是否仍然在一个集群中得到如此高浓度的观察。可能是 150-200 个集群的估计实际上与更现实的估计有很大不同。