算法原理
TF-IDF(Term Frequency-Inverse Document Frequency)是词频-逆文档频率,主要实现在一个文章集中找到每篇文章的关键字(也就是文章中哪些词汇是最重要的)。
主要从两个方面考虑,一篇文章中各个词语的出现频率。另一个是该词语在几篇文章中出现。
1、TF(Term Frequency) 词频
首先,解释第一个方面,一篇文章中各个词语出现的频率。从直观上来说,如果一篇文章中某些词语出现频率很高(除了“的、是、你”等助词等),那么从这一角度来说,可以认为该词是这篇文章的关键词。
使用数学公式表达就是
在某篇文章中该词出现较多,则TF值较大。该词在文章中出现较少,则TF值较小。注意要停用一些“的”、“是”、“你”、“我”…助词、人称代词等等。
2、IDF(Inverse Document Frequency)逆文件频率
然后,解释第二个方面,该词在哪几篇文章中出现过。在一个文章集中,我们的目标是找到每篇文章的特有的关键词,可以反映出该文章独有特点,即找到差异化且可有代表性的词。那么这个词通常情况下,并不会在其余文章中经常出现,否则对区分文章关键信息的作用就会较小。因此,我们这一方面就是找到本篇文章中的词语,很少出现在其余文章中。
使用数学公式表达就是
采用逆文档频率,该词在文档中没有怎么出现,则IDF值会较大。如果该词在其余文档出现较多,则IDF值会较小。
最后相乘就会得到,一篇文章中每个词的TF-IDF的值,值越大,则可认为重要程度越高,可作为文章的关键词。
参考:
TF-IDF 原理与实现
Python实现
在这里主要使用jieba
来实现中文分词,Counter
来进行计数统计
# -*- coding: utf-8 -*-
import math
import jieba
from collections import Counter
from collections import defaultdict
def TFIDF(dataset):
# 统计每个文章中每个词语的tf
j = 0
doc_len = len(dataset)
cntr = [0] * doc_len # Counter每个文章
total = [0] * doc_len # 获取每个文章中各自的词语总数
word_tf = [0] * doc_len # 获取每个文章中每个词语的tf
for sent in dataset:
iters = jieba.cut(sent)
cntr[j] = Counter(iters)
total[j] = sum(cntr[j].values())
word_tf[j] = defaultdict(int)
for i in cntr[j].keys():
word_tf[j][i] = cntr[j][i] / total[j]
j += 1
# 构建词汇表和总词频
word_cnt = defaultdict(int)
for word_list in word_tf:
for word in word_list:
word_cnt[word] += 1
# 统计词汇在文档中的频率
doc_tf = defaultdict(int)
for word in word_cnt:
for article in dataset:
if word in article:
doc_tf[word] += 1
# 构建词汇的idf
word_idf = {}
for word in doc_tf:
word_idf[word] = math.log(doc_len / (doc_tf[word] + 1))
# 构建每篇文章中词的tf-idf
t = 0
word_tf_idf = [0] * doc_len
for article in word_tf:
word_tf_idf[t] = defaultdict(int)
for word in article:
word_tf_idf[t][word] = article[word] * word_idf[word]
t += 1
# 对每篇文章每个词的tf-idf进行由大到小排序
t = 0
for i in word_tf_idf:
for j in i:
word_tf[t] = dict(sorted(word_tf[t].items(), key=lambda x:x[1], reverse=True))
word_tf_idf[t] = dict(sorted(word_tf_idf[t].items(), key=lambda x:x[1], reverse=True))
t += 1
return word_tf_idf, word_tf
if __name__ == '__main__':
dataset = ["中国的北京是中国的首都","那里有一句话叫做“北京欢迎您”,北京啊北京",
"北京欢迎您!相信梦想,梦,相信有梦就会有奇迹"]
word_tf_idf,word_tf = TFIDF(dataset)
print("=============tf-idf=============")
for i in word_tf_idf:
print(i)
print("=============tf=============")
for i in word_tf:
print(i)
注:代码主要目的是实现TF-IDF,对标点符号等没有进行停用处理。