TF-IDF模型详解
1. 理论基础
由于数据挖掘所有数据都要以数字形式存在,而文本是以字符串形式存在。所以进行文本挖掘时需要先对字符串进行数字化,从而能够进行计算。TF-IDF就是这样一种技术,能够将字符串转换为数字,从而能够进行数据计算。
TF-IDF(term frequency–inverse document frequency)是一种用于资讯检索与资讯探勘的常用加权技术。TF-IDF是一种统计方法,用以评估一字词对于一个文件集或一份文件对于所在的一个语料库中的重要程度。字词的重要性随着它在文件中出现的次数成正比增加,但同时会随着它在语料库中出现的频率成反比下降。
TF意思是词频(Term Frequency),IDF意思是逆向文件频率(Inverse Document Frequency)。
1.1 简介
FIDF的主要思想是:如果某个词或短语在一篇文章中出现的频率TF高,并且在其他文章中很少出现,即IDF低,则认为此词或者短语具有很好的类别区分能力,适合用来分类。
可以将一个词对的TF-IDF值表示为公式-1,该值明确定义了对于分类的重要性,值越大,说明越有益于分类;值越小,说明越无益于分类。
1.2 TF(词频)
在一份给定的文件里,词频(term frequency,TF)指的是某一个给定的词语在该文件中出现的频率。这个数字是对词数(term count)的归一化,以防止它偏向长的文件。(同一个词语在长文件里可能会比短文件有更高的词数,而不管该词语重要与否。)对于在某一特定文件里的词语ti来说,它的重要性可表示为:
以上式子中ni,j是该词在文件dj中的出现次数,而分母则是在文件dj中所有字词的出现次数之和。
1.3 IDF(逆向文件频率)
逆向文件频率 (inverse document frequency, IDF) 是一个词语普遍重要性的度量。某一特定词语的IDF,可以由总文件数目除以包含该词语之文件的数目,再将得到的商取对数得到。
其中:
- |D|:语料库中的文件总数;
- |{j:ti∈dj}|:包含词语ti的文件数目,如果该词语不在语料库中,就会导致被除数为零,因此一般情况下使用1+|{j:ti∈dj}|
所以公式-1可以表示为:
某一特定文件内的高词语频率,以及该词语在整个文件集合中的低文件频率,可以产生出高权重的TF-IDF。因此,TF-IDF倾向于过滤掉常见的词语,保留重要的词语。
1.4示例
TFIDF实际上是:TF * IDF,TF词频(Term Frequency),IDF逆向文件频率(Inverse Document Frequency)。TF表示词条在文档d中出现的频率。IDF的主要思想是:如果包含词条t的文档越少,也就是n越小,IDF越大,则说明词条t具有很好的类别区分能力。
如果某一类文档C中包含词条t的文档数为m,而其它类包含t的文档总数为k,显然所有包含t的文档数n=m+k,当m大的时候,n也大,按照IDF公式得到的IDF的值会小,就说明该词条t类别区分能力不强。但是实际上,如果一个词条在一个类的文档中频繁出现,则说明该词条能够很好代表这个类的文本的特征,这样的词条应该给它们赋予较高的权重,并选来作为该类文本的特征词以区别与其它类文档。
有很多不同的数学公式可以用来计算TF-IDF。这边的例子以上述的数学公式来计算。词频 (TF) 是一词语出现的次数除以该文件的总词语数。假如一篇文件的总词语数是100个,而词语"母牛"出现了3次,那么"母牛"一词在该文件中的词频就是3/100=0.03。一个计算文件频率 (DF) 的方法是测定有多少份文件出现过"母牛"一词,然后除以文件集里包含的文件总数。所以,如果"母牛"一词在1,000份文件出现过,而文件总数是10,000,000份的话,其逆向文件频率就是 log(10,000,000 / 1,000)=4。最后的TF-IDF的分数为0.03 * 4=0.12。
根据关键字k1,k2,k3进行搜索结果的相关性就变成TF1*IDF1 + TF2*IDF2 + TF3*IDF3。比如document1的term总量为1000,k1,k2,k3在document1出现的次数是100,200,50。包含了 k1, k2, k3的docuement总量分别是 1000, 10000,5000。document set的总量为10000。 TF1 = 100/1000 = 0.1 TF2 = 200/1000 = 0.2 TF3 = 50/1000 = 0.05 IDF1 = log(10000/1000) = log(10) = 2.3 IDF2 = log(10000/100000) = log(1) = 0; IDF3 = log(10000/5000) = log(2) = 0.69 这样关键字k1,k2,k3与docuement1的相关性= 0.1*2.3 + 0.2*0 + 0.05*0.69 = 0.2645 其中k1比k3的比重在document1要大,k2的比重是0.
2. Spark应用
Spark有两个机器学习的算法库:mlLib和ml,这两个库的最大区别是依赖的容器不同。mlLib将数据存储在DataFrame中,而ml是将数据存储在RDD中。其中mlLib较新,所以本文只对mlLib的TF-IDF进行介绍。其中对于Spark mlLib框架和使用方式不熟悉可以参考另外一篇文章。
2.1 依赖组件
TF操作依赖两个类:HashingTF和CountVectorizer,它们都可以用来生成频率向量。其中HashingTF是一个Transformer子类,它接受一组数据,并将这些数据转换为固定长度的特征向量。CountVectorizer将文本文档转换为术语计数的向量。更多的细节请参考CountVectorizer。
IDF是一个Estimator子类,其会训练数据集并生成一个IDFModel对象。IDFModel采用特征向量(通常是从HashingTF或CountVectorizer创建的),并缩放每一列。直观地说,它降低了在语料库中频繁出现的列。
2.2 示例
如下示例通过Tokenizer类,将一组句子分离为一个个单词。对于每一个句子(单词袋),我们使用HashingTF把这个句子变成一个特征向量。我们使用IDF来重新缩放特征向量;当使用文本作为特性时,这通常会提高性能。我们的特征向量可以被传递给一个学习算法。
- import org.apache.spark.ml.feature.{HashingTF, IDF, Tokenizer}
- val sentenceData = spark.createDataFrame(Seq(
- (0.0, "Hi I heard about Spark"),
- (0.0, "I wish Java could use case classes"),
- (1.0, "Logistic regression models are neat")
- )).toDF("label", "sentence")
- val tokenizer = new Tokenizer().setInputCol("sentence").setOutputCol("words")
- val wordsData = tokenizer.transform(sentenceData)
- val hashingTF = new HashingTF()
- .setInputCol("words").setOutputCol("rawFeatures").setNumFeatures(20)
- val featurizedData = hashingTF.transform(wordsData)
- // alternatively, CountVectorizer can also be used to get term frequency vectors
- val idf = new IDF().setInputCol("rawFeatures").setOutputCol("features")
- val idfModel = idf.fit(featurizedData)
- val rescaledData = idfModel.transform(featurizedData)
- rescaledData.select("label", "features").show()
3. Scikit-learn应用
3.1 依赖组件
- sudo pip install scikit-learn
- sudo pip install jieba
3.2 Jieba使用
关于jieba分词的使用非常简单,参考这里,关键的语句就是(这里简单试水,不追求效果 )
- import jieba.posseg as pseg
- words=pseg.cut("对这句话进行分词")
- for key in words:
- print key.word,key.flag
输出: 对 p 这 r 句 q 话 n 进行 v 分词 n |
3.3 示例
采用scikit-learn包进行tf-idf分词权重计算关键用到了两个类:CountVectorizer和TfidfTransformer,具体参见这里.
一个简单的代码如下:
- # coding:utf-8
- __author__ = "liuxuejiang"
- import jieba
- import jieba.posseg as pseg
- import os
- import sys
- from sklearn import feature_extraction
- from sklearn.feature_extraction.text import TfidfTransformer
- from sklearn.feature_extraction.text import CountVectorizer
- if __name__ == "__main__":
- corpus=["我 来到 北京 清华大学",#第一类文本切词后的结果,词之间以空格隔开
- "他 来到 了 网易 杭研 大厦",#第二类文本的切词结果
- "小明 硕士 毕业 与 中国 科学院",#第三类文本的切词结果
- "我 爱 北京 天安门"]#第四类文本的切词结果
- vectorizer=CountVectorizer()#该类会将文本中的词语转换为词频矩阵,矩阵元素a[i][j] 表示j词在i类文本下的词频
- transformer=TfidfTransformer()#该类会统计每个词语的tf-idf权值
- tfidf=transformer.fit_transform(vectorizer.fit_transform(corpus))#第一个fit_transform是计算tf-idf,第二个fit_transform是将文本转为词频矩阵
- word=vectorizer.get_feature_names()#获取词袋模型中的所有词语
- weight=tfidf.toarray()#将tf-idf矩阵抽取出来,元素a[i][j]表示j词在i类文本中的tf-idf权重
- for i in range(len(weight)):#打印每类文本的tf-idf词语权重,第一个for遍历所有文本,第二个for便利某一类文本下的词语权重
- print u"-------这里输出第",i,u"类文本的词语tf-idf权重------"
- for j in range(len(word)):
- print word[j],weight[i][j]
程序输出:每行格式为:词语 tf-idf权重
-------这里输出第 0 类文本的词语tf-idf权重------ #该类对应的原文本是:"我来到北京清华大学" 中国 0.0 北京 0.52640543361 大厦 0.0 天安门 0.0 小明 0.0 来到 0.52640543361 杭研 0.0 毕业 0.0 清华大学 0.66767854461 硕士 0.0 科学院 0.0 网易 0.0 -------这里输出第 1 类文本的词语tf-idf权重------ #该类对应的原文本是: "他来到了网易杭研大厦" 中国 0.0 北京 0.0 大厦 0.525472749264 天安门 0.0 小明 0.0 来到 0.414288751166 杭研 0.525472749264 毕业 0.0 清华大学 0.0 硕士 0.0 科学院 0.0 网易 0.525472749264 -------这里输出第 2 类文本的词语tf-idf权重------ #该类对应的原文本是: "小明硕士毕业于中国科学院" 中国 0.4472135955 北京 0.0 大厦 0.0 天安门 0.0 小明 0.4472135955 来到 0.0 杭研 0.0 毕业 0.4472135955 清华大学 0.0 硕士 0.4472135955 科学院 0.4472135955 网易 0.0 -------这里输出第 3 类文本的词语tf-idf权重------ #该类对应的原文本是: "我爱北京天安门" 中国 0.0 北京 0.61913029649 大厦 0.0 天安门 0.78528827571 小明 0.0 来到 0.0 杭研 0.0 毕业 0.0 清华大学 0.0 硕士 0.0 科学院 0.0 网易 0.0 |
4. 参考文献
[1].tf-idf.
[2].TF-IDF原理及使用.
[3].python scikit-learn计算tf-idf词语权重.
[4].Python TF-IDF计算100份文档关键词权重.
[5].Spark mllib官网.
TF-IDF模型详解的更多相关文章
- ASP.NET Core的配置(2):配置模型详解
在上面一章我们以实例演示的方式介绍了几种读取配置的几种方式,其中涉及到三个重要的对象,它们分别是承载结构化配置信息的Configuration,提供原始配置源数据的ConfigurationProvi ...
- ISO七层模型详解
ISO七层模型详解 作者:尹正杰 版权声明:原创作品,谢绝转载!否则将追究法律责任. 在我刚刚接触运维这个行业的时候,去面试时总是会做一些面试题,笔试题就是看一个运维工程师的专业技能的掌握情况,这个很 ...
- 28、vSocket模型详解及select应用详解
在上片文章已经讲过了TCP协议的基本结构和构成并举例,也粗略的讲过了SOCKET,但是讲解的并不完善,这里详细讲解下关于SOCKET的编程的I/O复用函数. 1.I/O复用:selec函数 在介绍so ...
- 第94天:CSS3 盒模型详解
CSS3盒模型详解 盒模型设定为border-box时 width = border + padding + content 盒模型设定为content-box时 width = content所谓定 ...
- JVM的类加载过程以及双亲委派模型详解
JVM的类加载过程以及双亲委派模型详解 这篇文章主要介绍了JVM的类加载过程以及双亲委派模型详解,类加载器就是根据指定全限定名称将 class 文件加载到 JVM 内存,然后再转化为 class 对象 ...
- 云时代架构阅读笔记六——Java内存模型详解(二)
承接上文:云时代架构阅读笔记五——Java内存模型详解(一) 原子性.可见性.有序性 Java内存模型围绕着并发过程中如何处理原子性.可见性和有序性这三个特征来建立的,来逐个看一下: 1.原子性(At ...
- css 06-CSS盒模型详解
06-CSS盒模型详解 #盒子模型 #前言 盒子模型,英文即box model.无论是div.span.还是a都是盒子. 但是,图片.表单元素一律看作是文本,它们并不是盒子.这个很好理解,比如说,一张 ...
- 图解机器学习 | LightGBM模型详解
作者:韩信子@ShowMeAI 教程地址:http://www.showmeai.tech/tutorials/34 本文地址:http://www.showmeai.tech/article-det ...
- flink内存模型详解与案例
任务提交时的一些yarn设置(通用客户端模式) 指定并行度 -p 5 \ 指定yarn队列 -Dyarn.appl ...
- 无所不能的Embedding6 - 跨入Transformer时代~模型详解&代码实现
上一章我们聊了聊quick-thought通过干掉decoder加快训练, CNN-LSTM用CNN作为Encoder并行计算来提速等方法,这一章看看抛开CNN和RNN,transformer是如何只 ...
随机推荐
- 处理文本,提取数据的脚本-主要就是用sed
处理文本,提取数据的脚本 #! /bin/sh | sed 's/)<\/small><\/td><td>/\n/g' # 用换行符替换 # 删除带有分号的行 # ...
- Everything 使用记录
背景:在windows环境下,使用系统自带的搜索框经常出现搜索不到指定文件的问题,在网上无意发现了这款软件,真的很好用! 1 文件列表 建立文件列表主要是为了以后可以在指定的目录内查找自己想要的文件, ...
- LeetCode题解 343.Integer Break
题目:Given a positive integer n, break it into the sum of at least two positive integers and maximize ...
- angular JS中使用jquery datatable 自定义搜索按钮点击事件 和mRender的 ng-click事件
'use strict'; app.controller('DataTableCtrl', function ($scope, $compile) { $scope.searchFiles = { n ...
- opnet点对点通信模型 分类: opnet 2014-05-26 22:15 246人阅读 评论(3) 收藏
网络包含两个节点,一个发送节点,一个接收节点.发送节点按照某种随机的规律产生数据包(包大小和包间隔可自己定义),然后发送给接收节点.传输过程中会有一些随机的差错(误包率也可自己定义).接收节点收到正确 ...
- maven相关的学习资料
1, maven的settings配置文件详解: http://blog.csdn.net/jinshuaiwang/article/details/23686099 2,maven原理---翡青的博 ...
- [补档]暑假集训D8总结
%dalao 今天有两位大佬来讲课,meaty来讲了Catalan(本来说好的莫比乌斯反演呢),聪聪来讲Splay呢 至于听课笔记= =,没来得及记= = 不过好不想上树啊,上了树就下不来了 考试 仍 ...
- ffmpeg编解码视频导致噪声增大的一种解决方法
一.前言 ffmpeg在视音频编解码领域算是一个比较成熟的解决方案了.公司的一款视频编辑软件正是基于ffmpeg做了二次封装,并在此基础上进行音视频的编解码处理.然而,在观察编码后的视频质量时,发现图 ...
- mysql创建定时任务,每月1号删除上月数据
1.创建存储过程: CREATE DEFINER=`gzy`@`%` PROCEDURE `delLastMonth`() BEGIN DECLARE lastmonth int; SET lastm ...
- 【有意思的BUG】分享按钮 分享功能
[分享按钮]是一个常见的功能,你可以把看到的有意思的东西分享到自己的BLOG.朋友圈之类的地方. 但是,分享出去的文本(也可以包含图片)在每个目标网站上面的格式并不是统一的,所以就存在了美感的三六九等 ...