2021SC@SDUSC
计算TF-IDF是自然语言处理
(NLP)中比较常见的方法,今天来介绍一下此方法。
概念:
TF-IDF(term frequency–inverse document frequency)是一种用于资讯检索与资讯探勘的常用加权技术。TF-IDF是一种统计方法,用以评估一字词对于一个文件集或一个语料库中的其中一份文件的重要程度。字词的重要性随着它在文件中出现的次数成正比增加,但同时会随着它在语料库中出现的频率成反比下降。TF-IDF加权的各种形式常被搜寻引擎应用,作为文件与用户查询之间相关程度的度量或评级。除了TF-IDF以外,因特网上的搜寻引擎还会使用基于连结分析的评级方法,以确定文件在搜寻结果中出现的顺序。
原理:
在一份给定的文件里,词频 (term frequency, TF) 指的是某一个给定的词语在该文件中出现的次数。这个数字通常会被归一化(分子一般小于分母 区别于IDF),以防止它偏向长的文件。(同一个词语在长文件里可能会比短文件有更高的词频,而不管该词语重要与否。)
逆向文件频率 (inverse document frequency, IDF) 是一个词语普遍重要性的度量。某一特定词语的IDF,可以由总文件数目除以包含该词语之文件的数目,再将得到的商取对数得到。
某一特定文件内的高词语频率,以及该词语在整个文件集合中的低文件频率,可以产生出高权重的TF-IDF。因此,TF-IDF倾向于过滤掉常见的词语,保留重要的词语。
TFIDF的主要思想是:如果某个词或短语在一篇文章中出现的频率TF高,并且在其他文章中很少出现,则认为此词或者短语具有很好的类别区分能力,适合用来分类。TFIDF实际上是:TF * IDF,TF词频(Term Frequency),IDF反文档频率(Inverse Document Frequency)。TF表示词条在文档d中出现的频率(另一说:TF词频(Term Frequency)指的是某一个给定的词语在该文件中出现的次数)。IDF的主要思想是:如果包含词条t的文档越少,也就是n越小,IDF越大,则说明词条t具有很好的类别区分能力。如果某一类文档C中包含词条t的文档数为m,而其它类包含t的文档总数为k,显然所有包含t的文档数n=m+k,当m大的时候,n也大,按照IDF公式得到的IDF的值会小,就说明该词条t类别区分能力不强。(另一说:IDF反文档频率(Inverse Document Frequency)是指果包含词条的文档越少,IDF越大,则说明词条具有很好的类别区分能力。)但是实际上,如果一个词条在一个类的文档中频繁出现,则说明该词条能够很好代表这个类的文本的特征,这样的词条应该给它们赋予较高的权重,并选来作为该类文本的特征词以区别与其它类文档。这就是IDF的不足之处。
在一份给定的文件里,词频(term frequency,TF)指的是某一个给定的词语在该文件中出现的频率。这个数字是对词数(term count)的归一化,以防止它偏向长的文件。(同一个词语在长文件里可能会比短文件有更高的词数,而不管该词语重要与否。)对于在某一特定文件里的词语
t
i
t_{i}
ti来说,它的重要性可表示为:
以上式子中
n
i
,
j
n_{i,j}
ni,j 是该词在文件
d
j
d_{j}
dj中的出现次数,而分母则是在文件
d
j
d_{j}
dj中所有字词的出现次数之和。
逆向文件频率(inverse document frequency,IDF)是一个词语普遍重要性的度量。某一特定词语的IDF,可以由总文件数目除以包含该词语之文件的数目,再将得到的商取对数得到:
其中
|D|:语料库中的文件总数
∣
{
j
:
t
i
∈
d
j
}
∣
|\{ j: t_{i} \in d_{j}\}|
∣{j:ti∈dj}∣ :包含词语
t
i
t_{i}
ti的文件数目(即
n
i
,
j
≠
0
n_{i,j} \neq 0
ni,j=0的文件数目)如果该词语不在语料库中,就会导致被除数为零,因此一般情况下使用
1
+
∣
{
j
:
t
i
∈
d
j
}
∣
1 + |\{j : t_{i} \in d_{j}\}|
1+∣{j:ti∈dj}∣
然后:
t
f
i
d
f
i
,
j
=
t
f
i
,
j
×
i
d
f
i
\mathrm{tf{}idf_{i,j}} = \mathrm{tf_{i,j}} \times \mathrm{idf_{i}}
tfidfi,j=tfi,j×idfi
某一特定文件内的高词语频率,以及该词语在整个文件集合中的低文件频率,可以产生出高权重的TF-IDF。因此,TF-IDF倾向于过滤掉常见的词语,保留重要的词语。
示例:
# 计算TF-IDF的函数(1篇):TF:Term Frequency短语的频率,反映单词的重要程度;
# IDF:Inverse Document Frequency,即逆文档频率,就是越广泛存在的Term越不重要,也就是Term的重要性和出现的广泛性成反比。
# 比如“了”,”的“,”是的“等等;
# TF衡量的是短语和文档的关系,而idf衡量的是短语和所有文档的关系;
# TF-idf是用来计算短语在某个文档中重要性的算法。
# TF-idf的算法也很简单,我们直接将TF和idf计算得到的取值相乘即可。
def deal(p, t):
p = p.split() # 分词 # p是指paragraph,t是指tf ? 词频 ?
if p[0] in pre_word:
p = p[1:] # 为啥要去掉第一个token;
b = ' '.join(p) # 使用' '连接p;
tag = nltk.pos_tag(p) # nltk.pos_tag()是一种用来进行词性标注的函数。
if len(p) <= 2: # tag是指各种词的词性,比如名词、动词、副词等等。
return set([b]) # set()返回对象的集合。
else: # 并且把pos_tag方法创建的词和对应词性保存在pos_tags数列。(2维数组)
pro = 2 # pos_tags[][]表示(词,词性)。
if p[0] in stoplist: # 去除停用词 # 如果p[0]在stop list中,去掉第一个词
p = p[1:]
if len(p) == 1:
return set([b])
ret = [b] # 之后创建空数组ret,遍历pos_tags,把有我们需要的词性的数组保存到ret[];
for e in p:
if e not in idf:
return set(ret) # set集合?
if tag[0][1] not in ['NN', 'NNS', 'NNP']: # NN名词单数形式、NNS名词复数形式、NNP专有名词
r0 = idf[p[0]] * t.count(p[0])
r1 = idf[p[1]] * t.count(p[1]) # 使用count来计算词频。
if r0*5 < r1: # r可能就是TF-IDF
ret = []
ret.append(' '.join(p[1:]))
return set(ret)
if idf[p[-1]]*t.count(p[-1])*5 < idf[p[-2]]*t.count(p[-2]):
ret.append(' '.join(p[:-1]))
return set(ret)
return set(ret)