【问题标题】:HashingTF not giving unique indicesHashingTF 没有给出唯一索引
【发布时间】:2016-09-07 02:44:02
【问题描述】:

我正在使用 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)的错误;我怎样才能为每个术语保持唯一性。

【问题讨论】:

    标签: java apache-spark svd lsa


    【解决方案1】:

    Spark 类HashingTF 利用hashing trick

    通过应用哈希将原始特征映射到索引(术语) 功能。然后根据映射计算词频 指数。这种方法避免了计算全局 term-to-index map,这对于大型语料库来说可能很昂贵,但它 遭受潜在的哈希冲突,其中不同的原始特征 哈希后可能变成同一个词。为了减少发生的机会 碰撞,我们可以增加目标特征维度,即 哈希表的桶数。默认特征维度为 2^20=1,048,576。

    所以词组可以有相同的索引。

    相对于下面的 cmets,如果您需要所有术语,可以使用 CountVectorizer 代替 HashingTF。 CountVectorizer 也可用于获取词频向量。 使用CountVectorizer,随后使用IDF 您必须使用 DataFrame 而不是 JavaRDD,因为 CountVectorizer 仅在 ml 包中受支持。

    这是一个带有 idwords 列的 DataFrame 示例:

    id | words
    ---|----------  
    0  | Array("word1", "word2", "word3")  
    1  | Array("word1", "word2", "word2", "word3", "word1")
    

    因此,如果您将 articles JavaRDD 转换为 DataFrame,其中包含 idwords 列,其中每一行都是来自句子或文档的一组单词,您可以使用如下代码计算 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);
    

    【讨论】:

    • 我明白了,我将大小设置为 1048576 的最大值 (),它适用于 14696 个唯一术语,我得到了 14453 个唯一索引,缺少 243 个术语,但它会为 671333 个唯一索引做同样的事情吗条款。因为我有更大的数据要测试,它会错过很多术语吗??
    • 对于 671333,我得到了 489302,缺少 185031,仍然不好,我需要每个术语的索引,缺少的术语可能很重要,有什么办法可以解决吗???
    • 您只能使用构造函数 HashingTF(numFeatures: Int) 将最大尺寸放大到 1048576 以上,并希望它不会产生碰撞。即使 HashingTF 缺少许多术语,也有 two reasons It still works
    • 但是,如果我要在一个单词少的新短文档之间找到相似之处,我认为这会影响结果,对于带有很多单词的新大文档,我们可以忽略它,但我正在工作在简短的情况下,您认为它会得到可接受的结果吗??(再次:输入文档很大,测试文档很短)
    • 一种可能的解决方法是使用CountVectorizer 而不是 HashingTF。 CountVectorizer 也可用于获取词频向量。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2019-10-26
    • 1970-01-01
    • 2012-12-01
    • 2021-07-22
    • 2013-11-23
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多