TF-IDF(附代码)

词频(Term Frequency,TF)是指某一个给定的词语在该文件中出现的频率。这个数字是对词数(Term Count)的归一化,以防止它偏向长的文件。对于在某一特定文件中的词语来说,它的重要性可以表示为:

                         TF=(该词在文件中的出现次数)/(在文件中所有字词的出现次数之和)      (定义来自百度百科)

逆向文件频率(Inverse Document Frequency,IDF)是一个词语普通重要性的度量。某一特定词语的IDF,可以由总文件数目除以包含该词语之文件的数目,再讲得到的商去对数得到:

                         IDF=(语料库中的文件总数)/(包含该词语的文件数目)

  其中,如果该语料不在语料库中,就会导致分母为0.因此,一般情况下分母要+1.

最后计算TF*IDF.

下面举一个例子:

假设当前有一个语料库,这个语料库中有3个文本。

文本1: My dog ate my homework.

文本2:  My cat ate my sandwich.

文本3: A dolphin ate the homework.

由这3个文本生成的词典共有9个词,为:

[a, ate, cat, dolphin, dog, homework, my, sandwich, the]     (注意:词典里面是无序且不能重复的)

这9个词一次表示成One-hot向量的形式如下:(这里不将讲one-hot,网上一堆,一看就懂)

“a"------------>[1 0 0 0 0 0 0 0 0]

"ate"----------->[0 1 0 0 0 0 0 0 0]

...

"the"-------------->[0 0 0 0 0 0 0 0 1]

那么我们直接来看词条的文档词频:(注意是词条的文档词频)

TF:  a(1/3), ate(3/3), cat(1/3), dolphin(1/3), dog(1/3), homework(2/3), my(2/3), sandwich(1/3),  the(2/3)

注意,这里的"my"最特殊,因为第一文本里有两个"my",第二个文本里有一个“my",但是第三个文本里没有"my",所以说”my"的词条文档频率是2/3.

下面我们看词袋模型的IDF权重如下:

IDF:

a------>log(3/1)

ate------->log(3/3)

cat--------->log(3/1)

...

my-------->log(3/2)

...

其他的我就不算了。

值得注意的是这里的log是以2为底的!!!我在这里栽了个大跟头,老是记成以10为底的,以10为底的应该是lg。希望你不要犯错!

那么重点来了,稍作分析,你能发现什么?

把TF和IDF乘起来,你就会发现如果某个词在每个文本中都出现的话,那么它的TF-IDF值越小。往远了想想,给你10篇论文,像“a","the","so"这类的词在每一篇论文中都会出现,那么他的TF-IDF值就小,我们不需要它,它并不是关键。而在10篇中的某一篇中经常出现”pollution“,而其他9篇论文里没有出现,那么"pollution"它的TF-IDF值就很大,是我们想要保留的重要词语,是我们想要提取的重要信息。

换句话说,TF-IDF倾向于过滤掉常见词,保留重要词语。

下面附上代码,其实这个结果0.707106....,我真的没有算下来,IDF值与我算的是一致的,但是词频TF不知道是怎么算的,跟我笔算的不一致。但是代码是没错的。

#-*-coding:utf-8 -*-

#在词袋模型中,文档的特征就是其包含的word,corpus的每一个元素对应一篇文档
texts=[['human','interface','computer'],
       ['survey','user','computer','system','response','time'],
       ['eps','use','interface','system'],
       ['system','human','system','eps'],
       ['user','response','time'],
       ['trees'],
       ['graph','trees'],
       ['graph','minors','trees'],
       ['graph','minors','survey']]

#训练语料的预处理,将原始文本特征表达转换成词袋模型对应的系数向量
from gensim import corpora
#from gensim.models.word2vec import Word2Vec
dictionary=corpora.Dictionary(texts)#texts就是若干个被拆成单词集合的文档的集合,而dictionary就是把所有单词取一个set(),并对set中每个单词分配一个Id号的map
print(dictionary)
#是把文档 doc变成一个稀疏向量,[(0, 1), (1, 1)],表明id为0,1的词汇出现了1次,至于其他词汇,没有出现,在这里可以看出set()中computer的id是0,human的id是1...
corpus=[dictionary.doc2bow(text) for text in texts]
print(corpus)#输出为[(0, 1), (1, 1), (2, 1)],就表示id为0,1,2,即单词computer,human,interface,在第一个维度中都出现了一次

#tf-idf的计算
from gensim import models
tfidf=models.TfidfModel(corpus)
print(tfidf)
doc_bow=[(0,1),(1,1)]
print(tfidf[doc_bow])
print(tfidf.idfs)

TF-IDF的计算结果是这样: 

[(0, 0.7071067811865476), (1, 0.7071067811865476)]

如有错误,请留言指正。

以及如何得到的0.70710678.....如果你懂了,请联系我,交流交流

猜你喜欢

转载自blog.csdn.net/weixin_37567451/article/details/81132322
今日推荐