规范化TF-IDF结果

5

我希望能够归一化我从这段代码中得到的tfidf结果:

for (int docNum = 0; docNum < ir.numDocs(); docNum++) {
            TermFreqVector tfv = ir.getTermFreqVector(docNum, "contents");
            if (tfv == null) {
                // ignore empty fields
                continue;
            }
            String[] tterms = tfv.getTerms();
            int termCount = tterms.length;
            int[] freqs = tfv.getTermFrequencies();
            for (int t = 0; t < termCount; t++) {
                double idf = ir.numDocs() / ir.docFreq(new Term("contents", tterms[t]));
                System.out.println(" " + tterms[t] + " " + freqs[t]*Math.log(idf));
            }
        }

这段代码的输出结果是:
area 0.0
areola 5.877735781779639
ari 3.9318256327243257
art 1.6094379124341003
artifici 1.0986122886681098
assign 2.1972245773362196
associ 3.295836866004329
assur 1.9459101490553132
averag 1.0986122886681098
avoid 0.6931471805599453
.
.
.

任何帮助都会非常感激。谢谢。

1
我想对我从给定代码中得到的tfidf结果进行归一化处理: - Dan
5
TF-IDF是一种规范化方法。 - Has QUIT--Anony-Mousse
1个回答

10
一种常见的方法是按文档大小进行标准化。即,不使用术语计数(或绝对频率),而使用相对频率。
设freqsum为您的频率数组的总和。然后使用以下公式:
freqs[t]/(double)freqsum*Math.log(idf)

为了避免这种混淆,我建议使用以下术语:
  • 词项计数代表“绝对频率”
  • 相对频率代表文档中某个单词的比例
而不是模棱两可的术语“词项频率”。
我知道从历史上看,如果你查阅Salton、Yang在《自动索引中词项值规范化》(1973)一书中所提到的是绝对计数。余弦相似度将会移除比例,因此无论如何那都不重要。现代系统如Lucene将尽力控制文档的影响。

只是为了澄清一下 - 你是说根据我上面的代码,"freqsum" 是 "termCount" 吗?我只是想要澄清一下,抱歉兄弟。 - Dan
不,termCount 是指不同术语的数量,对吧?我说的是总和。考虑到相对术语频率,应该很清楚了。 - Has QUIT--Anony-Mousse
"先生,这个正确吗?" int[] freqs = tfv.getTermFrequencies(); double freqsum = Math.sqrt(freqs[i]) / tterms.length; - Dan
不,计算总和并不涉及取平方根。 - Has QUIT--Anony-Mousse
那难道不可能会得到一个负值吗? - Leo
那会在什么时候发生? - Has QUIT--Anony-Mousse

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接