上一篇博文中,我们使用结巴分词对文档进行分词处理,但分词所得结果并不是每个词语都是有意义的(即该词对文档的内容贡献少),那么如何来判断词语对文档的重要度呢,这里介绍一种方法:TF-IDF。

  一,TF-IDF介绍

  TF-IDF(Term Frequency–Inverse Document Frequency)是一种用于资讯检索与文本挖掘的常用加权技术。TF-IDF是一种统计方法,用以评估一个字词对于一个文件集或一个语料库中的其中一份文件的重要程度。字词的重要性随着它在文件中出现的次数成正比增加,但同时会随着它在语料库中出现的频率成反比下降。TF-IDF加权的各种形式常被搜索引擎应用,作为文件与用户查询之间相关程度的度量或评级。

  TF-IDF的主要思想是:如果某个词或短语在一篇文章中出现的频率TF高,并且在其他文章中很少出现,则认为此词或者短语具有很好的类别区分能力,适合用来分类。TF-IDF实际上是:TF * IDF。

  (1)词频(Term Frequency,TF)指的是某一个给定的词语在该文件中出现的频率。即词w在文档d中出现的次数count(w, d)和文档d中总词数size(d)的比值。

  1. tf(w,d) = count(w, d) / size(d)

  这个数字是对词数(term count)的归一化,以防止它偏向长的文件。(同一个词语在长文件里可能会比短文件有更高的词数,而不管该词语重要与否。)

  (2)逆向文件频率(Inverse Document Frequency,IDF)是一个词语普遍重要性的度量。某一特定词语的IDF,可以由总文件数目除以包含该词语之文件的数目,再将得到的商取对数得到。即文档总数n与词w所出现文件数docs(w, D)比值的对数。  

  1. idf = log(n / docs(w, D))

  TF-IDF根据 tf 和 idf 为每一个文档d和由关键词w[1]...w[k]组成的查询串q计算一个权值,用于表示查询串q与文档d的匹配度:

  1. tf-idf(q, d)
  2. = sum { i = 1..k | tf-idf(w[i], d) }
  3. = sum { i = 1..k | tf(w[i], d) * idf(w[i]) }

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

  关于TF-IDF的详细介绍和例子,有兴趣的同学可以看这一篇博客。  下面主要分享TF-IDF在Python的如何使用。

  二,Python中计算TF-IDF

  在Python中,scikit-learn包下有计算TF-IDF的api,其效果也很不错。首先得安装Scikit-clearn。不同系统安装请看:http://scikit-learn.org/stable/install.html。

  本机环境:linux(ubuntu) 64位,python2.7.6

  1. 安装scikit-learn包(先安装依赖包,再安装sklearn)

  1. sudo apt-get install build-essential python-dev python-setuptools \
  2. python-numpy python-scipy \
  3. libatlas-dev libatlas3gf-base
  1. sudo apt-get install python-sklearn

  或者通过pip进行安装,pip是一个给python用的挺不错的安装工具。

  1. sudo apt-get install python-pip
    sudo pip install -U scikit-learn

  检验是否安装成功,在terminal里面输入

  1. pip list

  会列出pip安装的所有东西,如果里面有sklearn这一项,则安装成功。

  2. 安装jieba分词包

  由于计算TF-IDF是对分词结果进行计算,所以这里需要使用jieba中文分词。有关结巴分词的使用,可以看上一篇博文:Python 结巴分词

  1. sudo pip install jieba

  3. 计算TF-IDF

  scikit-learn包进行TF-IDF分词权重计算主要用到了两个类:CountVectorizer和TfidfTransformer。其中

  CountVectorizer是通过fit_transform函数将文本中的词语转换为词频矩阵,矩阵元素a[i][j] 表示j词在第i个文本下的词频。即各个词语出现的次数,通过get_feature_names()可看到所有文本的关键字,通过toarray()可看到词频矩阵的结果。简例如下:

  1. >>> from sklearn.feature_extraction.text import CountVectorizer
    >>> vectorizer = CountVectorizer()
  2. >>> corpus = [
  3. ... 'This is the first document.',
  4. ... 'This is the second second document.',
  5. ... 'And the third one.',
  6. ... 'Is this the first document?',
  7. ... ]
  8. >>> X = vectorizer.fit_transform(corpus)
  9. >>> X.toarray()
  10. array([[0, 1, 1, 1, 0, 0, 1, 0, 1],
  11. [0, 1, 0, 1, 0, 2, 1, 0, 1],
  12. [1, 0, 0, 0, 1, 0, 1, 1, 0],
  13. [0, 1, 1, 1, 0, 0, 1, 0, 1]]...)
  1. >>> vectorizer.get_feature_names()
    (['and', 'document', 'first', 'is', 'one', 'second', 'the', 'third', 'this'])

  TfidfTransformer是统计vectorizer中每个词语的tf-idf权值,用法如下:

  1. >>> from sklearn.feature_extraction.text import CountVectorizer
    >>> transformer = TfidfTransformer()
  1. >>> counts = [[3, 0, 1],
  2. ... [2, 0, 0],
  3. ... [3, 0, 0],
  4. ... [4, 0, 0],
  5. ... [3, 2, 0],
  6. ... [3, 0, 2]]
  7.  
  8. >>> tfidf = transformer.fit_transform(counts)
  1. >>> tfidf.toarray()
  2. array([[ 0.85..., 0. ..., 0.52...],
  3. [ 1. ..., 0. ..., 0. ...],
  4. [ 1. ..., 0. ..., 0. ...],
  5. [ 1. ..., 0. ..., 0. ...],
  6. [ 0.55..., 0.83..., 0. ...],
  7. [ 0.63..., 0. ..., 0.77...]])

  关于函数的具体说明,请看官方说明文档:scikit-learn common-vectorizer-usage

  这里我处理的是对100份文档进行分词,然后进行TF-IDF的计算,其效果相当好。

  1. import os
  2. import jieba
  3. import jieba.posseg as pseg
  4. import sys
  5. import string
  6. from sklearn import feature_extraction
  7. from sklearn.feature_extraction.text import TfidfTransformer
  8. from sklearn.feature_extraction.text import CountVectorizer
  9. reload(sys)
  10. sys.setdefaultencoding('utf8')
  11. #获取文件列表(该目录下放着100份文档)
  12. def getFilelist(argv) :
  13. path = argv[1]
  14. filelist = []
  15. files = os.listdir(path)
  16. for f in files :
  17. if(f[0] == '.') :
  18. pass
  19. else :
  20. filelist.append(f)
  21. return filelist,path
  22. #对文档进行分词处理
  23. def fenci(argv,path) :
  24. #保存分词结果的目录
  25. sFilePath = './segfile'
  26. if not os.path.exists(sFilePath) :
  27. os.mkdir(sFilePath)
  28. #读取文档
  29. filename = argv
  30. f = open(path+filename,'r+')
  31. file_list = f.read()
  32. f.close()
  33.  
  34. #对文档进行分词处理,采用默认模式
  35. seg_list = jieba.cut(file_list,cut_all=True)
  36.  
  37. #对空格,换行符进行处理
  38. result = []
  39. for seg in seg_list :
  40.      seg = ''.join(seg.split())
  41. if (seg != '' and seg != "\n" and seg != "\n\n") :
  42. result.append(seg)
  43.  
  44. #将分词后的结果用空格隔开,保存至本地。比如"我来到北京清华大学",分词结果写入为:"我 来到 北京 清华大学"
  45. f = open(sFilePath+"/"+filename+"-seg.txt","w+")
  46. f.write(' '.join(result))
  47. f.close()
  48.  
  49. #读取100份已分词好的文档,进行TF-IDF计算
  50. def Tfidf(filelist) :
  51.   path = './segfile/'
  52. corpus = [] #存取100份文档的分词结果
  53. for ff in filelist :
  54. fname = path + ff
  55. f = open(fname,'r+')
  56. content = f.read()
  57. f.close()
  58. corpus.append(content)
  59.  
  60. vectorizer = CountVectorizer()
  61. transformer = TfidfTransformer()
  62. tfidf = transformer.fit_transform(vectorizer.fit_transform(corpus))
  63.  
  64. word = vectorizer.get_feature_names() #所有文本的关键字
  65. weight = tfidf.toarray() #对应的tfidf矩阵
  66.  
  67. sFilePath = './tfidffile'
  68. if not os.path.exists(sFilePath) :
  69. os.mkdir(sFilePath)
  70.  
  71. # 这里将每份文档词语的TF-IDF写入tfidffile文件夹中保存
  72. for i in range(len(weight)) :
         print u"--------Writing all the tf-idf in the",i,u" file into ",sFilePath+'/'+string.zfill(i,5)+'.txt',"--------"
  73. f = open(sFilePath+'/'+string.zfill(i,5)+'.txt','w+')
  74. for j in range(len(word)) :
  75. f.write(word[j]+" "+str(weight[i][j])+"\n")
  76. f.close()
  77.  
  78. if __name__ == "__main__" :
  79. (allfile,path) = getFilelist(sys.argv)
  80.   for ff in allfile :
  81. print "Using jieba on "+ff
  82. fenci(ff,path)
  83.  
  84. Tfidf(allfile)

