2

我正在使用 Apache Spark 和 Scala。我有一个 String,Int 的 RDD

val counts =words.map(word => (word, 1)).reduceByKey((a,b) => (a + b))     

现在我通过 Key 减少了 RDD,但我想添加另一个功能来减少相似的单词。

我虽然使用 Levenshtein 距离、欧几里得距离或余弦距离。

那么,我怎样才能应用这些功能之一来减少我的 RDD?

例子:

RDD ->  (forks,12), (fork,4), (chair,15) , (table,1), (tables,11)

承认相似度算法有效,我怎样才能获得减少的 RDD,如:

RDD -> (fork,16), (table,12), (chair,15)

我试过类似的东西:

counts.foldLeft(){(x,y) => 
  if(x._1.euclideanDistance(y._1) > 0.9) 
    (x,x._2+y._2) 
}
4

2 回答 2

6

你正在尝试的将不起作用。

如果你只有一个distance(a, b)功能,解决问题确实效率低下且复杂。您需要使用RDD.cartesian来生成所有可能的(word1, word2)对。然后过滤掉距离太远的。现在你有了相似的词对。假设它们是(fox, fix),(fix, six)和它们的反转。然后,您想要总结 、 和foxfix计数six。为此,您需要在由相似词对定义的图中找到连接的组件。获得每个单词的组件 ID 后,您可以通过组件 ID 将计数相加。

我认为解决方案是编写一个可以将单词转换为“规范”形式的函数。它会变成forks,forking和。然后你可以一次又一次地应用这个。forkedforkreduceByKey

在没有 Spark 的情况下执行此步骤将是最快的。一旦你counts用 Spark 进行了计算,你就有了一个很小的数据集——每个不同的单词对应一个整数。这是最简单的,collect然后是本地的。mapgroupBy counts

于 2014-12-05T22:16:31.280 回答
0

@Daniel 的回复可能是解决整体问题的正确方法。

关于具体的q。当您if在折叠中进行操作时,您还需要提供else在您的情况下将保留 x 的当前计数

于 2014-12-08T08:02:10.843 回答