TF-IDF的原理及代码实现

如何衡量词的重要性

在文本处理过程中总会遇到这样一个问题,如何衡量一个词在一篇文档中的重要性?就像我们在写论文的时候,会有一个摘要和关键词,这个关键词便是我们认为的对于这篇文章来说最重要的几个词,那我们怎么得到这样的关键词呢?

假设我们现在有这么一段文本:

我最喜欢度假了,度假的时候我的心情会变得十分美丽,因为我可以去游山玩水,我还可以去吃好多好吃的,我还可以认识好多新的朋友,经历不一样的人生。。。。。

那么从我们来看,这一段话中明显“度假”的重要性要高于其他的词,那么我们怎么才能让计算机把它找出来呢,因为我们知道,计算机最擅长的就是计算,它几乎就是只在跟数字打交道,那么我们能不能通过数学的方式,将这个关键词计算出来呢?

我们第一个想到的是某个词出现的次数,也就是词频(Term Frequency,即TF),我们认为出现次数多的一般都比较重要,但这样就会出现一个问题,有些无用词会来干扰我们的判断,比如上面文本中,最重要的词“度假”出现的词频是2,而主语词“我”出现的词频是5,而单单一个“我”,却带来不了什么实际的含义。所以说我们肯定是得做去停用词的操作的。但是仅仅去掉停用词,似乎还是不能完全解决我们的问题,假设现在有两个词在同一篇文本中的词频一样,但是当我们把这篇文本划分为不同主题时,可能这两个词的重要程度又是不一样的。所以简单的词频,并不能很好的满足我们的需求,我们需要更好的词语重要性表征工具。

于是一种加了权重的词频表达方式就来了:TF-IDF 。

TF-IDF的引出

TF-IDF是TF(词频,Term Frequency)和IDF(逆文档频率,Inverse Document Frequency)的乘积。我们先来看他们分别是怎么计算的:

TF的计算有多种方式,常见的是:

image-20200827195643901

考虑到文章有长短之分,为了便于不同文章的比较,进行"词频"标准化:

image-20200827195719423

或者是:
image-20210315212557328

再来看IDF的计算:

逆文档频率需要站在语料库的角度看:

image-20200827195952753

如果一个词越常见,那么分母就越大,逆文档频率就越小越接近0。分母之所以要加1,是为了避免分母为0(即所有文档都不包含该词)。log表示对得到的值取对数,求log是为了归一化,保证IDF不会过大

所以TF-IDF 的计算就是:

image-20200827200130122

以下有几个细节点的理解:

  1. IDF表征的是区分度、稀缺性,用以评估一个单词在语料库中的重要程度,一个词在少数几篇文档中出现的次数越多,它的IDF值越高,如果这个词在大多数文档中都出现了,这个值就不大了。从公式也可以看出来,由于log函数是单增函数,当文档总数固定时,包含该词的文档数越少,IDF值越大,稀缺性越强。背后的思想是某个词或者短语在一篇文章中出现的频率高(TF大),并且在其他文档中很少出现(IDF也大),则认为该词或短语具备很好的类别区分能力(TF-IDF就越大)
  2. TF刻画了词语w对某篇文档的重要性,IDF刻画了w对整个文档集的重要性。TF与IDF没有必然联系,TF低并不一定伴随着IDF高。实际上我们可以看出来,IDF其实是给TF加了一个权重

应用场景

  • 找关键词:TF-IDF值排序,取前top-k。
  • 文本相似度:找出两个待比较文档中TF-IDF排名前top-k的关键词,利用余弦相似度来计算两个文本的相似度。
  • 自动文本摘要:拟定一个簇长度n,其实就是一个窗口长度,在这个窗口长度下,某个句子含有的关键词越多说明这个句子就越重要,就可以作为摘要的一句,可能还要加上重要的文头文尾,就可以简单的生成一个摘要。

利用代码理解

利用sklearn中既有的包来简单看一下TF-IDF的计算:

from sklearn.feature_extraction.text import CountVectorizer,TfidfTransformer

texts=["dog cat fish","dog cat cat","fish bird", 'bird'] # “dog cat fish” 为输入列表元素,假设代表一篇文章的所有字符串
cv = CountVectorizer()#创建词袋数据结构
cv_fit=cv.fit_transform(texts)

print(cv.get_feature_names())    #['bird', 'cat', 'dog', 'fish'] 列表形式呈现文章生成的词典,以字母顺序进行排列

print(cv.vocabulary_	)              # {‘dog’:2,'cat':1,'fish':3,'bird':0} 字典形式呈现,key:词,value:在词袋列表中的index

