Python TF-IDF计算100份文档关键词权重

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

时间: 2024-10-05 23:08:03

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

使用sklearn进行中文文本的tf idf计算

Created by yinhongyu at 2018-4-28 email: [email protected] 使用jieba和sklearn实现了tf idf的计算 import jieba import jieba.posseg as pseg from sklearn import feature_extraction from sklearn.feature_extraction.text import TfidfTransformer from sklearn.feature_e

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

今日给合作公司讲解本公司网站SEO优化整理的一份简单文档 架构 ########################################## 1.尽量避免Javascript和flash导航. 虽然JS和FLASH能把网站做的绚丽漂亮,但目前搜索引擎还是无法顺利的抓取其中的内容,所以我们要避免. 2.目录层次不能太深. 网站目录尽量保持在三层以内,尽可能接近根网址,比如“www.xxx.com/产品目录/产品名称”明显比“www.xxx.com/产品目录/年份/月份/产品名称”要好. 3

你看到这份文档,我就想摔鼠标!

我做了一套UI设计的页面,然后测试发回来一个文档,一些页面参数不对.然后根据文档修改到一半,我就想摔鼠标不干了! 因为这里都是和设计相差两三像素的问题.看到这份文档,我感觉我不是在编程,而是在给UI打工,这不是我想要的编程生活.不要和我说什么"不积跬步无以至千里".我想要的编程生活是"设计",是"逻辑".而现在她们让我改参数,将32改成28,将15改成18.设计是别人的.逻辑不存在!   或许这个任务安排的流程根本就是错误的.对于页面布局设计的实

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

这几天在重新整服务器,几个站点都是用dedecms搭建的,版本相对比较早,虽然都已经打了补丁,但客户还是在纠结,所以就下载了新的系统进行搭建(注意编码要和原来的一样),导入数据,一切安好,可发现后台有很多的文档关键词都是不相关的,以其这样不如直接删除,问题来了,几百条数据,一页页删到什么时候,怎么批量删除呢? DELETE FROM dede_keywords 一行代码轻松搞定. 如果想批量删除搜索关键词呢?也是可以实现的 Delete from dede_search_cache; Delet

python中os模块中文帮助文档

这个模块提供了一个轻便的方法使用要依赖操作系统的功能. 如何你只是想读或写文件,请使用open() ,如果你想操作文件路径,请使用os.path模块,如果你想在命令行中,读入所有文件的所有行,请使用 fileinput模块.使用tempfile模块创建临时文件和文件夹,更高级的文件和文件夹处理,请使用shutil模块. os.error 内建OSError exception的别名. os.name 导入依赖操作系统模块的名字.下面是目前被注册的名字:'posix', 'nt', 'mac',

Python学习笔记__8.4章 文档测试

# 这是学习廖雪峰老师python教程的学习笔记 1.概览 在文档中编写规范的注释代码.则Python内置的"文档测试"(doctest)模块可以直接提取注释中的代码并执行测试. 1.1.以abs()函数为例: #abs.py def abs(n): ''' # 两个为一对,换行输入 Function to get absolute value of number.  # 简单的介绍 Example: >>> abs(1)   # 测试 1 >>>

python读取文件下的所有文档

两类文档存储在两个路径下,假设每类文档有25个文档 def spamTest(): docList = [] classList = [] fullText = [] for i in range(1,26):#循环读取所有的txt,并解析成列表 wordlist = textParse(open('路径.txt' % i).read()) docList.append(wordlist) fullText.extend(wordlist) classList.append(1)#文档类别 wo

使用Lucene实现多个文档关键词检索demo(一)

在进行demo前先到http://www.ibm.com/developerworks/cn/java/j-lo-lucene1/了解关于lucene的一些基本概念,忽略其中的代码实例,因为年代久远,而我的这篇文档正是补充其中代码部分. 了解了基本概念后,接下来就可以开始完成demo了. 首先在http://www.apache.org/dyn/closer.cgi/lucene/java/4.10.0下载lucene包,这里我使用的是最新的4.10版,由于最新版与网上其他lucene使用dem

使用Lucene实现多个文档关键词检索demo(二)

上次在使用Lucene建立索引时使用的时自带的StandAnalyzer分词器,而这个分词器在对中文进行分词时只是机械的按字进行划分,因此使用它lucene就不能很好的对中文索引,也就不能实现对中文关键词的检索了,因此其实上次的实践只能对英文进行. 为了解决这个问题,可以使用IKAnalyzer,它是以开源项目Lucene为应用主体的,结合词典分词和文法分析算法的中文分词组件.它支持中英文等分词. 接下来就用它来改善检索功能,首先是下载IKAnalyzer开发包,我将开发包上传到了这里密钥:7j