将每个 RDD 值与 Scala 中 RDD 中的所有其他值配对

Posted

技术标签:

【中文标题】将每个 RDD 值与 Scala 中 RDD 中的所有其他值配对【英文标题】:pairing each RDD value with all the other values in RDD in scala 【发布时间】:2017-03-31 03:12:15 【问题描述】:

我试图将 RDD 中的每个值与同一 RDD 的所有其他值配对。但我无法想出一个合适的解决方案。

RDD : 下图表示带有一对 as-> (UserId, MovieName::Rating) 的 RDD 数据。

我想将每个用户的电影名称和评分配对如下:

从上图看:

用户 1 将 Edison Kinetoscope.. 评为 10La sortie... 作为 10 用户 2 将 The Arrival .. 评为 8Le manoir.. 为 7Edison Kinetoscope.. 为 7 等。 .

所以,输出应该是..

**key**: (Edison Kinetoscopic,La sortie des)  
**Value** : (10,10), (7,8)   -> Since user 1 and user two rated these two movies  
**Key**: (The Arrival, Le manoir)  
**value**: (8,7)    -> only user-2 rated these two movies. 

任何帮助表示赞赏。

【问题讨论】:

为每个用户获取电影的强大功能似乎很昂贵。如果只按每部电影分组,你确定不能做你想做的事吗?这个(我认为是协同过滤推荐系统)的目标是什么? @vefthym 是对的。计算所有对是一项非常昂贵的操作。 @vefthym 我知道该操作非常昂贵,尤其是在处理大数据时。但我使用相关值来推荐电影。所以我认为我必须将每个用户的电影和评分对配对。 【参考方案1】:

如果您正在尝试构建推荐系统,或计算电影与电影的相似度,那么一定有更好的方法来做到这一点。

但是,要解决您的问题,您可以执行以下操作:

val rdd = sc.parallelize(List(
      (1,"Edison", 10),
      (1,"La sortie", 10),
      (2,"The Arrival", 8),
      (2,"Le manoir", 7),
      (2,"Edison", 7),
      (2,"La sortie", 8),
      (2,"Le voyage", 8),
      (2,"The Great", 7)
))

// first group user movies
val pairings = rdd.mapcase (user,movie,rating) => (user, List((movie,rating))).reduceByKey(_++_)

// then get all pairs for each user
val allPairs = pairings.flatMapcase (user, movieRatings) => (1 until movieRatings.length).flatMap(i => movieRatings.zip(movieRatings drop i))

// re-structure pairings into format we want
val finalPairing = allPairs.mapcase ((m1,r1),(m2,r2)) => m1.compareTo(m2) match case -1 => ((m1,m2),List((r1,r2))); case _ => ((m2,m1),List((r2,r1))).

// group by pairings
val groupByPair = finalPairing.reduceByKey(_++_)

// look at our pairings
pairings.take(100).foreach(println)

需要compareTo 来保证电影在元组中以相同的顺序出现,因此可以进行分组。

【讨论】:

很遗憾,此解决方案无法扩展。 我认为该解决方案将与所描述问题的任何解决方案一样扩展。断点当然是当数据集中出现两部热门电影时,我们在地图函数中得到了密集的工作。它应该运行,但是它会很慢。 真的,我认为这个问题可能不是解决另一个问题的正确方法。如果它是推荐人,我会看看 ALS,例如 :) @BenHorsburgh。你是对的,与这种配对相比,使用协同过滤和 ALS 算法是处理此类问题的更好方法。由于我试图使用相关值来解决问题,因此我需要生成电影和评分对。感谢您的解决方案

以上是关于将每个 RDD 值与 Scala 中 RDD 中的所有其他值配对的主要内容,如果未能解决你的问题,请参考以下文章

如何将 RDD [GenericRecord] 转换为 scala 中的数据框?

将 Scala 的 K-means 应用于 rdd 的每个元素。

scala如何取出rdd中的每一个元素

将 RDD 保存到 Scala 中的文本文件

Scala - 将 RDD[String] 转换为地图

Scala:RDD映射中的任务不可序列化由json4s“隐式val格式= DefaultFormats”引起