我正在使用eclipse Mars,java 8和spark spark-assembly-1.6.1-hadoop2.4.0.jar实现潜在语义分析LSA 我把文件作为代币传递,然后得到SVD等等
HashingTF hf = new HashingTF(hashingTFSize);
JavaRDD<Vector> ArticlesAsV = hf.transform(articles.map(x->x.tokens));
JavaRDD<Vector> ArticlesTFIDF = idf.fit(ArticlesAsV).transform(ArticlesAsV);
RowMatrix matTFIDF = new RowMatrix(ArticlesTFIDF.rdd());
double rCond= 1.0E-9d;
int k = 50;
SingularValueDecomposition<RowMatrix, Matrix> svd = matTFIDF.computeSVD(k, true, rCond);
每件事情都很完美,除了一件事,就是当我试图从hashingTF获得条款的索引时
int index = hf.indexOf(term);
我发现有很多术语具有相同的索引,这些是我得到的一些
0:期限
1:全部
1:下一个
2:tt
3:中
7:文件
9:这样的
9:矩阵
11:文件
11:关于
11:每个
12:功能
12:机会
14:这个
14:提供
意味着,当我试图将术语的向量与其相关时,我可能得到另一个具有相同索引的向量,我在词形还原后删除了停止词,但仍然得到相同的错误,是否存在我错过的任何事情,或者需要更新的组件(例如MLip)的错误;我怎样才能保持每个学期的独特性。
答案 0 :(得分:2)
Spark类HashingTF 利用hashing trick。
通过应用哈希将原始要素映射到索引(术语) 功能。然后基于映射计算术语频率 指数。这种方法避免了计算全局的需要 术语到索引的映射,对于大型语料库来说可能是昂贵的,但它 遭受潜在的哈希冲突,其中有不同的原始特征 散列后可能会成为同一个词。减少机会 碰撞,我们可以增加目标特征维度,即 哈希表的桶数。默认要素尺寸为2 ^ 20 = 1,048,576。
因此,术语组可以具有相同的索引。
相对于以下评论,如果您需要所有字词,则可以使用 CountVectorizer 而不是 HashingTF 。 CountVectorizer也可用于获取术语频率向量。 使用CountVectorizer,然后使用IDF 您必须使用DataFrame而不是JavaRDD,因为只有 ml 包支持CountVectorizer。
这是DataFrame的示例,其列 id 和字:
id | words
---|----------
0 | Array("word1", "word2", "word3")
1 | Array("word1", "word2", "word2", "word3", "word1")
因此,如果您将文章 JavaRDD翻译为DataFrame,其列 id 和字,其中每一行都是一个句子或文档中的单词包,您可以使用以下代码计算 TfIdf :
CountVectorizerModel cvModel = new CountVectorizer()
.setInputCol("words")
.setOutputCol("rawFeatures")
.setVocabSize(100000) // <-- Specify the Max size of the vocabulary.
.setMinDF(2) // Specifies the minimum number of different documents a term must appear in to be included in the vocabulary.
.fit(df);
DataFrame featurizedData = cvModel.transform(articles);
IDF idf = new IDF().setInputCol("rawFeatures").setOutputCol("features");
IDFModel idfModel = idf.fit(featurizedData);