为什么 Spark Mllib KMeans 算法非常慢?

Why is Spark Mllib KMeans algorithm extremely slow?

我遇到了与此 相同的问题,但我没有足够的积分来添加评论。我的数据集有 100 万行,100 列。我也在使用 Mllib KMeans,它非常慢。事实上,这项工作永远不会完成,我必须终止它。我正在 运行 在 Google 云 (dataproc) 上执行此操作。它 运行s 如果我要求较少数量的集群 (k=1000),但仍然需要超过 35 分钟。我需要它 运行 k~5000。我不知道为什么这么慢。考虑到 workers/nodes 的数量,数据已正确分区,100 万 x ~300,000 col 矩阵上的 SVD 需要大约 3 分钟,但当涉及到 KMeans 时,它就会进入黑洞。我现在正在尝试减少迭代次数(2 次而不是 100 次),但我觉得某处不对劲。

KMeansModel Cs = KMeans.train(datamatrix, k, 100);//100 iteration, changed to 2 now. # of clusters k=1000 or 5000

看来原因比较简单。您使用了相当大的 k 并将其与昂贵的初始化算法结合使用。

默认情况下,Spark 用作 K-means++ called K-means|| (see ) 的分布式变体。分布式版本大致为 O(k),因此 k 越大,启动速度越慢。这应该可以解释为什么在减少迭代次数时看不到任何改进。

训练模型时使用大 K 也很昂贵。 Spark 使用的是 Lloyds 的一个变体,它大约是 O(nkdi)

如果您期望数据结构复杂,那么很可能有比 K-Means 更好的算法来处理这个问题,但如果您真的想坚持使用它,您可以从使用随机初始化开始。

请尝试 k-means 的其他实现。 ELKI 中的某些变体比 Spark 更好,即使只有一个 CPU。您会惊讶地发现,您可以在不进入集群的情况下从单个节点获得如此多的性能!不幸的是,根据我的实验,您至少需要一个 100 节点的集群才能击败良好的本地实现。

我读到 these C++ versions 是多核(但单节点)并且可能是您现在可以找到的最快的 K-means,但我自己还没有尝试过(满足我的所有需求) , ELKI 版本非常快,在我最大的数据集上几秒钟内完成。