scala - 如何使用 RowMatrix.columnSimilarities(相似性搜索)

标签 scala machine-learning apache-spark apache-spark-mllib

TL;DR; 我正在尝试训练现有数据集(Seq[Words] 以及相应的类别),并使用该训练数据集来过滤另一个数据集使用类别相似度的数据集。

我正在尝试训练数据语料库,然后将其用于文本分析*。我尝试过使用 NaiveBayes,但这似乎只适用于您拥有的数据,因此它的预测算法总是会返回一些内容,即使它与任何内容都不匹配。

所以,我现在尝试使用 TFIDF 并将输出传递到 RowMatrix 中并计算相似性。但是,我不确定如何运行我的查询(现在一个词)。这是我尝试过的:

val rddOfTfidfFromCorpus : RDD[Vector]
val query = "word"
val tf = new HashingTF().transform(List(query))
val tfIDF = new IDF().fit(sc.makeRDD(List(tf))).transform(tf)  
val mergedVectors = rddOfTfidfFromCorpus.union(sc.makeRDD(List(tfIDF)))
val similarities = new RowMatrix(mergedVectors).columnSimilarities(1.0)

这就是我被困住的地方(如果我在这里之前所做的一切都是正确的话)。我尝试将 similarities ij 过滤到查询的 TFIDF 部分,最终得到一个空集合。

要点是我想对数据集进行训练并找到它所属的类别。上面的代码至少试图将其归结为一个类别,并检查我是否至少可以从中得到预测....

*请注意,这是一个玩具示例,所以我只需要一些运行良好的东西 *我使用的是Spark 1.4.0

最佳答案

使用columnSimilarities在这里没有意义。由于矩阵中的每一列代表一组术语,因此您将获得标记而不是文档之间的相似性矩阵。您可以转置矩阵,然后使用columnSimilarities,但据我了解您想要的是查询和语料库之间的相似性。您可以使用矩阵乘法来表示,如下所示:

对于初学者,您需要一个在语料库上训练过的 IDFModel。假设它名为 idf:

import org.apache.spark.mllib.feature.IDFModel
val idf: IDFModel = ??? // Trained using corpus data

还有一个小 helper :

def toBlockMatrix(rdd: RDD[Vector]) = new IndexedRowMatrix(
  rdd.zipWithIndex.map{case (v, i) => IndexedRow(i, v)}
).toCoordinateMatrix.toBlockMatrix

首先让我们将查询转换为 RDD 并计算 TF:

val query: Seq[String] = ??? 
val queryTf = new HashingTF().transform(query)

接下来我们可以应用IDF模型并将结果转换为矩阵:

val queryTfidf = idf.transform(queryTf)
val queryMatrix = toBlockMatrix(queryTfidf)

我们还需要一个语料库矩阵:

val corpusMatrix = toBlockMatrix(rddOfTfidfFromCorpus)

如果将两者相乘,我们会得到一个矩阵,其行数等于查询中的文档数,列数等于语料库中的文档数。

val dotProducts = queryMatrix.multiply(corpusMatrix.transpose)

要获得适当的余弦相似度,您必须除以幅度的乘积,但如果您可以处理的话。

这里有两个问题。首先它相当昂贵。而且我不确定它是否真的有用。为了降低成本,您可以首先应用一些降维算法,但我们暂时保留它。

从下面的陈述来看

NaiveBayes (...) seems to only work with the data you have, so it's predict algorithm will always return something, even if it doesn't match anything.

我猜你想要某种无监督学习方法。您可以尝试的最简单的方法是 K 均值:

import org.apache.spark.mllib.clustering.{KMeans, KMeansModel}

val numClusters: Int = ???
val numIterations = 20

val model = KMeans.train(rddOfTfidfFromCorpus, numClusters, numIterations)
val predictions = model.predict(queryTfidf)

关于scala - 如何使用 RowMatrix.columnSimilarities(相似性搜索),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/32911810/

相关文章:

scala - 使用 Slick 3.1.x 将数据库连接返回到 HikariCP 池

python - 决策边界逻辑回归不正确

python - 我们可以从Python程序运行Orange吗

machine-learning - 使用 Flux.jl 更新函数的参数

java - Spark-Java : Concatenate aggregated groupBy's result

apache-spark - 如何在Spark中更有效地加载Parquet文件(pySpark v1.2.0)

python - Apache Spark 读取 S3 : can't pickle thread. 锁对象

scala - 如何收集 TinkerPop3 中的可选分支?

scala - 在 Spark RDD 中寻找最大值

scala - 通过交错值合并两个集合