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

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

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

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

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

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

tf-idf(q, d)
= sum { i = 1..k | tf-idf(w[i], d) }
= 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)

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

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

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

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

pip list

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

  2. 安装jieba分词包

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

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()可看到词频矩阵的结果。简例如下:

>>> from sklearn.feature_extraction.text import CountVectorizer
>>> vectorizer = CountVectorizer()
>>> corpus = [
... 'This is the first document.',
... 'This is the second second document.',
... 'And the third one.',
... 'Is this the first document?',
... ]
>>> X = vectorizer.fit_transform(corpus)
>>> X.toarray()
array([[0, 1, 1, 1, 0, 0, 1, 0, 1],
[0, 1, 0, 1, 0, 2, 1, 0, 1],
[1, 0, 0, 0, 1, 0, 1, 1, 0],
[0, 1, 1, 1, 0, 0, 1, 0, 1]]...)
>>> vectorizer.get_feature_names()
(['and', 'document', 'first', 'is', 'one', 'second', 'the', 'third', 'this'])

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

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

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

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

import os
import jieba
import jieba.posseg as pseg
import sys
import string
from sklearn import feature_extraction
from sklearn.feature_extraction.text import TfidfTransformer
from sklearn.feature_extraction.text import CountVectorizer
reload(sys)
sys.setdefaultencoding('utf8')
#获取文件列表(该目录下放着100份文档)
def getFilelist(argv) :
path = argv[1]
filelist = []
files = os.listdir(path)
for f in files :
if(f[0] == '.') :
pass
else :
filelist.append(f)
return filelist,path
#对文档进行分词处理
def fenci(argv,path) :
#保存分词结果的目录
sFilePath = './segfile'
if not os.path.exists(sFilePath) :
os.mkdir(sFilePath)
#读取文档
filename = argv
f = open(path+filename,'r+')
file_list = f.read()
f.close() #对文档进行分词处理,采用默认模式
seg_list = jieba.cut(file_list,cut_all=True) #对空格,换行符进行处理
result = []
for seg in seg_list :
     seg = ''.join(seg.split())
if (seg != '' and seg != "\n" and seg != "\n\n") :
result.append(seg) #将分词后的结果用空格隔开,保存至本地。比如"我来到北京清华大学",分词结果写入为:"我 来到 北京 清华大学"
f = open(sFilePath+"/"+filename+"-seg.txt","w+")
f.write(' '.join(result))
f.close() #读取100份已分词好的文档,进行TF-IDF计算
def Tfidf(filelist) :
  path = './segfile/'
corpus = [] #存取100份文档的分词结果
for ff in filelist :
fname = path + ff
f = open(fname,'r+')
content = f.read()
f.close()
corpus.append(content) vectorizer = CountVectorizer()
transformer = TfidfTransformer()
tfidf = transformer.fit_transform(vectorizer.fit_transform(corpus)) word = vectorizer.get_feature_names() #所有文本的关键字
weight = tfidf.toarray() #对应的tfidf矩阵 sFilePath = './tfidffile'
if not os.path.exists(sFilePath) :
os.mkdir(sFilePath) # 这里将每份文档词语的TF-IDF写入tfidffile文件夹中保存
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',"--------"
f = open(sFilePath+'/'+string.zfill(i,5)+'.txt','w+')
for j in range(len(word)) :
f.write(word[j]+" "+str(weight[i][j])+"\n")
f.close() if __name__ == "__main__" :
(allfile,path) = getFilelist(sys.argv)
  for ff in allfile :
print "Using jieba on "+ff
fenci(ff,path) 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. php连接ftp的研究,自带ftp函数 | fsockopen | curl实现ftp的连接

    持续更新中..............

  2. Android第三方开源对话消息提示框:SweetAlertDialog(sweet-alert-dialog)

    Android第三方开源对话消息提示框:SweetAlertDialog(sweet-alert-dialog) Android第三方开源对话消息提示框:SweetAlertDialog(sweet- ...

  3. nginx 配置优化的几个参数

    nginx 配置优化的几个参数 2011-04-22 本文地址: http://blog.phpbean.com/a.cn/7/ --水平有限欢迎指正-- -- 最近在服务器上搞了一些nginx 研究 ...

  4. C++-const_cast, reinterpret_cast, static_cast的用法

    /////////////////////////////////////////////////////////////////////////////// // // FileName : cas ...

  5. SharePoint开发 - 自定义导航菜单(二)母版页的菜单应用

    博客地址 http://blog.csdn.net/foxdave 接上篇点击打开链接 本篇叙述在母版页中应用之前的配置信息生成菜单,主要涉及到母版页的自定义,并应用了第三方控件库DevExpress ...

  6. SWPFILE实现(增加swap空间)

    1.mkdir /var/swap chmod  700  /var/swap(可以不用设置) 2.dd if=/dev/zero of=/var/swap/file bs=1024 count=65 ...

  7. MapReduce实现TopK的示例

    由于开始学习MapReduce编程已经有一段时间了,作为一个从编程中寻找自信和乐趣以及热爱编程的孩子来讲,手开始变得很“痒”了,很想小试一下身手.于是自己编写了TopK的代码.TopK的意思就是从原文 ...

  8. 04-树5 Complete Binary Search Tree

    这题也是第二次做,本想第一次做时参考的算法会和老师讲的一样,不想老师讲的算法用在这题感觉还不如思雪园友的算法(http://www.cnblogs.com/sixue/archive/2015/04. ...

  9. 找不到库文件地址,修改修改方法framework

    直接双击地址行修改

  10. ISO c++11 does not allow conversion from string literal to 'char*'

    http://stackoverflow.com/questions/9650058/deprecated-conversion-from-string-literal-to-char