TF-IDF(term frequency-inverse document frequency)是一种用于资讯检索与资讯探勘的常用加权技术。
- 是一种统计方法,用以评估一字词对于一个文件集或一个语料库中的其中一份文件的重要程度。
- 字词的重要性随着它在文件中出现的次数成正比增加,但同时会随着它在语料库中出现的频率成反比下降。
顾名思义,TF-IDF 算法由两部分组成:TF 和 IDF。接下来,我们具体来讲讲这两部分算法。
TF
TF = term frequency,翻译成中文,即词语频率(简称词频),表示某个词语在某一篇文档中出现的频率。
【基本思想】:一个词在文档中出现的次数越多,则其对文档的表达能力也越强。例如“人工智能”在一篇文章中出现多次,那么我们可以判断出这篇文章很有可能是在介绍与“人工智能”领域相关的内容。
【计算公式】:
t
f
i
,
j
=
n
i
,
j
∑
k
n
k
,
j
tf_{i,j} = \frac{n_{i,j}}{\sum_kn_{k,j}}
tfi,j=∑knk,jni,j
- n i , j n_{i,j} ni,j:词 i 在文档 j 中出现的频数。
- ∑ k n k , j \sum_kn_{k,j} ∑knk,j:文档 j 中所有字词的出现频数之和。
【问】:为什么不直接用词语在文档中出现的频数来作为 TF 呢?
【答】:目的在于防止词频偏向长文档(同一个词语在长文档中可能比短文档拥有更高的词频,而不管该词语重要与否)。例如,在一个 10000 字的文档 A 中出现“人工智能” 100 次,而在另一个 1000 字的文档 B 中出现“人工智能” 80 次,单纯根据频数来判断,“人工智能”对文档 A 的重要性要高于文档 B,但实际上并非如此。
以防止其偏向长的文件(同一个词语在长文件里可能会比短文件有更高的词频,而不管该词语重要与否)。
【存在缺陷】:“我”、“你”、“的”这一类词语在文档中的出现频率非常高,但它们并不能作为文档的关键词。换言之,TF 仅衡量词语的出现频率,却没有考虑词语对文档的区分能力。
IDF
IDF = inverse document frequency,翻译成中文,即逆向文档频率,表示某个词语在文档集中出现的频率。
【基本思想】:如果一个词语在越少的文档中出现,那么这个词语对文档的区分能力也就越强。例如,基本上每篇文章中都会出现“我”、“的”,但它们对区分文章的类型并不能起到作用,而只在特定领域文章中出现的“深度学习”等,这一类词语则可以很明确地标识当前文章的类型。
【计算公式】:可以由文档集中的文档数目除以包含该词语的文档的数目,再将得到的商取对数。
i
d
f
i
=
l
o
g
∣
D
∣
∣
∑
j
i
∈
d
j
∣
idf_i = log\frac{|D|}{|\sum_j i \in d_j|}
idfi=log∣∑ji∈dj∣∣D∣
- |D|:文档集中的文档数目。
- ∣ ∑ j i ∈ d j ∣ |\sum_j i \in d_j| ∣∑ji∈dj∣:包含词语 i 的文档数目。需要注意的是,如果该词语不在文档集中,会导致被除数为零,因此一般情况下使用拉普拉斯平滑 1 + ∣ ∑ j i ∈ d j ∣ 1 + |\sum_j i \in d_j| 1+∣∑ji∈dj∣,借以增强算法的健壮性。
【存在缺陷】:根据 IDF 的计算公式可知,词语出现的文档数越少,IDF 越高,表明词语具有很好的类别区分能力。但实际上,如果一个词语在一个类的文档中频繁出现,则说明这个词语能够很好代表这个类的文本的特征,例如“TF-IDF”频繁出现在“关键词抽取算法”中,却因为 IDF 过低而导致未能被抽取为关键词,这就是 IDF 的不足之处。
TF-IDF
TF 和 IDF 可以单独使用,但是各自都存在缺陷,因此前辈们尝试将两者进行整合,构成 TF-IDF 算法,从词频和逆向文档频率两个角度对词语的重要性进行衡量。
【计算公式】:TF-IDF 倾向于过滤掉常见的词语,保留重要的词语。
t
f
−
i
d
f
i
j
=
t
f
i
,
j
∗
i
d
f
i
tf-idf_ij = tf_{i,j} * idf_i
tf−idfij=tfi,j∗idfi
实际上对于 TF 和 IDF 如何进行组合可以有多种方式,例如 tf + idf,或者对相加后的结果取对数 log(tf + idf)。根据《Python自然语言处理实战:核心技术与算法》中叙述,可知 tf * idf 是较为有效的计算方式之一。我的理解是针对业务场景选择合适的计算方式,例如在文档数较少时,我们可以适当提高 TF 的权重。
除了上面提到的传统 TF-IDF 算法之外,TF-IDF 算法也有很多变种的加权方法。传统的 TF-IDF 算法仅考虑了词语的出现频率和逆向文档频率两个统计信息,而对文本的信息利用程度不高。除了上面的信息外,在一个文本中还有许多信息能对关键词的提取起到很好的指导作用。
- 词性:名词带有更多的关键信息,在关键词抽取过程中给予名词更高的权重,能使提取出来的关键词更合理。
- 词语出现的位置:文本的首段和尾段相比其他段落更为重要,对出现在这些位置中的词语赋予更高的权重,也能提高关键词的提取效果。
【汲取的思想】:算法本身的定义是死的,但结合应用场景,对算法进行合适的重塑及改造,使之更适应对应场景的应用环境,无疑能对我们想要得到的结果起到更好的指导作用。
示例
例如一篇文档的总词语数是 100,而“人工智能”出现了 3 次,那么“人工智能”一词在该文档中的词频就是 3 / 100 = 0.03。一个简单的计算 IDF 的方法是测定有多少份文档中出现过“人工智能”一词,然后除以文档总数。所以,如果“人工智能”一词在 1,000 份文档出现过,而文档总数是 10,000,000 份的话,其逆向文件频率就是 log(10,000,000 / 1,000) = 4。最后的 TF-IDF 的分数为 0.03 * 4 = 0.12。
实现
jieba 已经实现了基于 TF-IDF 算法的关键词抽取,通过命令 import jieba.analyse
引入。
【语法】:
jieba.analyse.extract_tags(sentence, topK=20, withWeight=False, allowPOS=())
- sentence:待提取的文本语料;
- topK:返回 TF/IDF 权重最大的关键词个数,默认值为 20;
- withWeight:是否需要返回关键词权重值,默认值为 False;
- allowPOS:仅包括指定词性的词,默认值为空,即不筛选。
【示例】:百度百科对人工智能的定义,获取 Top 20 关键字,用空格隔开打印。
from jieba.analyse import extract_tags
sentence = "人工智能......"
keywords = extract_tags(sentence, topK=20, withWeight=False, allowPOS=())
print(" ".join(keywords))
# 输出
人工智能 智能 2017 机器 不同 人类 科学 模拟 一门 技术 计算机
研究 工作 Artificial Intelligence AI 图像识别 12 复杂 流行语
keywords = extract_tags(sentence, topK=10, withWeight=True, allowPOS=(['n', 'v']))
print(keywords)
# 输出
[('人工智能', 0.9750542675762887),
('智能', 0.5167124540885567),
('机器', 0.20540911929525774),
('人类', 0.17414426566082475),
('科学', 0.17250169374402063),
('模拟', 0.15723537382948452),
('技术', 0.14596259315164947),
('计算机', 0.14030483362639176),
('图像识别', 0.12324502580309278),
('流行语', 0.11242211730309279)]
参考
- TF-IDF 及其算法:https://blog.csdn.net/sofuzi/article/details/80340861
- 《Python自然语言处理实战:核心技术与算法》