如何根据查询查找相关文档
How do I find relavence documents against the query
我正在经历一个项目,我必须根据查询逐一查找相关文档。首先我计算了所有文档的所有单词的 TF,IDF。然后我将 TF 和 IDF 相乘,并将特定文档的每个术语及其相应的 TF-IDF 分数存储在 List.here 中 class 命名的 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 ]", " ").trim().replaceAll(" +", " ").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 向量如果我的查询是“life and learning”?我该如何计算在所有文档之间查询以找到查询与所有文档之间的相似性?
tf-idf 分数与查询和文档之间的余弦相似度结合使用。所以你需要计算两个向量之间的点积。一个向量表示查询“生活和学习”。另一个向量表示其中一个文档。要找到最相关的文档,您需要计算与所有文档(或者理想情况下,仅包含某些单词的文档)的余弦相似度。
在向量 space 模型中,向量的每一维代表一个不同的词。因此,在这个特定示例中,仅有的两个相关维度是代表“生活”、“和”、“学习”的维度。理论上还有其他维度对应于每个其他已知单词,但在这种情况下这些维度的分数将为 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 更自然。
我正在经历一个项目,我必须根据查询逐一查找相关文档。首先我计算了所有文档的所有单词的 TF,IDF。然后我将 TF 和 IDF 相乘,并将特定文档的每个术语及其相应的 TF-IDF 分数存储在 List.here 中 class 命名的 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 ]", " ").trim().replaceAll(" +", " ").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 向量如果我的查询是“life and learning”?我该如何计算在所有文档之间查询以找到查询与所有文档之间的相似性?
tf-idf 分数与查询和文档之间的余弦相似度结合使用。所以你需要计算两个向量之间的点积。一个向量表示查询“生活和学习”。另一个向量表示其中一个文档。要找到最相关的文档,您需要计算与所有文档(或者理想情况下,仅包含某些单词的文档)的余弦相似度。 在向量 space 模型中,向量的每一维代表一个不同的词。因此,在这个特定示例中,仅有的两个相关维度是代表“生活”、“和”、“学习”的维度。理论上还有其他维度对应于每个其他已知单词,但在这种情况下这些维度的分数将为 0,因此在计算余弦相似度时可以跳过它们。
具体如何应用权重有多种可能的变化。但如果我们坚持最简单的...
你可以认为查询向量有
您可以使用许多可能的权重变化。您已经谈到了 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 更自然。