TF-IDF学习笔记

计算文本的权重向量,有个很有效的权重方案:TF-IDF权重策略。TF-IDF含义是词频逆文档频率,指的是,如果某个词或短语在一篇文章中出现的频率高,并且在其他文章中很少出现,则认为此词或短语具有很好的分类区分能力,适合用来分类。简单的说,TF-IDF(词频-逆文档频率),它可以反映出语料库中某篇文档中某个词的重要性。目前所知应用是用来计算文档相似性(TF-IDF与余弦相似性的应用(二):找出相似文章

TF-IDF权重公式参见这篇博文:TF-IDF与余弦相似性的应用(一):自动提取关键词。由于自己实现代码,在运算时效率很低,所以本文主要讲述sklearn里面的TF-IDF方法。里面主要用到了两个函数:CountVectorizer()和TfidfTransformer()。CountVectorizer是通过fit_transform函数将文本中的词语转换为词频矩阵,矩阵元素weight[i][j] 表示j词在第i个文本下的词频,即各个词语出现的次数;通过get_feature_names()可看到所有文本的关键字,通过toarray()可看到词频矩阵的结果。TfidfTransformer也有个fit_transform函数,它的作用是计算tf-idf值。这里附上一个我初学时用于理解的小例子(python2实现)。

 1 # coding:utf-8
 2 import jieba
 3 import jieba.posseg as pseg
 4 import os
 5 import sys
 6 from sklearn import feature_extraction
 7 from sklearn.feature_extraction.text import TfidfTransformer
 8 from sklearn.feature_extraction.text import CountVectorizer
 9
10 if __name__ == "__main__":
11     corpus=["我 来到 北京 清华大学",#第一类文本切词后的结果,词之间以空格隔开
12         "他 来到 了 网易 杭研 大厦",#第二类文本的切词结果
13         "小明 硕士 毕业 与 中国 科学院",#第三类文本的切词结果
14         "我 爱 北京 天安门"]#第四类文本的切词结果
15     vectorizer=CountVectorizer()
16     #该类会将文本中的词语转换为词频矩阵,矩阵元素a[i][j],表示j词在i类文本下的词频
17     transformer=TfidfTransformer()
18     #该类会统计每个词语的tf-idf权值
19     tfidf=transformer.fit_transform(vectorizer.fit_transform(corpus))
20     #第一个fit_transform是计算tf-idf,第二个fit_transform是将文本转为词频矩阵
21     word=vectorizer.get_feature_names()
22     #获取词袋模型中的所有词语
23     weight=tfidf.toarray()
24     #将tf-idf矩阵抽取出来,元素a[i][j]表示j词在i类文本中的tf-idf权重
25     for i in range(len(weight)):
26         #打印每类文本的tf-idf词语权重,第一个for遍历所有文本,第二个for便利某一类文本下的词语权重
27         print u"-------这里输出第",i,u"类文本的词语tf-idf权重------"
28         for j in range(len(word)):
29             print word[j],weight[i][j]

  若有多个文档统计TF-IDF权重时,则会出现一些计算结果不等值的问题。现取4个小样本txt数据做测试分析,每个txt中取单个句子,句子先做分词,再调用sklearn库做计算。测试案例代码实现如下图1,分词结果和计算结果展示如下图2:

 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
10 reload(sys)
11 sys.setdefaultencoding(‘utf8‘)
12
13 def savefile(savepath, content):
14     fp = open(savepath, ‘wb‘)
15     fp.write(content)
16     fp.close()
17
18 def readfile(path):
19     fp = open(path, ‘rb‘)
20     content = fp.read()
21     fp.close()
22     return content
23
24 if __name__ == "__main__":
25     start_path = "segfile/"
26     end_path = "resultfile/"
27     corpus = []
28     tfidfdict = {}
29     for file_path in os.listdir(start_path):
30         fullname = start_path + file_path
31         content = readfile(fullname).strip()
32         #content = content.decode(‘gbk‘,‘ignore‘).encode(‘utf-8‘)
33         content = content.replace("\r\n", "")
34         content = content.decode(‘utf-8‘)
35         content_seg = jieba.cut(content.strip())
36         savefile(end_path + file_path, " ".join(content_seg))
37     for file_path in os.listdir(end_path):
38         fullname = end_path + file_path
39         content = readfile(fullname).strip()
40         content = content.decode(‘utf-8‘)
41         content = content.replace("\r\n", "").strip()
42         corpus.append(content)
43         #print corpus
44     for i in range(len(corpus)):
45         print str(corpus[i])
46     print "--------"
47     vectorizer = CountVectorizer()
48     transformer = TfidfTransformer()
49     tfidf = transformer.fit_transform(vectorizer.fit_transform(corpus))
50     word = vectorizer.get_feature_names()
51     weight = tfidf.toarray()
52     #print(weight)
53     for i in range(len(weight)):
54         print u"-------这里输出第", i, u"类文本的词语tf-idf权重------"
55         for j in range(len(word)):
56             print word[j], weight[i][j]
 1 我 来到 北京 清华大学 。
 2 他 来到 了 网易 杭研 大厦
 3 小明 硕士 毕业 于 中国科学院
 4 我 爱 北京 天安门
 5 --------
 6 -------这里输出第 0 类文本的词语tf-idf权重------
 7 中国科学院 0.0
 8 北京 0.52640543361
 9 大厦 0.0
10 天安门 0.0
11 小明 0.0
12 来到 0.52640543361
13 杭研 0.0
14 毕业 0.0
15 清华大学 0.66767854461
16 硕士 0.0
17 网易 0.0
18 -------这里输出第 1 类文本的词语tf-idf权重------
19 中国科学院 0.0
20 北京 0.0
21 大厦 0.525472749264
22 天安门 0.0
23 小明 0.0
24 来到 0.414288751166
25 杭研 0.525472749264
26 毕业 0.0
27 清华大学 0.0
28 硕士 0.0
29 网易 0.525472749264
30 -------这里输出第 2 类文本的词语tf-idf权重------
31 中国科学院 0.5
32 北京 0.0
33 大厦 0.0
34 天安门 0.0
35 小明 0.5
36 来到 0.0
37 杭研 0.0
38 毕业 0.5
39 清华大学 0.0
40 硕士 0.5
41 网易 0.0
42 -------这里输出第 3 类文本的词语tf-idf权重------
43 中国科学院 0.0
44 北京 0.61913029649
45 大厦 0.0
46 天安门 0.78528827571
47 小明 0.0
48 来到 0.0
49 杭研 0.0
50 毕业 0.0
51 清华大学 0.0
52 硕士 0.0
53 网易 0.0

  这时我们会发现问题,如果用传统的TF-IDF与余弦相似性的应用(一):自动提取关键词 中计算方法,笔算之后结果和程序结果完全不同,相差很大,在确定自己笔算无误后,debug调试研究计算的中间过程,我们发现计算过程中加入了tfidf平滑处理:

 1         if self.use_idf:
 2             n_samples, n_features = X.shape
 3             df = _document_frequency(X)
 4
 5             # perform idf smoothing if required 平滑处理
 6             df += int(self.smooth_idf)    #df+1 1处
 7             n_samples += int(self.smooth_idf)  #n_samples+1 2处
 8
 9             # log+1 instead of log makes sure terms with zero idf don‘t get
10             # suppressed entirely.
11             idf = np.log(float(n_samples) / df) + 1.0  #idf+1 3处
12             self._idf_diag = sp.spdiags(idf, diags=0, m=n_features,
13                                         n=n_features, format=‘csr‘)

  假设t表示某个词,d表示一篇文档,则词频TF(t,d)是某个词t在文档d中出现的次数,而文档DF(t,D)是包含词t的文档数目,于是公式变成了这样:

IDF(t,D)=log(|D|+1)/(DF(t,D)+1) +1

这里|D|表示语料库的文档总数,为了不让分母为了0,在此进行了加1平滑操作。

TFIDF(t,d,D)=TF(t,d)*IDF(t,D)=TF(t,d)*(log(|D|+1)/(DF(t,D)+1) +1)

  然后发现结果还是不对,除了做平滑处理以外,sklearn库还进行了归一化处理normalization,将值趋于0到1之间。什么是归一化,比如[1,2],归一化后成为[1/sqrt(5), 2/sqrt(5)]。(归一化问题未做研究,有时间再看看,跳过)

  所以得出结论,调用sklearn库最后得出的TF-IDF结果是归一化后的idf值。不同的词在不同文档中有不同的idf,又有不同的tf词频,所以这个求得的值是在单篇文档中对于单个词做的分析,那么对于整个语料来说,如何利用求得的这个tf-idf值做热词分析呢?还是不知啊。

[ 0.52640543  0.52640543  0.66767854  0.41428875  0.52547275  0.52547275
  0.52547275  0.5         0.5         0.5         0.5         0.6191303
  0.78528828]

参考博文:用python开始机器学习(5:文本特征抽取与向量化)

基于k-means和tfidf的文本聚类代码简单实现

  

时间: 2024-10-11 23:25:23

TF-IDF学习笔记的相关文章

文本分类学习(三) 特征权重(TF/IDF)和特征提取

上一篇中,主要说的就是词袋模型.回顾一下,在进行文本分类之前,我们需要把待分类文本先用词袋模型进行文本表示.首先是将训练集中的所有单词经过去停用词之后组合成一个词袋,或者叫做字典,实际上一个维度很大的向量.这样每个文本在分词之后,就可以根据我们之前得到的词袋,构造成一个向量,词袋中有多少个词,那这个向量就是多少维度的了.然后就把这些向量交给计算机去计算,而不再需要文本啦.而向量中的数字表示的是每个词所代表的权重.代表这个词对文本类型的影响程度. 在这个过程中我们需要解决两个问题:1.如何计算出适

Elasticsearch学习之相关度评分TF&IDF

relevance score算法,简单来说,就是计算出,一个索引中的文本,与搜索文本,他们之间的关联匹配程度 Elasticsearch使用的是 term frequency/inverse document frequency算法,简称为TF/IDF算法 Term frequency(TF):搜索文本中的各个词条在field文本中出现了多少次,出现次数越多,就越相关 Inverse document frequency(IDF):搜索文本中的各个词条在整个索引的所有文档中出现了多少次,出现的

Tensorflow学习笔记2:About Session, Graph, Operation and Tensor

简介 上一篇笔记:Tensorflow学习笔记1:Get Started 我们谈到Tensorflow是基于图(Graph)的计算系统.而图的节点则是由操作(Operation)来构成的,而图的各个节点之间则是由张量(Tensor)作为边来连接在一起的.所以Tensorflow的计算过程就是一个Tensor流图.Tensorflow的图则是必须在一个Session中来计算.这篇笔记来大致介绍一下Session.Graph.Operation和Tensor. Session Session提供了O

tf–idf算法解释及其python代码实现(下)

tf–idf算法python代码实现 这是我写的一个tf-idf的核心部分的代码,没有完整实现,当然剩下的事情就非常简单了,我们知道tfidf=tf*idf,所以可以分别计算tf和idf值在相乘,首先我们创建一个简单的语料库,作为例子,只有四句话,每句表示一个文档 copus=['我正在学习计算机','它正在吃饭','我的书还在你那儿','今天不上班'] 由于中文需要分词,jieba分词是python里面比较好用的分词工具,所以选用jieba分词,文末是jieba的链接.首先对文档进行分词: i

CLR_VIA_C# 学习笔记(1)

Perface 如果让你实现这个页面和一些操作的,比如点击1.2.3等就在那个input text中显示,还有删除功能,拨打我们先不要管它,只是模拟而已.要是我刚开始做的话,我会这样做: 用css.HTML布局那个界面 用javascript的事件委托监听那个按钮的父节点的点击事件 但是如果我想用面向对象的思想做呢?我是用Ext做的,所以我想说的是它帮我封装了很多.可能一些没用过Ext的人不太了解我下面贴的代码,但是我会尽量解释清楚的! Description ContactTelPanel =

线性回归学习笔记

操作系统 : CentOS7.3.1611_x64 python版本:2.7.5 sklearn版本:0.18.2 tensorflow版本 :1.2.1 线性回归是利用数理统计中回归分析, 来确定两种或两种以上变量间相互依赖的定量关系的一种统计分析方法, 运用十分广泛. 其表达形式为y = w'x+e,e为误差服从均值为0的正态分布. 根据变量个数的多少可以分为一元线性回归和多元线性回归. 回归模型中, 一元回归是最简单且稳健的, 但描述复杂系统的行为时往往乏力, 因此基于多元回归的预测技术更

cubieboard学习笔记

ubieboard学习笔记 2014-05-09  hginvent   阅 5345  转 16 转藏到我的图书馆 微信分享: 入手开发板,刷机肯定是少不了的,就像我们平时刷安卓手机一样.开发板也有很多适配的固件.比如Cubieboard3 Cubietruck就有安卓,debian,ubuntu等定制的固件. Cubieboard3 Cubietruck出厂的固件为安卓,拿到手上电,用HDMI接上电视,没有反应,后来确定是我HDMI切换器的问题.个人比较喜欢debian,去 Cubieboa

EasyARM i.mx28学习笔记——开箱试用总结

0 前言 本月初(2014年8月)购买了周立功的EasyARM开发板,主控为EasyARM i.mx287.出于下面几个理由购买了该开发板. [1]主要原因,有人约我一起学习一起使用该开发板. [2]该开发板性价比較高,到手300元以内,比2440/2410开发板稍廉价些. [3]该开发板的CAN功能是一个特色. [4]通过学习EasyARM i.mx287,比較和树莓派的开发的不同.     [建议] 假设亲爱的读者Linux的基础比較薄弱的话,请优先考虑树莓派.假设从此类ARM开发板入手,可

多项式回归学习笔记

操作系统 : CentOS7.3.1611_x64 python版本:2.7.5 sklearn版本:0.18.2 tensorflow版本 :1.2.1 多项式的定义及展现形式 多项式(Polynomial)是代数学中的基础概念,是由称为不定元的变量和称为系数的常数通过有限次加减法.乘法以及自然数幂次的乘方运算得到的代数表达式. 多项式分为一元多项式和多元多项式,其中: 不定元只有一个的多项式称为一元多项式: 不定元不止一个的多项式称为多元多项式. 本文讨论的是一元多项式相关问题. 其一般形式

EasyARM i.mx28学习笔记——开箱使试用总结

0 前言 本月初(2014年8月)购买了周立功的EasyARM开发板,主控为EasyARM i.mx287.出于以下几个理由购买了该开发板. [1]主要原因,有人约我一起学习一起使用该开发板. [2]该开发板性价比较高,到手300元以内,比2440/2410开发板稍便宜些. [3]该开发板的CAN功能是一个特色. [4]通过学习EasyARM i.mx287,比较和树莓派的开发的不同. [建议] 如果亲爱的读者Linux的基础为0的话,请优先考虑树莓派.如果从此类ARM开发板入手,可能会搞不清楚