首页 > 解决方案 > 计算文档相关性的余弦相似度

问题描述

我已经为关键字 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:不能将类型视为向量

作为错误。

标签: pysparkapache-spark-mllibtf-idf

解决方案


您收到错误是因为您试图将 RDD 强制转换为 Vectors。

通过执行以下步骤,您可以在不进行转换的情况下实现所需的功能:

  1. 将两个 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)
  1. 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以查看它们。


推荐阅读