目录

前言

一、TF-IDF的由来

二、什么是TF-IDF?

2.1 TF(Term Frequency)

2.2 IDF(Inverse Document Frequency)

2.3 TF-IDF(Term Frequency-Inverse Document Frequency)

三、TF-IDF应用

四、代码实现

4.1 常规Python实现TF-IDF

4.2 NLTK实现TF-IDF

4.3 Jieba实现TF-IDF算法

五、TF-IDF不足之处

六、TF-IDF变种

5.1 通过对数函数避免 TF 线性增长

5.2 标准化解决长文档、短文档问题

5.3 对数函数处理 IDF

5.4 查询词及文档向量标准化

六、参考文章


前言

最近在读一篇论文《Mining Quality Phrases from Massive Text Corpora》,其中涉及到了TF-IDF和随机森林算法(Random Forest),顾对两个算法进行巩固加深记忆,这篇文章主要是讲TF-IDF算法,行文过程中参考了几篇博文,做了如下总结。

一、TF-IDF的由来

把查询关键字(Query)和文档(Document)都转换成 “向量”,并且尝试用线性代数等数学工具来解决信息检索问题,这样的努力至少可以追溯到 20 世纪 70 年代。

1971 年,美国康奈尔大学教授杰拉德 · 索尔顿(Gerard Salton)发表了《SMART 检索系统:自动文档处理实验》(The SMART Retrieval System—Experiments in Automatic Document Processing)一文,文中首次提到了把查询关键字和文档都转换成 “向量”,并且给这些向量中的元素赋予不同的值。这篇论文中描述的 SMART 检索系统,特别是其中对 TF-IDF 及其变种的描述成了后续很多工业级系统的重要参考。

1972 年,英国的计算机科学家卡伦 · 琼斯(Karen Spärck Jones)在《从统计的观点看词的特殊性及其在文档检索中的应用》(A Statistical Interpretation of Term Specificity and Its Application in Retrieval) 一文中第一次详细地阐述了 IDF 的应用。其后卡伦又在《检索目录中的词赋值权重》(Index Term Weighting)一文中对 TF 和 IDF 的结合进行了论述。可以说,卡伦是第一位从理论上对 TF-IDF 进行完整论证的计算机科学家,因此后世也有很多人把 TF-IDF 的发明归结于卡伦。

杰拉德本人被认为是 “信息检索之父”。他 1927 年出生于德国的纽伦堡,并与 1950 年和 1952 年先后从纽约的布鲁克林学院获得数学学士和硕士学位,1958 年从哈佛大学获得应用数学博士学位,之后来到康奈尔大学参与组建计算机系。为了致敬杰拉德本人对现代信息检索技术的卓越贡献,现在,美国计算机协会 ACM(Association of Computing Machinery)每三年颁发一次“杰拉德 · 索尔顿奖”(Gerard Salton Award),用于表彰对信息检索技术有突出贡献的研究人员。卡伦 · 琼斯在 1988 年获得了第二届“杰拉德 · 索尔顿奖” 的殊荣。

二、什么是TF-IDF?

TF-IDF(Term Frequency-Inverse Document Frequency, 词频-逆文件频率)是一种用于资讯检索与资讯探勘的常用加权技术。TF-IDF是一种统计方法,用以评估一字词对于一个文件集或一个语料库中的其中一份文件的重要程度。字词的重要性随着它在文件中出现的次数成正比增加,但同时会随着它在语料库中出现的频率成反比下降。

简单来说就是:一个词语在一篇文章中出现次数越多, 同时在所有文档中出现次数越少, 越能够代表该文章。这也就是TF-IDF的含义。

2.1 TF(Term Frequency)

词频(TF)表示词条(关键字)在文本中出现的频率

这个数字通常会被归一化(一般是词频除以文章总词数), 以防止它偏向长的文件。

公式   (术语 t 在文档中出现的次数) / (文档中的术语总数)

但是,需要注意, 一些通用的词语对于主题并没有太大的作用, 反倒是一些出现频率较少的词才能够表达文章的主题, 所以单纯使用是TF不合适的。权重的设计必须满足:一个词预测主题的能力越强,权重越大,反之,权重越小。所有统计的文章中,一些词只是在其中很少几篇文章中出现,那么这样的词对文章的主题的作用很大,这些词的权重应该设计的较大。IDF就是在完成这样的工作。

