如何针对查询查找相关文档

问题描述

我正在经历一个项目,在该项目中,我必须根据查询一个一个地找到相关文档。首先,我为所有文档的所有单词计算了 TF,IDF 。然后我将TF和IDF相乘,并将每个术语及其对应的TF-IDF分数存储在List内的特定文档中。在这里,名为Tfidf的类计算TF和IDF

public double TF(String[] document,String term) {
    double value = 0;                 //calculate Term Frequency for all term
    for (String s : document) {
        if (s.equalsIgnoreCase(term)) {
            tfmap.put(s,tfmap.getOrDefault(term,0) + 1);
            for (Map.Entry entry : tfmap.entrySet()) {
                value = (int) entry.getValue();
            }
        }
    }
    return value / document.length;
}

public double idf(List alldocument,String term) {
    double b = alldocument.size();
    double count = 0;
    for (int i = 0; i < alldocument.size(); i++) {
        String[] f = alldocument.get(i).toString().replaceAll("[^a-zA-Z0-9 ]"," ").trim().replaceAll(" +"," ").toLowerCase().split(" ");

        for (String ss : f) {
            if (ss.equalsIgnoreCase(term)) {
                count++;
                break;
            }
        }
    }
    return 1 + Math.log(b / count);
}}

这里是我将TF和IDF相乘的代码

  List<String> alldocument= new ArrayList<>();
  List tfidfVector = new ArrayList<>();
 public void TfIdf() {
    double tf;
    double idf;
    double tfidf = 0;


    for (int i = 0; i < alldocument.size(); i++) {
        double[] tfidfvector = new double[allterm.size()];  //allterm is all unique word in all documents
        for (String terms : allterm) {
            String[] file = alldocument.get(i).replaceAll("[^a-zA-Z0-9 ]"," ").toLowerCase().split(" ");
            int count = 0;
            tf = new Tfidf().TF(file,terms);
            idf = new Tfidf().idf(alldocument,terms);
            tfidf = tf * idf;
            tfidfvector[count] = tfidf;
            count++;
        }
        tfidfVector.add(tfidfvector);            
    }   
}

谁能告诉我我如何计算查询的TF-IDF向量(如果我的查询是“ 生活和学习”?)以及如何计算所有文档之间查询的余弦相似度?找到查询和所有文档之间的相似性?

解决方法

tf-idf得分与查询和文档之间的余弦相似度结合使用。因此,您需要计算两个向量之间的点积。一个向量表示查询“生活与学习”。另一个向量代表其中一个文档。要查找最相关的文档,您需要计算与所有文档的余弦相似度(或者理想情况下,仅计算包含某些单词的文档)。 在向量空间模型中,向量的每个维度代表一个不同的词。因此,在此特定示例中,仅有的两个相关维度将是代表“生活”,“和”,“学习”的维度。从理论上讲,还有其他与每个已知单词相对应的维,但是在这种情况下,这些维的分数将为0,因此在计算余弦相似度时可以跳过它们。

确切地应用加权有几种可能的变化。但是如果我们坚持最简单的... 您可以考虑查询向量具有。并且文档向量具有。 然后,您只需计算这两个向量之间的点积即可。对于查询中未出现的单词,您将最终乘以0并将其添加到分数中,这意味着您可以忽略所有这些单词。因此,您只需要考虑查询中的术语。对于查询中的每个字词,请将查询中的tf(如果需要,甚至仅乘以1)乘以文档中该字词的tf-idf得分。

您可以使用许多可能的加权变量。您已经讨论过TF和IDF。我还看到您已经编写了一些代码,以按照文档的长度对术语频率进行归一化。要了解更多信息,请参考《信息检索教科书简介》的这一部分:https://nlp.stanford.edu/IR-book/html/htmledition/document-and-query-weighting-schemes-1.html#sec:querydocweighting。 (不过,如果不阅读前面的部分内容,它可能会太密集)

仅供参考,关于您已发布的代码,您当前将它们存储在ArrayList中,只是按顺序索引。好吧,您有一个问题,每次循环都将count重置为0,这似乎不正确。但忽略这一点,您将需要一种简单的方法来查找特定术语的tf-idf信息。 HashTable比ArrayList更自然。

相关问答

依赖报错 idea导入项目后依赖报错,解决方案:https://blog....
错误1:代码生成器依赖和mybatis依赖冲突 启动项目时报错如下...
错误1:gradle项目控制台输出为乱码 # 解决方案:https://bl...
错误还原:在查询的过程中,传入的workType为0时,该条件不起...
报错如下,gcc版本太低 ^ server.c:5346:31: 错误:‘struct...