在 Spark 中使用 Kmeans 对小短语进行聚类

Posted

技术标签:

【中文标题】在 Spark 中使用 Kmeans 对小短语进行聚类【英文标题】:Using Kmeans to cluster small phrases in Spark 【发布时间】:2016-06-04 02:20:21 【问题描述】:

我有一个想要聚类的单词/短语列表(大约一百万)。我假设它是以下列表:

a_list = [u'java',u'javascript',u'python dev',u'pyspark',u'c ++']
a_list_rdd = sc.parallelize(a_list)

我遵循以下程序:

使用字符串距离(让我们说 jaro winkler 度量)我计算单词列表之间的所有距离,这将创建一个 5x5 矩阵,对角线为 1,因为它计算自身之间的距离。为了计算所有距离,我广播了整个列表。所以:

a_list_rdd_broadcasted = sc.broadcast(a_list_rdd.collect())

以及字符串距离计算:

import jaro
def ComputeStringDistance(phrase,phrase_list_broadcasted):
     keyvalueDistances = []
     for value in phrase_list_broadcasted:
         distanceValue = jaro.jaro_winkler_metric(phrase,value)
         keyvalueDistances.append(distanceValue)
     return (array(keyvalueDistances))

string_distances = (a_list_rdd
                             .map(lambda phrase:ComputeStringDistance(phrase,a_list_rdd_broadcasted.value))
                    )

并使用 K 方法进行聚类:

from pyspark.mllib.clustering import KMeans, KMeansModel
clusters = KMeans.train(string_distances, 3 , maxIterations=10,
    runs=10, initializationMode="random")
PredictGroup = string_distances.map(lambda point:clusters.predict(point)).zip(a_list_rdd)

结果:

PredictGroup.collect()

ut[73]: 
[(0, u'java'),
 (0, u'javascript'),
 (2, u'python'),
 (2, u'pyspark'),
 (1, u'c ++')]

还不错!但是,如果我有 100 万个观测值和大约 10000 个集群的估计值,会发生什么?阅读大量集群的一些帖子确实很昂贵。有没有办法解决这个问题?

【问题讨论】:

【参考方案1】:

k-means foes not 对距离矩阵进行运算(距离矩阵也不能缩放)。

K-means 也适用于任意距离函数。

这是关于最小化 方差,即均值的偏差平方和。

你正在做的工作是因为它是谱聚类的一半,但它既不是正确使用 k-means,也不是谱聚类。

【讨论】:

你的意思是我不应该使用 Kmean 来完成这项任务?有哪些替代方案?我已经通过使用 R 在字符串距离中使用层次聚类完成了相同的任务,但据我所知 pyspark 和 mllib 不支持它。 层次聚类确实适用于距离矩阵,并且可以支持其他距离,因此对于此类数据更好的选择,是的。仅当您的输入数据是向量场时才正确使用 k-means。

以上是关于在 Spark 中使用 Kmeans 对小短语进行聚类的主要内容,如果未能解决你的问题,请参考以下文章

Kmeans 聚类与火花中的地图减少

使用 Spark MLlib KMeans 从数据中预测集群

均值||用于 Spark 的情感分析

流式传输 Kmeans Spark JAVA

在 Spark 上训练 Kmeans 算法失败

使用 Spark KMeans 算法打印 ClusterID 及其元素。