我遇到与post相同的问题,但我没有足够的积分在那里添加评论。我的数据集有1百万行,100列。我也使用Mllib KMeans而且它非常慢。这项工作实际上从未结束,我必须杀死它。我在谷歌云(dataproc)上运行它。如果我要求较少数量的群集(k = 1000),它仍会运行,但仍需要超过35分钟。我需要它运行k~5000。我不知道为什么这么慢。考虑到工人/节点的数量,数据被正确分区,并且在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
答案 0 :(得分:5)
看起来原因相对简单。您使用相当大的k并将其与昂贵的初始化算法相结合。
默认情况下,Spark使用名为K-means ||的K-means++的分布式变体(见What exactly is the initializationSteps parameter in Kmeans++ in Spark MLLib?)。分布式版本大致 O(k)因此,如果k值较大,则可以预期启动速度较慢。这可以解释为什么在减少迭代次数时没有看到任何改进。
在训练模型时使用大K也很昂贵。 Spark使用Lloyds的变体,大致是 O(nkdi)。
如果您期望数据的复杂结构,那么很可能有更好的算法来处理这个问题而不是K-Means,但是如果您真的想坚持使用它,那么首先要使用随机初始化。
答案 1 :(得分:2)
请尝试k-means的其他实现。有些像ELKI中的变体 way 比Spark更好,即使只在一个CPU上也是如此。您会惊讶地发现,单个节点可以获得多少性能,而无需进入群集!根据我的实验,不幸的是,至少需要一个100节点集群才能击败好的本地实现。
我读到these C++ versions是多核的(但是单节点),可能是你现在可以找到的最快的K-means,但我还没有尝试过(尽管我的需要, ELKI的版本速度非常快,几秒钟就完成了我最大的数据集。