HashingTF没有给出独特的指数

时间:2016-09-07 02:44:02

标签: java apache-spark svd lsa

我正在使用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)的错误;我怎样才能保持每个学期的独特性。

1 个答案:

答案 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);