参考资料:

  1.维基百科:http://zh.wikipedia.org/wiki/TF-IDF

  2.TF-IDF模型的概率解释:http://www.cnblogs.com/weidagang2046/archive/2012/10/22/tf-idf-from-probabilistic-view.html#top

  3.liuxuejiang158的专栏:http://blog.csdn.net/liuxuejiang158blog/article/details/31360765

  4.Scikit-learn:http://scikit-learn.org/stable/modules/feature_extraction.html#common-vectorizer-usage

Python TF-IDF计算100份文档关键词权重的更多相关文章

  1. Atitit 计算word ppt文档的页数

    Atitit 计算word ppt文档的页数 http://localhost:8888/ http://git.oschina.net/attilax/ati_wordutil private vo ...

  2. DedeCms文档关键词替换,优先替换长尾关键词

    本文教大家:dedecms文档关键词维护之关键词出现多次,只给出现的第一个加链接的 举例:当文章中出现了一百次台历时,按官方的原理,他会给一百个台历都加上链接的.dedecms这如何是好? 解决方法( ...

  3. dedecms批量删除文档关键词可以吗

    这几天在重新整服务器,几个站点都是用dedecms搭建的,版本相对比较早,虽然都已经打了补丁,但客户还是在纠结,所以就下载了新的系统进行搭建(注意编码要和原来的一样),导入数据,一切安好,可发现后台有 ...

  4. 根据网站所做的SEO优化整理的一份文档

    今日给合作公司讲解本公司网站SEO优化整理的一份简单文档 架构 ########################################## 1.尽量避免Javascript和flash导航. ...

  5. python 使用win32com实现对word文档批量替换页眉页脚

    最近由于工作需要,需要将70个word文件的页眉页脚全部进行修改,在想到这个无聊/重复/没有任何技术含量的工作时,我的内心是相当奔溃的.就在我接近奔溃的时候我突然想到完全可以用python脚本来实现这 ...

  6. 用python批量生成简单的xml文档

    最近生成训练数据时,给一批无效的背景图片生成对应的xml文档,我用python写了一个简单的批量生成xml文档的demo,遇见了意外的小问题,记录一下. 报错问题为:ImportError: No m ...

  7. 使用sphinx自动提取python中的注释成为接口文档

    写好了代码,交付给他人使用的时候,查看代码固然可以了解各类和函数的功能细节,但接口文档能更方便的查找和说明功能.所以,一价与代码同步的接口文档是很有必要的.sphinx可以根据python中的注释,自 ...

  8. python开发_xml.dom_解析XML文档_完整版_博主推荐

    在阅读之前,你需要了解一些xml.dom的一些理论知识,在这里你可以对xml.dom有一定的了解,如果你阅读完之后. 下面是我做的demo 运行效果: 解析的XML文件位置:c:\\test\\hon ...

  9. Linux进阶文档丨阿里架构师十年Linux心得,全在这份文档里面

    Linux是什么 Linux就是个操作系统: 它和Windows XP.Windows 7.Windows 10什么的一样就是一个操作系统而已! Linux能干什么: 它能当服务器,服务器上安装者各种 ...

随机推荐

  1. discuz判断用户登录

        在include/common.inc.php 文件.程序开始先判断是否有cookie存到了sid值,然后解密cookie['auth']这个用户登录状态加密字符串,如果解密出来有uid值表示 ...

  2. 用户列表-投资记录sql

    --普通标.定向标.新手标.老互融计划-投资记录表select bid.borrow_id, (select yyb.borrow_valid_time from YYD_Borrow_BorrowI ...

  3. 【同行说技术】Python程序员小白变大神必读资料汇总( 三)

    在文章<Python开发.调试.爬虫类工具大全>里面向大家总结了各种实用工具和爬虫技术,今天小编收集了5篇带有实例干货的资料,赶紧来看看吧!另外,喜欢写博客的博主可以申请加工程师博主交流群 ...

  4. Autolayout-VFL语言添加约束

    一.VFL语言简洁 VFL(Visual format language)语言是苹果为了简化手写Autolayout代码所创建的专门负责编写约束的代码.为我们简化了许多代码量. 二.使用步骤 使用步骤 ...

  5. Android ViewPager 里有子ViewPager的事件冲突

    在Android应用中有时候要用到类似网易新闻左右滑动页面且页面里又有左右滑动的图片功能,我不知道网易是怎么实现的,本人的做法是外面的BaseFragmentActivity布局就是TabViewPa ...

  6. Access 中数据库操作时提示from子句语法错误

    问题:如果在Access 中数据库操作时提示from子句语法错误原因:语句中某一单词为Access中的关键字.如:select * from user.其中user就是一关键字.解决:用中括号[]将其 ...

  7. 修改Centos SSH远程端口

    1. 在防火墙添加开放端口10000:本机防火墙和云防火墙 本机防火墙:-A INPUT -m state --state NEW -m tcp -p tcp --dport 10000 -j ACC ...

  8. 【python】list。列表

    列表 list 特点:有序,支持不同类型的元素在一个列表中,可变(使用sort方法排序,影响到的是列表自身而不是创建新的列表——这与字符串不同,所以说字符串是不可变的) 在python中列表也是对象, ...

  9. 虚拟机无法上网的问题:无法启动VMnet0等问题

    虚拟机无法上网,由于之前安装过虚拟机,后来将它卸载了,然后重新安装,最后出现了虚拟机无法上网.刚开始以为是系统的原因,于是就通过linux命令查看系统里面的网卡时是否启动,如:/etc/init.d/ ...

  10. hibernate实现增删改查的各种方法

    1>接口(主要是增删改查的接口)BaseDao.java /** * * @author fly.zhou */ public interface IBaseDao { //增加对应实体的一条记 ...