Spark余弦相似度(DIMSUM算法)稀疏输入文件

时间:2015-05-05 18:08:02

标签: apache-spark sparse-matrix cosine-similarity

我想知道Spark Cosine Similarity是否可以使用Sparse输入数据?我见过一些例子,其中输入由以下形式的空格分隔的特征线组成:

id feat1 feat2 feat3 ...

但我有一个固有的稀疏,隐式反馈设置,并希望在表单中输入:

id1 feat1:1 feat5:1 feat10:1
id2 feat3:1 feat5:1 ..
...

我想利用稀疏性来改进计算。最后,我希望使用DIMSUM算法计算最近并入Spark的所有对相似度。有人会建议一个稀疏输入格式,可以在火花上使用DIMSUM吗?我检查了示例代码,并在注释中说“输入必须是一个密集的矩阵”,但这个代码在示例中,所以我不知道它是否只是指一个特定的情况。

spark/examples/src/main/scala/org/apache/spark/examples/mllib/CosineSimilarity.scala

这是我所指的示例代码的路径。

表示稀疏输入格式应该看起来的几行(从推荐系统的角度来看,user_id feat1:1 feat2:1 ...),以处理余弦相似性,将非常有用。

如果我将user_ids留作字符串也可以吗?

我知道libsvm格式是相似的,但在这种情况下没有用户ID的概念,只有具有功能的输入实例,所以我想知道libsvm格式将如何转换为推荐系统域?

我为非常简单的问题道歉,我对Spark非常陌生,我只是沾到了脚步。

非常感谢任何帮助。提前谢谢!

1 个答案:

答案 0 :(得分:2)

为什么不呢?天真的解决方案看起来或多或少是这样的:

// Parse input line
def parseLine(line: String) = {
    def parseFeature(feature: String) = {
        feature.split(":") match {
            case Array(k, v) => (k, v.toDouble)
        }
    }

    val bits = line.split(" ")
    val id = bits.head
    val features = bits.tail.map(parseFeature).toMap
    (id, features)
}

// Compute dot product between to dicts
def dotProduct(x: Map[String, Double], y: Map[String, Double]): Double = ???

// Compute norm of dict
def norm(x: Map[String, Double]): Double = ???

// Compute cosine similarity
def sparseCosine(x: Map[String, Double], y: Map[String, Double]): Double = {
    dotProduct(x, y) / (norm(x) * norm(y))
}

// Parse input lines
val parsed  = sc.textFile("features.txt").map(parseLine)

// Find unique pairs
val pairs = parsed.cartesian(parsed).filter(x => x._1._1 != x._2._1)

// Compute cosine similarity between pairs
pairs.map { case ((k1, m1), (k2, m2)) => ((k1, k2), sparseCosine(m1, m2)) }