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. Ubuntu安装桌面环境

    1.安装Ubuntu默认的Gnome桌面: sudo apt-get install ubuntu-desktop 2.不安装默认组件,例如Evolution和OpenOffice: sudo apt ...

  2. xdu_1165:均值滤波

    题目: Problem A 均值滤波问题描述图像中的噪声在空间上的自相关很低,因此往往可以用均值滤波加以削弱.具体来说,对于每个像素点P(x; y),我们选出所有距P 的Manhattan 距离不超过 ...

  3. 图像处理与matlab实例之图像平滑(一)

    一.何为图像噪声?噪声是妨碍人的感觉器官所接受信源信息理解的因素,是不可预测只能用概率统计方法认识的随机误差. 举个例子: 从这个图中,我们可以观察到噪声的特点:1>位置随机 2>大小不规 ...

  4. eclipse 下使用git clone

    方法一:eclipse安装好git插件后,直接import-git-project from git- clone url-输入github的网址等就可以了方法二:使用git软件,到指定的目录,右击g ...

  5. python数据结构之队列

    队列(queue)是只允许在一端进行插入操作,而在另一端进行删除操作的线性表. 队列是一种先进先出的(First In First Out)的线性表,简称FIFO.允许插入的一端为队尾,允许删除的一端 ...

  6. MySQL学习笔记(一):SQL基础

    定义:SQL即Structure Query Language(机构化查询语言)的缩写,是使用关系数据库的应用语言. 包括三个类别: (1):DDL(Data Definition Language) ...

  7. AJAX 中JSON 和JSONP 的区别 以及请求原理

    AJAX 跨域请求 - JSONP获取JSON数据 博客分类: Javascript /Jquery / Bootstrap / Web   Asynchronous JavaScript and X ...

  8. CentOS下安装Nginx服务器

    一.nginx安装环境 nginx是C语言开发,建议在linux上运行,本教程使用Centos7作为安装环境. 1.1  gcc 安装nginx需要先将官网下载的源码进行编译,编译依赖gcc环境,如果 ...

  9. Abp(.NetCore)开发与发布过程3-部署Ubuntu站点

    以下是笔者在 Ubuntu 16.0-64bit 环境下 发布 ABP(.NetCore)的全过程.特此记录,希望对大家有所帮助. 准备的工具 1.PuTTY(ssh,如果不想每次都用阿里云的远程登录 ...

  10. windows下Ubuntu虚拟机联网配置 + Ubuntu虚拟机代理配置

    Ubuntu虚拟机网络连接方式设置: http://blog.csdn.net/u013052460/article/details/50039937 or http://www.gezila.com ...