print(cv_fit)
'''
  (0, 2)	1  #第0个列表元素"dog cat fish",词典中索引为2的元素:‘dog’, 词频为1
  (0, 1)	1
  (0, 3)	1
  (1, 2)	1
  (1, 1)	2
  (2, 3)	1
  (2, 0)	1
  (3, 0)	1
  '''
print(cv_fit.toarray()) #.toarray() 是将结果转化为稀疏矩阵矩阵的表示方式;
'''
[[0 1 1 1]#"dog cat fish"
 [0 2 1 0]#"dog cat cat"
 [1 0 0 1]#"fish bird"
 [1 0 0 0]]#'bird'
'''

print(cv_fit.toarray().sum(axis=0))  #每个词在所有文档中的词频
#[2 3 2 2]#dog:2,cat:3,fish:3,bird:2
print(cv_fit.shape)#(4, 4)


tfidf = TfidfTransformer()
tfidf_fit = tfidf.fit_transform(cv_fit)
print(tfidf_fit)
'''
  (0, 3)	0.5773502691896257 #dog cat fish中dog对应的tfidf值
  (0, 2)	0.5773502691896257
  (0, 1)	0.5773502691896257
  (1, 2)	0.4472135954999579
  (1, 1)	0.8944271909999159
  (2, 3)	0.7071067811865475
  (2, 0)	0.7071067811865475
  (3, 0)	1.0
'''
print(tfidf_fit.toarray())
'''#对应的稀疏矩阵
[[0.         0.57735027 0.57735027 0.57735027]
 [0.         0.89442719 0.4472136  0.        ]
 [0.70710678 0.         0.         0.70710678]
 [1.         0.         0.         0.        ]]
'''

print(tfidf_fit.shape)#(4, 4)

优点与不足

TF-IDF算法的优点是简单快速,结果比较符合实际情况。缺点是,单纯以"词频"衡量一个词的重要性,不够全面,有时重要的词可能出现次数并不多。这会导致TF-IDF法的精度并不是很高。而且,这种算法无法体现词的位置信息,出现位置靠前的词与出现位置靠后的词,都被视为重要性相同,这是不正确的。(常用的一种解决方法是,对全文的第一段和每一段的第一句话,给予较大的权重。)

总结

我们通过寻找关键词入手,想要寻找一种带有权重的词频统计方法,从而引入了TF-IDF方法,并且探寻了这种方法可能应用的场景已经该方法的优点与不足。学习简单传统方法的意义就在于掌握思想、打好基础,为后面的进阶做好准备,加油。

参考文章:

通俗理解TF-IDF

TF-IDF与余弦相似性的应用(一):自动提取关键词

TF-IDF算法介绍及实现

  • 0
    点赞
  • 11
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
TF-IDF(词频-逆文档频率)是一常用的文本特征表示方法。以下是一个使用TF-IDF实现的标准demo,并附有逐行注解和通俗易懂的说明: ```python from sklearn.feature_extraction.text import TfidfVectorizer # 创建TF-IDF向量化器实例 vectorizer = TfidfVectorizer() # 定义文本数据 corpus = [ "This is the first document.", "This document is the second document.", "And this is the third one.", "Is this the first document?" ] # 使用TF-IDF向量化器对文本数据进行转换 X = vectorizer.fit_transform(corpus) # 打印转换结果 print(X.toarray()) ``` 模型解释和原理技术说明: 1. TF-IDF(词频-逆文档频率)是一种用于衡量文本中词语重要性的方法,常用于文本特征表示和信息检索。 2. 在上述代码中,首先导入了`TfidfVectorizer`类,它是scikit-learn库中用于实现TF-IDF的向量化器。 3. 创建了一个TF-IDF向量化器实例`vectorizer`。 4. 定义了一个包含多个文本的文本数据列表`corpus`。 5. 将文本数据传递给TF-IDF向量化器的`fit_transform`方法,对文本数据进行转换,得到TF-IDF特征表示的矩阵`X`。 6. `X.toarray()`将矩阵`X`转换为数组形式,并打印转换结果。 通过以上代码和解释,一个NLP新手可以了解到: - TF-IDF是一种常用的文本特征表示方法,用于衡量词语在文本中的重要性。 - TF-IDF向量化器是一种实现TF-IDF的工具,可以将文本数据转换为TF-IDF特征表示的矩阵。 - 在使用TF-IDF向量化器时,需要将文本数据传递给`fit_transform`方法进行转换。 - 转换后的结果是一个矩阵,每行代表一个文本样本,每列代表一个词语,矩阵的值表示该词语在对应文本中的TF-IDF权重。 - 通过打印转换结果,可以查看TF-IDF特征表示的矩阵。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值