【问题标题】:Spark - correlation matrix from file of ratingsSpark - 评级文件中的相关矩阵
【发布时间】:2015-10-14 05:50:18
【问题描述】:

我对 Scala 和 Spark 还很陌生,我无法从评级文件中创建相关矩阵。它类似于this question,但我的矩阵形式数据稀疏。我的数据如下所示:

<user-id>, <rating-for-movie-1-or-null>, ... <rating-for-movie-n-or-null>

123, , , 3, , 4.5
456, 1, 2, 3, , 4
...

目前最有前途的代码如下所示:

val corTest = sc.textFile("data/collab_filter_data.txt").map(_.split(","))
Statistics.corr(corTest, "pearson")

(我知道其中的 user_ids 存在缺陷,但我愿意暂时忍受)

我期待这样的输出:

1,   .123, .345
.123, 1,   .454
.345, .454, 1

这是一个矩阵,显示了每个用户与其他每个用户之间的关系。从图形上看,这将是一个相关图。

这完全是一个菜鸟问题,但我已经与它斗争了几个小时,似乎无法通过谷歌搜索。

【问题讨论】:

  • 您可以使用_.split(",").drop(1)轻松删除第一个元素,即包含用户标识的元素

标签: scala apache-spark


【解决方案1】:

我相信这段代码应该能完成你想要的:

import org.apache.spark.mllib.stat.Statistics
import org.apache.spark.mllib.linalg._
...
val corTest = input.map { case (line: String) => 
  val split = line.split(",").drop(1)
  split.map(elem => if (elem.trim.isEmpty) 0.0 else elem.toDouble)
}.map(arr => Vectors.dense(arr))

val corrMatrix = Statistics.corr(corTest)

在这里,我们将您的输入映射到 String 数组,删除用户 ID 元素,将您的空格清零,最后从结果数组创建一个密集向量。另外请注意,如果没有提供方法,则默认使用 Pearson 方法。

通过一些示例在 shell 中运行时,我看到以下内容:

scala> val input = sc.parallelize(Array("123, , , 3, , 4.5", "456, 1, 2, 3, , 4", "789, 4, 2.5, , 0.5, 4", "000, 5, 3.5, , 4.5, "))
input: org.apache.spark.rdd.RDD[String] = ParallelCollectionRDD[18] at parallelize at <console>:16

scala> val corTest = ...
corTest: org.apache.spark.rdd.RDD[org.apache.spark.mllib.linalg.Vector] = MappedRDD[20] at map at <console>:18

scala> val corrMatrix = Statistics.corr(corTest)
...
corrMatrix: org.apache.spark.mllib.linalg.Matrix =
1.0                  0.9037378388935388   -0.9701425001453317  ... (5 total)
0.9037378388935388   1.0                  -0.7844645405527361  ...
-0.9701425001453317  -0.7844645405527361  1.0                  ...
0.7709910794438823   0.7273340668525836   -0.6622661785325219  ...
-0.7513578452729373  -0.7560667258329613  0.6195855517393626   ...

【讨论】:

  • 真的很有帮助。非常感谢。解析现实生活中的 CSV 时出现索引越界错误。我在split.map(elem =&gt; if (elem.isEmpty) 0.0 else elem.toDouble) 的末尾添加了.padTo(100, 0.0),现在我得到了我想要的结果。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-11-30
  • 1970-01-01
  • 1970-01-01
  • 2020-11-29
  • 2012-11-04
相关资源
最近更新 更多