【问题标题】:Implementation of TFIDF weighting schemeTFIDF加权方案的实施
【发布时间】:2014-08-11 18:06:45
【问题描述】:

我的目标是使用 TFIDF 加权方案将文本 txt 与以下语料库中的每个项目进行比较。

corpus=['小学生在看','谁在看漫画?','小男孩在看']

txt='小学生詹姆斯总是忙着读书'

这是我的实现:

TFIDF=词频-逆文档频率=tf * log (n/df) n=语料库中的文档数---在这种情况下为 3 个

import collections
from collections import Counter
from math import log

txt2=Counter(txt.split())
corpus2=[Counter(x.split()) for x in corpus]
def tfidf(doc,_corpus):
    dic=collections.defaultdict(int)
    for x in _corpus:
       for y in x:
          dic[y] +=1
    for x in doc:
       if x not in dic:dic[x]=1.
    return {x : doc[x] * log(3.0/dic[x])for x in doc}

txt_tfidf=tfidf(txt2, corpus2)
corpus_tfidf=[tfidf(x, corpus2) for x in corpus2]

结果

print txt_tfidf
    {'boy': 0.4054651081081644, 'school': 1.0986122886681098, 'busy': 1.0986122886681098, 'James': 1.0986122886681098,
     'is': 0.0, 'always': 1.0986122886681098, 'the': 0.4054651081081644, 'reading': 0.0}
for x in corpus_tfidf:
    print x
{'boy': 0.4054651081081644, 'the': 0.4054651081081644, 'reading': 0.0, 'school': 1.0986122886681098, 'is': 0.0}
{'a': 1.0986122886681098, 'is': 0.0, 'who': 1.0986122886681098, 'comic?': 1.0986122886681098, 'reading': 0.0}
{'boy': 0.4054651081081644, 'the': 0.4054651081081644, 'reading': 0.0, 'little': 1.0986122886681098, 'is': 0.0}

我不太确定我是否正确,因为 James 和 Comic 等稀有术语的 TFIDF 权重应该高于学校等常见术语。

任何建议将不胜感激。

【问题讨论】:

  • 虽然“学校”在英语中可能更常见,但“学校”与“漫画?”的分布相同在你的数据集中,所以看起来他们的分数应该是相似的
  • @confuser,但是学校出现了两次,而漫画出现了一次,还是只是关于语料库?请让我知道我的实现是否正确以及有关如何进行比较的任何建议。谢谢。
  • 啊,我明白了。我相信所有句子(包括txt)都需要成为TF-IDF 真正有意义的语料库的一部分。 (也许对这件事更了解的人可以证实这一点?)

标签: python text tf-idf


【解决方案1】:

首先,正如@confuser 在 cmets 中所说,让我们将 txt 放入语料库并摆脱这段代码:

for x in doc:
   if x not in dic:dic[x]=1.

在那之后,我想在你的代码中添加一个.,因为编码中的一个点,就像烹饪中的盐。 ;)

    for y in x:
        dic[y] += 1.

哦,我还在您的代码中看到了一些神奇的数字。对不起,他们让我很紧张,所以我们有:

return {x: doc[x] * log(len(_corpus) / dic[x]) for x in doc}

通过所有这些小修改,我们可以看到以下代码的结果:

import collections
from collections import Counter
from math import log

corpus = ['the school boy is reading', 'who is reading a comic?', 'the little boy is reading',
          'James the school boy is always busy reading']

txt = corpus[-1]

txt2 = Counter(txt.split())
corpus2 = [Counter(x.split()) for x in corpus]


def tfidf(doc, _corpus):
    dic = collections.defaultdict(int)
    for x in _corpus:
        for y in x:
            dic[y] += 1.
    return {x: doc[x] * log(len(_corpus) / dic[x]) for x in doc}


txt_tfidf = tfidf(txt2, corpus2)
corpus_tfidf = [tfidf(x, corpus2) for x in corpus2]

print txt_tfidf

在我看来,'boy' 的 tf_idf 比 'busy' 少得多。你同意吗?

{'boy': 0.28768207245178085, 'school': 0.6931471805599453, 'busy': 1.3862943611198906, 'James': 1.3862943611198906, 'is': 0.0, 'always': 1.3862943611198906, 'the': 0.28768207245178085, 'reading': 0.0}

【讨论】:

  • 非常感谢您的贡献,您的回答和解释非常完美。大约一个小时前,我得到了完全相同的答案。
猜你喜欢
  • 2017-08-09
  • 2015-04-01
  • 1970-01-01
  • 2011-07-03
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多