Spark ml余弦相似度:如何获得1到n的相似度得分

时间:2016-10-18 08:38:58

标签: scala apache-spark apache-spark-mllib cosine-similarity apache-spark-ml

我读到我可以使用columnSimilarities附带的RowMatrix方法来查找各种记录(基于内容)的余弦相似度。我的数据看起来像这样:

genre,actor
horror,mohanlal shobhana pranav 
comedy,mammooty suraj dulquer
romance,fahad dileep manju
comedy,prithviraj

现在,我已经创建了一个spark-ml管道来计算上述文本特征(流派,演员)的tf-idf,并使用我的管道中的VectorAssembler将这两个特征组合成一个列“特征”。之后,我使用此转换我获得的DataFrame

val vectorRdd = finalDF.map(row => row.getAs[Vector]("features"))

将其转换为RDD[Vector]

然后,我通过

获取RowMatrix
val matrix = new RowMatrix(vectorRdd)

我正在关注this指南以获取对余弦相似性的引用,我需要的是spark-mllib中的一个方法,用于查找特定记录与其他所有内容之间的相似性,例如sklearn中的this方法,如指南所示:

cosine_similarity(tfidf_matrix[0:1], tfidf_matrix)

但是,我无法找到如何做到这一点。我不明白matrix.columnSimilarities()正在比较和返回的内容。有人可以帮助我找到我要找的东西吗?

任何帮助表示赞赏!感谢。

1 个答案:

答案 0 :(得分:0)

我自己用2个小函数计算了它。在2个数据帧的crossJoin上调用cosineSimilarity。(将第1行和其他数据分成2)

def cosineSimilarity(vectorA: SparseVector, 
        vectorB:SparseVector,normASqrt:Double,normBSqrt:Double) :
    (Double,Double) = {
        var dotProduct = 0.0
        for (i <-  vectorA.indices){ 
            dotProduct += vectorA(i) * vectorB(i)
        }
        val div = (normASqrt * normBSqrt)
        if (div == 0 )
            (dotProduct,0)
        else
            (dotProduct,dotProduct / div)
    }

    val normSqrt : (org.apache.spark.ml.linalg.SparseVector => Double) = (vector: org.apache.spark.ml.linalg.SparseVector) => {
        var norm = 0.0
        for (i <- vector.indices ) {
            norm += Math.pow(vector(i), 2)
        }
        Math.sqrt(norm)
    }