pyspark - 计算文档相关性的余弦相似度
问题描述
我已经为关键字 RDD 进行了标准化的 TF-IDF,现在想要计算余弦相似度以找到文档的相关性分数。
所以我尝试了
documentRdd = sc.textFile("documents.txt").flatMap(lambda l: re.split(r'[^\w]+',l))
keyWords = sc.textFile("keywords.txt").flatMap(lambda l: re.split(r'[^\w]+',l))
normalizer1 = Normalizer()
hashingTF = HashingTF()
tf = hashingTF.transform(documentRdd)
tf.cache()
idf = IDF().fit(tf)
tfidf = idf.transform(tf)
normalizedtfidf=normalizer1.transform(tfidf)
现在我想计算归一化tfidf和keyWords之间的余弦相似度。所以我尝试使用
x = Vectors.dense(normalizedtfidf)
y = Vectors.dense(keywordTF)
print(1 - x.dot(y)/(x.norm(2)*y.norm(2)) , "is the releavance score")
但这会引发错误
TypeError: float() 参数必须是字符串或数字
这意味着我传递了错误的格式。感谢任何帮助。
更新
我当时试过
x = Vectors.sparse(normalizedtfidf.count(),normalizedtfidf.collect())
y = Vectors.sparse(keywordTF.count(),keywordTF.collect())
但得到了
TypeError:不能将类型视为向量
作为错误。
解决方案
您收到错误是因为您试图将 RDD 强制转换为 Vectors。
通过执行以下步骤,您可以在不进行转换的情况下实现所需的功能:
- 将两个 RDD 加入一个 RDD。请注意,我假设您在两个 RDD 中都没有用于加入的唯一索引。
# Adding index to both RDDs by row.
rdd1 = normalizedtfidf.zipWithIndex().map(lambda arg : (arg[1], arg[0]))
rdd2 = keywordTF.zipWithIndex().map(lambda arg : (arg[1], arg[0]))
# Join both RDDs.
rdd_joined = rdd1.join(rdd2)
map
具有计算余弦距离的函数的 RDD。
def cosine_dist(row):
x = row[1][0]
y = row[1][1]
return (1 - x.dot(y)/(x.norm(2)*y.norm(2)))
res = rdd_joined.map(cosine_dist)
然后,您可以使用您的结果或运行collect
以查看它们。
推荐阅读
- mongodb - 如何为 @Injectable() mongodb 服务编写 Nestjs 单元测试
- javascript - 无法使用interact.js拖放到另一个div
- json - Vscode:无法从“https://json.schemastore.org/gitlab-ci”加载架构:getaddrinfo ENOTFOUND json.schemastore.org.(768)
- ruby-on-rails - 从 Ruby On Rails Gem 添加 javascript 的推荐方法
- c++ - C++:从命令行传递参数时,为什么会出现“抛出异常:读取访问冲突。argv 为 0xFEFEFEFE”?
- python - 使用 pandas 过滤列以仅显示某些字符串位置
- javascript - 如何在数组内打印带有一组对的JavaScript数组
- amazon-ec2 - 在 aws Code Deploy 更新运行实例中的应用程序之后,使用 RunInstances 启动的新 EC2 实例使用 Launch Template 中的陈旧 AMI
- c - 为什么它只在最后一个循环点输出学生的信息?即第19个学生
- xamarin - Xamarin Grid UWP 和 iOS 显示问题