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类别区分能力不强。但是实际上,如果一个词条在一个类的文档中频繁出现,则说明该词条能够很好代表这个类的文本的特征,这样的词条应该给它们赋予较高的权重,并选来作为该类文本的特征词以区别与其它类文档。

  示例1

  有很多不同的数学公式可以用来计算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。

  示例2

   根据关键字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 依赖组件

  1) TF操作

  TF操作依赖两个类:HashingTF和CountVectorizer,它们都可以用来生成频率向量。其中HashingTF是一个Transformer子类,它接受一组数据,并将这些数据转换为固定长度的特征向量。CountVectorizer将文本文档转换为术语计数的向量。更多的细节请参考CountVectorizer

  2) IDF操作

  IDF是一个Estimator子类,其会训练数据集并生成一个IDFModel对象。IDFModel采用特征向量(通常是从HashingTF或CountVectorizer创建的),并缩放每一列。直观地说,它降低了在语料库中频繁出现的列。

2.2 示例

  如下示例通过Tokenizer类,将一组句子分离为一个个单词。对于每一个句子(单词袋),我们使用HashingTF把这个句子变成一个特征向量。我们使用IDF来重新缩放特征向量;当使用文本作为特性时,这通常会提高性能。我们的特征向量可以被传递给一个学习算法。

  1. import org.apache.spark.ml.feature.{HashingTF, IDF, Tokenizer}
  2. val sentenceData = spark.createDataFrame(Seq(
  3.   (0.0, "Hi I heard about Spark"),
  4.   (0.0, "I wish Java could use case classes"),
  5.   (1.0, "Logistic regression models are neat")
  6. )).toDF("label", "sentence")
  7.  
  8. val tokenizer = new Tokenizer().setInputCol("sentence").setOutputCol("words")
  9. val wordsData = tokenizer.transform(sentenceData)
  10.  
  11. val hashingTF = new HashingTF()
  12.   .setInputCol("words").setOutputCol("rawFeatures").setNumFeatures(20)
  13.  
  14. val featurizedData = hashingTF.transform(wordsData)
  15. // alternatively, CountVectorizer can also be used to get term frequency vectors
  16.  
  17. val idf = new IDF().setInputCol("rawFeatures").setOutputCol("features")
  18. val idfModel = idf.fit(featurizedData)
  19.  
  20. val rescaledData = idfModel.transform(featurizedData)
  21. rescaledData.select("label", "features").show()

3. Scikit-learn应用

3.1 依赖组件

  1) 安装scikit-learn包
    1. sudo pip install scikit-learn
  2) 中文分词采用的jieba分词,安装jieba分词包
    1. sudo pip install jieba

3.2 Jieba使用

  关于jieba分词的使用非常简单,参考这里,关键的语句就是(这里简单试水,不追求效果 )

  1. import jieba.posseg as pseg
  2. words=pseg.cut("对这句话进行分词")
  3. for key in words:
  4.      print key.word,key.flag

输出:

对 p

这 r

句 q

话 n

进行 v

分词 n

3.3 示例

  采用scikit-learn包进行tf-idf分词权重计算关键用到了两个类:CountVectorizer和TfidfTransformer,具体参见这里.

