我正在使用Apache Spark和Scala。我有一个字符串的RDD,Int
val counts =words.map(word => (word, 1)).reduceByKey((a,b) => (a + b)) 现在我按键减少了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)
}发布于 2014-12-06 06:16:31
您正在尝试的内容将不起作用。
如果你只有一个distance(a, b)函数,那么解决这个问题是非常低效和复杂的。您需要使用RDD.cartesian来生成所有可能的(word1, word2)对。然后过滤掉距离太远的那些。现在你有了相似的单词对。让我们假设它们是(fox, fix)、(fix, six)和它们的反转。然后,您需要对fox、fix和six的计数求和。为此,您需要在图中找到由相似单词对定义的连接组件。一旦您有了每个单词的组件ID,您就可以将计数与组件ID相加。
我认为更好的解决方案是编写一个函数,将一个单词转换成它的“规范”形式。它将把forks、forking和forked变成fork。然后你就可以再次应用这个和reduceByKey了。
在没有Spark的情况下完成这一步将是最快的。一旦您使用Spark计算了counts,您就拥有了每个不同单词的微型数据集- one整数。最简单的方法是先collect它,然后在本地使用map和groupBy counts。
https://stackoverflow.com/questions/27323340
复制相似问题