Scala Spark计算标签余弦相似度的NumberFormatException排查
基于Spark计算喜剧类标签余弦相似度的代码问题排查
业务背景
- 原始数据源为包含用户ID、电影ID、标签字段的
tags.csv,计算目标是通过领域方法统计各标签间的余弦相似度,仅筛选与comedy相关的标签,最终测算每个喜剧类标签与comedy标签的相似度 - 数据集示例可参考数据集示例
现有实现代码
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, j, v) => ((i, j), 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)
代码存在的核心问题
- 数据解析逻辑与源数据结构完全不匹配:原始
tags.csv每行由数值型的用户ID、电影ID,和文本型的标签字段组成,标签是black comedy、comedy这类非数值内容。现有代码直接将整行按,拆分后强制转换为Double类型,碰到非数值的标签文本就会触发类型转换异常。同时读取路径指向/usr/local/comedy而非正确的tags.csv文件,读取到的内容甚至是带方括号的序列化字符串(即报错中出现的[1,898,"black comedy"]格式),完全没有针对CSV的带引号字段做正确拆分解析。 - 缺失计算必需的核心预处理环节:
RowMatrix要求输入为纯数值型的特征向量,要计算标签间的余弦相似度,必须先完成:标签去重编码映射、标签共现关系统计、基于共现关系生成标签维度的数值矩阵,当前代码直接把原始日志行当特征向量输入,从输入源上就不符合RowMatrix的计算要求。 - 计算目标完全错位:即便解决了类型转换报错,当前的输入数据也无法构造出标签维度的矩阵,
columnSimilarities计算得到的结果不会是标签与comedy的余弦相似度,完全匹配不了业务需求。
内容的提问来源于stack exchange,提问作者salm
相关产品推荐
相关产品推荐

