在 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 对小短语进行聚类的主要内容,如果未能解决你的问题,请参考以下文章