TFIDF加权方案的实施

时间:2014-06-20 22:19:01

标签: python text tf-idf

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

语料库= ['学校男孩正在阅读','谁正在读漫画?','这个小男孩正在阅读']

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}

我不太确定我是否对,因为像詹姆斯和漫画这样的稀有术语应该比学校这样的常用术语具有更高的TFIDF权重。

任何建议都将受到赞赏。

1 个答案:

答案 0 :(得分:2)

首先,正如@confuser在评论中所说的那样,让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}