一个简单的代码如下:

  1. # coding:utf-8
  2. __author__ = "liuxuejiang"
  3. import jieba
  4. import jieba.posseg as pseg
  5. import os
  6. import sys
  7. from sklearn import feature_extraction
  8. from sklearn.feature_extraction.text import TfidfTransformer
  9. from sklearn.feature_extraction.text import CountVectorizer
  10.  
  11. if __name__ == "__main__":
  12.     corpus=["我 来到 北京 清华大学",#第一类文本切词后的结果,词之间以空格隔开
  13.       "他 来到 了 网易 杭研 大厦",#第二类文本的切词结果
  14.       "小明 硕士 毕业 与 中国 科学院",#第三类文本的切词结果
  15.       "我 爱 北京 天安门"]#第四类文本的切词结果
  16.     vectorizer=CountVectorizer()#该类会将文本中的词语转换为词频矩阵,矩阵元素a[i][j] 表示j词在i类文本下的词频
  17.     transformer=TfidfTransformer()#该类会统计每个词语的tf-idf权值
  18.     tfidf=transformer.fit_transform(vectorizer.fit_transform(corpus))#第一个fit_transform是计算tf-idf,第二个fit_transform是将文本转为词频矩阵
  19.     word=vectorizer.get_feature_names()#获取词袋模型中的所有词语
  20.     weight=tfidf.toarray()#将tf-idf矩阵抽取出来,元素a[i][j]表示j词在i类文本中的tf-idf权重
  21.     for i in range(len(weight)):#打印每类文本的tf-idf词语权重,第一个for遍历所有文本,第二个for便利某一类文本下的词语权重
  22.         print u"-------这里输出第",i,u"类文本的词语tf-idf权重------"
  23.         for j in range(len(word)):
  24.             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模型详解的更多相关文章

  1. ASP.NET Core的配置(2):配置模型详解

    在上面一章我们以实例演示的方式介绍了几种读取配置的几种方式,其中涉及到三个重要的对象,它们分别是承载结构化配置信息的Configuration,提供原始配置源数据的ConfigurationProvi ...

  2. ISO七层模型详解

    ISO七层模型详解 作者:尹正杰 版权声明:原创作品,谢绝转载!否则将追究法律责任. 在我刚刚接触运维这个行业的时候,去面试时总是会做一些面试题,笔试题就是看一个运维工程师的专业技能的掌握情况,这个很 ...

  3. 28、vSocket模型详解及select应用详解

    在上片文章已经讲过了TCP协议的基本结构和构成并举例,也粗略的讲过了SOCKET,但是讲解的并不完善,这里详细讲解下关于SOCKET的编程的I/O复用函数. 1.I/O复用:selec函数 在介绍so ...

  4. 第94天:CSS3 盒模型详解

    CSS3盒模型详解 盒模型设定为border-box时 width = border + padding + content 盒模型设定为content-box时 width = content所谓定 ...

  5. JVM的类加载过程以及双亲委派模型详解

    JVM的类加载过程以及双亲委派模型详解 这篇文章主要介绍了JVM的类加载过程以及双亲委派模型详解,类加载器就是根据指定全限定名称将 class 文件加载到 JVM 内存,然后再转化为 class 对象 ...

  6. 云时代架构阅读笔记六——Java内存模型详解(二)

    承接上文:云时代架构阅读笔记五——Java内存模型详解(一) 原子性.可见性.有序性 Java内存模型围绕着并发过程中如何处理原子性.可见性和有序性这三个特征来建立的,来逐个看一下: 1.原子性(At ...

  7. css 06-CSS盒模型详解

    06-CSS盒模型详解 #盒子模型 #前言 盒子模型,英文即box model.无论是div.span.还是a都是盒子. 但是,图片.表单元素一律看作是文本,它们并不是盒子.这个很好理解,比如说,一张 ...

  8. 图解机器学习 | LightGBM模型详解

    作者:韩信子@ShowMeAI 教程地址:http://www.showmeai.tech/tutorials/34 本文地址:http://www.showmeai.tech/article-det ...

  9. flink内存模型详解与案例

    任务提交时的一些yarn设置(通用客户端模式) 指定并行度                        -p 5 \ 指定yarn队列                     -Dyarn.appl ...

  10. 无所不能的Embedding6 - 跨入Transformer时代~模型详解&代码实现

    上一章我们聊了聊quick-thought通过干掉decoder加快训练, CNN-LSTM用CNN作为Encoder并行计算来提速等方法,这一章看看抛开CNN和RNN,transformer是如何只 ...

随机推荐

  1. SpringWeb增删改查

    模型类: package com; public class Model { private int id; private String name; private String dtype; pr ...

  2. (转)FastJson---高性能JSON开发包

    场景:javaBean对象转化为json对象! 1 Fastjson介绍 Fastjson是一个Java语言编写的JSON处理器,由阿里巴巴公司开发.1.遵循http://json.org标准,为其官 ...

  3. 【js】操作checkbox radio 的操作总结

    摘要 总是忘记checkbox radio 的具体操作,总是坑自己,总结下记下来 html <input type="checkbox" value="1" ...

  4. ABP+AdminLTE+Bootstrap Table权限管理系统第六节--abp控制器扩展及json封装

    一,控制器AbpController 说完了Swagger ui 我们再来说一下abp对控制器的处理和json的封装. 首先我们定义一个控制器,在新增控制器的时候,控制器会自动继承自AbpContro ...

  5. 白话ASP.NET MVC之二:Controller激活系统的概览

    前文简介:我们抽象类路由规则的对象,RouteBase是路由对象的抽象基类,ASP.NET 的路由系统中有唯一一个从RouteBase继承的路由对象,那就是Route类型了.我们注册了路由对象Rout ...

  6. Quartus16.0如何使用TCL脚本

    前言 TCL脚本语言在EDA工具中使用频繁,本文主要介绍使用TCL脚本文件进行引脚分配,避免手动分配以及分配出错: 流程 1.准备好你的TCL脚本文件,举个栗子(脚本文件内容): 2.在Quartus ...

  7. 怎么用snapman一个人在三天内开发出一个复杂的软件开发项目管理系统

    snapman是一个简单而强大的团队协作软件,在上面的信息可以是数据.可以是规则.也可以是自动化代码:最重要的它是一个可以开发的协作平台,所有信息都可以作用到所有人或机器上,大大减少了工作的复杂度.软 ...

  8. 云端TensorFlow读取数据IO的高效方式

    低效的IO方式 最近通过观察PAI平台上TensoFlow用户的运行情况,发现大家在数据IO这方面还是有比较大的困惑,主要是因为很多同学没有很好的理解本地执行TensorFlow代码和分布式云端执行T ...

  9. GitLab Development Kit 环境搭建

    在公司内网服务器上面搭建gdk环境,踩了很多坑,历时四五天(中间涉及申请开通固定外网),整理如下: 总览: 操作系统:redhat 6.3 参考文档:https://gitlab.com/gitlab ...

  10. CSS3 基础(1)——选择器详解

    CSS3选择器详解 一. 属性选择器 在CSS3中,追加了三个属性选择器分别为:[att*=val].[att^=val]和[att$=val],使得属性选择器有了通配符的概念. 选择器 示例 描述 ...