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
i
和 j
过滤到查询的 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/