2.2 IDF(Inverse Document Frequency)

逆向文件频率 (IDF) :某一特定词语的IDF,可以由总文件数目除以包含该词语的文件的数目再将得到的商取对数得到

如果包含词条t的文档越少, IDF越大,则说明词条具有很好的类别区分能力。

     log_e(文档总数/包含术语 t 的文档数)

其中,|D| 是语料库中的文件总数 |{j:ti∈dj}| 表示包含词语 ti 的文件数目(即 ni,j≠0 的文件数目)。如果该词语不在语料库中,就会导致分母为零,因此一般情况下使用 1+|{j:ti∈dj}|

IDF用于衡量一个术语的重要性。在计算 TF 时,所有项都被认为同样重要。然而,众所周知,某些术语,如"是","的"和"那个",可能会出现很多次,但并不重要。因此,我们需要通过计算以下内容来权衡常用术语,同时放大稀有术语:IDF(t)

2.3 TF-IDF(Term Frequency-Inverse Document Frequency)

某一特定文件内的高词语频率,以及该词语在整个文件集合中的低文件频率,可以产生出高权重的TF-IDF。因此,TF-IDF倾向于过滤掉常见的词语,保留重要的词语,表达为

注:  TF-IDF算法非常容易理解,并且很容易实现,但是其简单结构并没有考虑词语的语义信息,无法处理一词多义与一义多词的情况。

三、TF-IDF应用

(1)搜索引擎;(2)关键词提取;(3)文本相似性;(4)文本摘要

四、代码实现

4.1 常规Python实现TF-IDF

