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. MySQL IO线程及相关参数调优

    一.关于一个SQL的简单的工作过程 1.工作前提描述 1.启动MySQL,在内存中分配一个大空间innodb_buffer_pool(其中log_buffer) 2.多用户线程连接MySQL,从内存分 ...

  2. TCP简单通讯

    客户端代码: package com.kaige123.net01; import java.io.IOException; import java.io.InputStream; import ja ...

  3. docker~使用阿里加速器安centos

    回到目录 上一篇说了hub.docker.com里拉个镜像太,而阿里云为我们做了不少本国镜像,这样下载的速度就很惊人了,下面看一下在centos7下配置阿里云加速器的方法 打开服务配置文件 vi /e ...

  4. 在Docker Hub上查找可用的Image映像

    任何人都可以创建Docker Image映像,你可以浏览Docker Hub来查找这些Image映像. 定位Whalesay 映像 打开你的浏览器,浏览Docker Hub: Docker Hub包含 ...

  5. python爬虫主要就是五个模块:爬虫启动入口模块,URL管理器存放已经爬虫的URL和待爬虫URL列表,html下载器,html解析器,html输出器 同时可以掌握到urllib2的使用、bs4(BeautifulSoup)页面解析器、re正则表达式、urlparse、python基础知识回顾(set集合操作)等相关内容。

    本次python爬虫百步百科,里面详细分析了爬虫的步骤,对每一步代码都有详细的注释说明,可通过本案例掌握python爬虫的特点: 1.爬虫调度入口(crawler_main.py) # coding: ...

  6. Codeforces_499C:Crazy Town(计算几何)

    题目链接 给出点A(x1,y1),B(x2,y2),和n条直线(ai,bi,ci,aix + biy + ci = 0),求A到B穿过多少条直线 枚举每条直线判断A.B是否在该直线两侧即可 #incl ...

  7. 漫谈格兰杰因果关系(Granger Causality)——第一章 野火烧不尽,春风吹又生

    2017年7月9日上午6点10分,先师胡三清同志--新因果关系的提出者.植入式脑部电极癫痫治疗法的提出者.IEEE高级会员,因肺癌医治无效于杭州肿瘤医院去世,享年50岁.余蒙先师厚恩数载,一朝忽闻先师 ...

  8. 关于Class.forName(className).newInstance()介绍

    Class.forName(xxx.xx.xx) 返回的是一个类 首先你要明白在java里面任何class都要装载在虚拟机上才能运行.这句话就是装载类用的(和new 不一样,要分清楚). 至于什么时候 ...

  9. 电脑装windows与Centos双系统时引导问题

    (本文对电脑如何装windows系统和centos系统不进行详细赘述.) 电脑装双系统时,首先要安装windows系统,在硬盘中划分一块空闲的分区,用来安装centos系统(可以借助"软碟通 ...

  10. .net 自动分类算法【原创】

    目前自动分类算法是参考网上的思路和想法个人自主研发的. 当然互联网上有很多人采用不同的方式去解决自动分类问题,也有不同的算法和论文支持去做,但纵观自动分类这块工作是属于机器学习这块工作内容,总结出来比 ...