计算scala中的余弦相似度

问题描述

我有一个包含 UserId、MovieId、tags 的文件 (tags.csv)。我想使用基于域的方法来计算标签间的余弦相似度。我只想显示喜剧的相关标签,并衡量与喜剧标签相关的每个标签的相似度。

数据集

example of data in file

我的代码是:

val rows = sc.textFile("/usr/local/comedy")
val vecData = rows.map(line => Vectors.dense(line.split(",").map(_.todouble)))
val mat = new RowMatrix(vecData)
val exact = mat.columnSimilarities()
val approx = mat.columnSimilarities(0.07)
val exactEntries = exact.entries.map { case MatrixEntry(i,j,u) => ((i,j),u) }
val approxEntries = approx.entries.map { case MatrixEntry(i,v) => ((i,v) }
val MAE = exactEntries.leftOuterJoin(approxEntries).values.map {
  case (u,Some(v)) =>
    math.abs(u - v)
  case (u,None) =>
    math.abs(u)
}.mean()

但是出现这个错误

java.lang.NumberFormatException: For input string: "[1,898,"black comedy"]"
    at sun.misc.FloatingDecimal.readJavaFormatString(FloatingDecimal.java:2043)
    at sun.misc.FloatingDecimal.parseDouble(FloatingDecimal.java:110)
    at java.lang.Double.parseDouble(Double.java:538)

怎么了?

解决方法

错误消息中充满了相关信息。

NumberFormatException: For input string: "[1,898,"black comedy"]"

看起来输入 String 没有被拆分为单独的列数据。所以 .split(",") 没有完成它的工作,很容易理解为什么,没有逗号空格序列可以拆分。

我们可以去掉空格并只用逗号分隔,但这仍然会在第一列数据中留下一个非数字 [,而第三列数据根本没有数字字符。

有几种不同的方法可以解决这个问题。我很想使用正则表达式解析器。

val twoNums = "(\\d+),(\\d+),".r.unanchored
val vecData = rows.collect{ case twoNums(a,b) =>
                Vectors.dense(Array(a.toDouble,b.toDouble))
              }

相关问答

Selenium Web驱动程序和Java。元素在(x,y)点处不可单击。其...
Python-如何使用点“。” 访问字典成员?
Java 字符串是不可变的。到底是什么意思?
Java中的“ final”关键字如何工作?(我仍然可以修改对象。...
“loop:”在Java代码中。这是什么,为什么要编译?
java.lang.ClassNotFoundException:sun.jdbc.odbc.JdbcOdbc...