# -*- coding: utf-8 -*-
from collections import defaultdict
import math
import operator"""
函数说明:创建数据样本
Returns:dataset - 实验样本切分的词条classVec - 类别标签向量
"""
def loadDataSet():dataset = [ ['my', 'dog', 'has', 'flea', 'problems', 'help', 'please'],    # 切分的词条['maybe', 'not', 'take', 'him', 'to', 'dog', 'park', 'stupid'],['my', 'dalmation', 'is', 'so', 'cute', 'I', 'love', 'him'],['stop', 'posting', 'stupid', 'worthless', 'garbage'],['mr', 'licks', 'ate', 'my', 'steak', 'how', 'to', 'stop', 'him'],['quit', 'buying', 'worthless', 'dog', 'food', 'stupid'] ]classVec = [0, 1, 0, 1, 0, 1]  # 类别标签向量,1代表好,0代表不好return dataset, classVec"""
函数说明:特征选择TF-IDF算法
Parameters:list_words:词列表
Returns:dict_feature_select:特征选择词字典
"""
def feature_select(list_words):#总词频统计doc_frequency=defaultdict(int)for word_list in list_words:for i in word_list:doc_frequency[i]+=1#计算每个词的TF值word_tf={}  #存储没个词的tf值for i in doc_frequency:word_tf[i]=doc_frequency[i]/sum(doc_frequency.values())#计算每个词的IDF值doc_num=len(list_words)word_idf={} #存储每个词的idf值word_doc=defaultdict(int) #存储包含该词的文档数for i in doc_frequency:for j in list_words:if i in j:word_doc[i]+=1for i in doc_frequency:word_idf[i]=math.log(doc_num/(word_doc[i]+1))#计算每个词的TF*IDF的值word_tf_idf={}for i in doc_frequency:word_tf_idf[i]=word_tf[i]*word_idf[i]# 对字典按值由大到小排序dict_feature_select=sorted(word_tf_idf.items(),key=operator.itemgetter(1),reverse=True)return dict_feature_selectif __name__=='__main__':data_list,label_list=loadDataSet() #加载数据features=feature_select(data_list) #所有词的TF-IDF值print(features)print(len(features))

打印结果如下

[('to', 0.0322394037469742), ('stop', 0.0322394037469742), ('worthless', 0.0322394037469742), ('my', 0.028288263356383563), ('dog', 0.028288263356383563), ('him', 0.028288263356383563), ('stupid', 0.028288263356383563), ('has', 0.025549122992281622), ('flea', 0.025549122992281622), ('problems', 0.025549122992281622), ('help', 0.025549122992281622), ('please', 0.025549122992281622), ('maybe', 0.025549122992281622), ('not', 0.025549122992281622), ('take', 0.025549122992281622), ('park', 0.025549122992281622), ('dalmation', 0.025549122992281622), ('is', 0.025549122992281622), ('so', 0.025549122992281622), ('cute', 0.025549122992281622), ('I', 0.025549122992281622), ('love', 0.025549122992281622), ('posting', 0.025549122992281622), ('garbage', 0.025549122992281622), ('mr', 0.025549122992281622), ('licks', 0.025549122992281622), ('ate', 0.025549122992281622), ('steak', 0.025549122992281622), ('how', 0.025549122992281622), ('quit', 0.025549122992281622), ('buying', 0.025549122992281622), ('food', 0.025549122992281622)]
32

4.2 NLTK实现TF-IDF

from nltk.text import TextCollection
from nltk.tokenize import word_tokenize#首先,构建语料库corpus
sents=['this is sentence one','this is sentence two','this is sentence three']
sents=[word_tokenize(sent) for sent in sents] #对每个句子进行分词
print(sents)  #输出分词后的结果
corpus=TextCollection(sents)  #构建语料库
print(corpus)  #输出语料库#计算语料库中"one"的tf值
tf=corpus.tf('one',corpus)    # 1/12
print(tf)#计算语料库中"one"的idf值
idf=corpus.idf('one')      #log(3/1)
print(idf)#计算语料库中"one"的tf-idf值
tf_idf=corpus.tf_idf('one',corpus)
print(tf_idf)

打印结果如下

[['this', 'is', 'sentence', 'one'], ['this', 'is', 'sentence', 'two'], ['this', 'is', 'sentence', 'three']]
<Text: this is sentence one this is sentence two...>
0.08333333333333333
1.0986122886681098
0.0915510240556758

注:代码运行过程中可能报错,解决方法参考下文

NLTK:Resource punkt not found. Please use the NLTK Downloader to obtain the resource_massive_jiang的博客-CSDN博客

4.3 Jieba实现TF-IDF算法

import jieba.analysetext='关键词是能够表达文档中心内容的词语,常用于计算机系统标引论文内容特征、信息检索、系统汇集以供读者检阅。关键词提取是文本挖掘领域的一个分支,是文本检索、文档比较、摘要生成、文档分类和聚类等文本挖掘研究的基础性工作'keywords=jieba.analyse.extract_tags(text, topK=5, withWeight=False, allowPOS=())
print(keywords)

打印结果如下

['文档', '文本', '关键词', '挖掘', '文本检索']

注:

jieba.analyse.extract_tags(sentence, topK=20, withWeight=False, allowPOS=())
sentence 为待提取的文本
topK 为返回几个 TF/IDF 权重最大的关键词,默认值为 20
withWeight 为是否一并返回关键词权重值,默认值为 False
allowPOS 仅包括指定词性的词,默认值为空,即不筛选

五、TF-IDF不足之处

TF-IDF算法是建立在这样一个假设之上的:对区别文档最有意义的词语应该是那些在文档中出现频率高,而在整个文档集合的其他文档中出现频率少的词语,所以如果特征空间坐标系取TF词频作为测度,就可以体现同类文本的特点。另外考虑到单词区别不同类别的能力,TF-IDF法认为一个单词出现的文本频数(即包含某个单词的文本数)越小,它区别不同类别文本的能力就越大。因此引入了逆文本频度IDF的概念,以TF和IDF的乘积作为特征空间坐标系的取值测度,并用它完成对权值TF的调整,调整权值的目的在于突出重要单词,抑制次要单词。但是在本质上IDF是一种试图抑制噪声的加权,并且单纯地认为文本频率小的单词就越重要,文本频率大的单词就越无用,显然这并不是完全正确的。IDF的简单结构并不能有效地反映单词的重要程度和特征词的分布情况,使其无法很好地完成对权值调整的功能,所以TF-IDF法的精度并不是很高。

此外,在TFIDF算法中并没有体现出单词的位置信息,对于Web文档而言,权重的计算方法应该体现出HTML的结构特征。特征词在不同的标记符中对文章内容的反映程度不同,其权重的计算方法也应不同。因此应该对于处于网页不同位置的特征词分别赋予不同的系数,然后乘以特征词的词频,以提高文本表示的效果。

注:TF-IDF 算法主要适用于英文,中文首先要分词,分词后要解决多词一义,以及一词多义问题,这两个问题通过简单的tf-idf方法不能很好的解决。于是就有了后来的词嵌入方法,用向量来表征一个词。

六、TF-IDF变种

5.1 通过对数函数避免 TF 线性增长

很多人注意到 TF 的值在原始的定义中没有任何上限。虽然我们一般认为一个文档包含查询关键词多次相对来说表达了某种相关度,但这样的关系很难说是线性的。拿我们刚才举过的关于 “Car Insurance” 的例子来说,文档 A 可能包含 “Car” 这个词 100 次,而文档 B 可能包含 200 次,是不是说文档 B 的相关度就是文档 A 的 2 倍呢?其实,很多人意识到,超过了某个阈值之后,这个 TF 也就没那么有区分度了。

用 Log,也就是对数函数,对 TF 进行变换,就是一个不让 TF 线性增长的技巧。具体来说,人们常常用 1+Log(TF) 这个值来代替原来的 TF 取值。在这样新的计算下,假设 “Car” 出现一次,新的值是 1,出现 100 次,新的值是 5.6,而出现 200 次,新的值是 6.3。很明显,这样的计算保持了一个平衡,既有区分度,但也不至于完全线性增长。

5.2 标准化解决长文档、短文档问题

经典的计算并没有考虑 “长文档” 和“短文档”的区别。一个文档 A 有 3,000 个单词,一个文档 B 有 250 个单词,很明显,即便 “Car” 在这两个文档中都同样出现过 20 次,也不能说这两个文档都同等相关。对 TF 进行 “标准化”(Normalization),特别是根据文档的最大 TF 值进行的标准化,成了另外一个比较常用的技巧

5.3 对数函数处理 IDF

第三个常用的技巧,也是利用了对数函数进行变换的,是对 IDF 进行处理。相对于直接使用 IDF 来作为 “惩罚因素”,我们可以使用 N+1 然后除以 DF 作为一个新的 DF 的倒数,并且再在这个基础上通过一个对数变化。这里的 N 是所有文档的总数。这样做的好处就是,第一,使用了文档总数来做标准化,很类似上面提到的标准化的思路;第二,利用对数来达到非线性增长的目的。

5.4 查询词及文档向量标准化

还有一个重要的 TF-IDF 变种,则是对查询关键字向量,以及文档向量进行标准化,使得这些向量能够不受向量里有效元素多少的影响,也就是不同的文档可能有不同的长度。在线性代数里,可以把向量都标准化为一个单位向量的长度。这个时候再进行点积运算,就相当于在原来的向量上进行余弦相似度的运算。所以,另外一个角度利用这个规则就是直接在多数时候进行余弦相似度运算,以代替点积运算。

六、参考文章

1. TF-IDF 原理与实现 - 知乎 (zhihu.com)

2. 通俗理解TF-IDF - 简书 (jianshu.com)

3. Tf-idf :: 单页教程 - 信息检索和文本挖掘 (tfidf.com)

4. 一文看懂 TF-IDF (概念图解+4大变种+发展历史) (easyai.tech)

5. TF-IDF算法介绍及实现_Asia-Lee-CSDN博客_tf-idf

6. 机器学习:生动理解TF-IDF算法 - 知乎 (zhihu.com)

TF-IDF算法(原理+python代码实现)相关推荐

  1. 关键词提取算法—TF/IDF算法

    关键词提取算法一般可分为有监督学习和无监督学习两类. 有监督的关键词提取方法可以通过分类的方式进行,通过构建一个较为完善的词表,然后判断每个文档与词表中的每个词的匹配程度,以类似打标签的方式,达到关键 ...

  2. SSD算法原理与代码(三)

    说明:这几篇文章是讲解SSD,从算法原理.代码到部署到rk3588芯片上的过程.环境均是TF2.2,具体的安装过程请参考网上其他的文章. 一.SSD简介 SSD算法是一个优秀的one-stage目标检 ...

  3. 深度强化学习-D3QN算法原理与代码

    Dueling Double Deep Q Network(D3QN)算法结合了Double DQN和Dueling DQN算法的思想,进一步提升了算法的性能.如果对Doubel DQN和Duelin ...

  4. Kmean聚类算法原理python实现

    Kmean聚类算法原理python实现 Kmean聚类算法是基于距离对对象进行分类的算法,该算法实现步骤如下: 1.确定初始数据簇质心,质心的数量与需要分的类的数量一致: 2.将数据集中的每一个对象与 ...

  5. 深度强化学习-Double DQN算法原理与代码

    深度强化学习-Double DQN算法原理与代码 引言 1 DDQN算法简介 2 DDQN算法原理 3 DDQN算法伪代码 4 仿真验证 引言 Double Deep Q Network(DDQN)是 ...

  6. 多类线性分类器算法原理及代码实现 MATLAB

    多类线性分类器算法原理及代码实现 MATLAB 一.算法原理 下面举例说明为何蓝圈部分在case2中是确定的而在case1中不确定: 二.代码实现 1.HK函数 function [] = HK(w1 ...

  7. 计算机图形学--中点椭圆算法原理及代码实现

    目录 椭圆的几何特性: 算法原理: 代码实现: 说明,我们这里讨论的椭圆都是对称轴平行于坐标轴的椭圆,对于其他方程较为复杂的椭圆我们不做讨论. 椭圆的几何特性: 首先我们考虑椭圆的几何特性.椭圆是抽对 ...

  8. 论文|Node2vec算法原理、代码实战和在微信朋友圈的应用

    1 概述 Node2vec是2016年斯坦福教授 Jure Leskovec.Aditya Grover提出的论文,论文的下载链接为:https://arxiv.org/pdf/1607.00653. ...

  9. 随笔_从《芳华》影评到TF/IDF算法

     前两天看好多<芳华>的影评说:为什么好人没好报?于是感叹一堆世态炎凉,人性丑陋什么的.我觉得这问题是:为什么中央空调(对谁都温暖)往往不被看好.  先说说TF/IDF算法,这是一种信息处 ...

  10. 萤火虫算法_40多种智能优化算法原理和代码分享

    40多种智能优化算法原理和代码分享 <智能优化算法讲解>PDF下载地址: <智能优化算法原理讲解>PDF​mianbaoduo.com 包括: 1.海鸥算法SOA 智能优化算法 ...

最新文章

  1. 声明一个const数组
  2. Python zip() 与 map()的用法
  3. NYOJ 士兵杀敌(四) 树状数组
  4. 中科院分区 2020_2020中科院期刊分区出炉!文末附2020年中科院期刊分区基础版(全)...
  5. 小知识:常用开源协议详细解析
  6. WordPress二次开发经验简短总结
  7. 3 CO配置-企业结构-分配-把公司代码分配给成本控制范围
  8. mysql必会语法_sql语法:sql必读必会(二)mysql中的函数大全
  9. Xna环境在PC平台下的功能扩展
  10. IIS 配置 url 重写...
  11. CentOS 7 下安装.NET Core SDK 2.1
  12. exec还原oracle,详解通过Backup Exec来实施Oracle灾难恢复
  13. 计算机装配方案之游戏发烧型,5000元Intel八代i5-8500配RX580电脑配置 畅玩各类中大型游戏...
  14. IcedTea6 1.9已通过HotSpot 17更新为OpenJDK6 b20
  15. 转:原来可以这样出书、写书?
  16. Mysql桌面工具--SQLyog使用方法,告别黑白命令行
  17. 爬虫(豆瓣电影Top250数据分析)学习笔记
  18. ftp文件缓存服务器,ftp服务器上的缓存在哪
  19. 基于Servlet的验证码登陆demo
  20. 1W存一年和两个5000存一年,收益有区别吗?

热门文章

  1. matlab数学实验课件5,matlab_intro_西安交通大学-数学实验教案_ppt_大学课件预览_高等教育资讯网...
  2. TR069协议与商业应用6——TR069动态库开发
  3. #芯片# R8025(RX-8025T)
  4. 拼音输入法技巧-智能ABC
  5. 关于淘宝出售的杀毒软件激活码
  6. 使用Java轻松破解顶象滑动拼图验证码,成功率接近100%?
  7. 代管挂账业务,没有做代管挂账确认单是否可以暂估入账
  8. 【论文阅读】深度学习与多种机器学习方法在不同的药物发现数据集进行对比
  9. 使用 Python 合并地图瓦片
  10. O2O营销模式的特点