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实现)。
# coding:utf-8
import jieba
import jieba.posseg as pseg
import os
import sys
from sklearn import feature_extraction
from sklearn.feature_extraction.text import TfidfTransformer
from sklearn.feature_extraction.text import CountVectorizer if __name__ == "__main__":
corpus=["我 来到 北京 清华大学",#第一类文本切词后的结果,词之间以空格隔开
"他 来到 了 网易 杭研 大厦",#第二类文本的切词结果
"小明 硕士 毕业 与 中国 科学院",#第三类文本的切词结果
"我 爱 北京 天安门"]#第四类文本的切词结果
vectorizer=CountVectorizer()
#该类会将文本中的词语转换为词频矩阵,矩阵元素a[i][j],表示j词在i类文本下的词频
transformer=TfidfTransformer()
#该类会统计每个词语的tf-idf权值
tfidf=transformer.fit_transform(vectorizer.fit_transform(corpus))
#第一个fit_transform是计算tf-idf,第二个fit_transform是将文本转为词频矩阵
word=vectorizer.get_feature_names()
#获取词袋模型中的所有词语
weight=tfidf.toarray()
#将tf-idf矩阵抽取出来,元素a[i][j]表示j词在i类文本中的tf-idf权重
for i in range(len(weight)):
#打印每类文本的tf-idf词语权重,第一个for遍历所有文本,第二个for便利某一类文本下的词语权重
print u"-------这里输出第",i,u"类文本的词语tf-idf权重------"
for j in range(len(word)):
print word[j],weight[i][j]
若有多个文档统计TF-IDF权重时,则会出现一些计算结果不等值的问题。现取4个小样本txt数据做测试分析,每个txt中取单个句子,句子先做分词,再调用sklearn库做计算。测试案例代码实现如下图1,分词结果和计算结果展示如下图2:
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') def savefile(savepath, content):
fp = open(savepath, 'wb')
fp.write(content)
fp.close() def readfile(path):
fp = open(path, 'rb')
content = fp.read()
fp.close()
return content if __name__ == "__main__":
start_path = "segfile/"
end_path = "resultfile/"
corpus = []
tfidfdict = {}
for file_path in os.listdir(start_path):
fullname = start_path + file_path
content = readfile(fullname).strip()
#content = content.decode('gbk','ignore').encode('utf-8')
content = content.replace("\r\n", "")
content = content.decode('utf-8')
content_seg = jieba.cut(content.strip())
savefile(end_path + file_path, " ".join(content_seg))
for file_path in os.listdir(end_path):
fullname = end_path + file_path
content = readfile(fullname).strip()
content = content.decode('utf-8')
content = content.replace("\r\n", "").strip()
corpus.append(content)
#print corpus
for i in range(len(corpus)):
print str(corpus[i])
print "--------"
vectorizer = CountVectorizer()
transformer = TfidfTransformer()
tfidf = transformer.fit_transform(vectorizer.fit_transform(corpus))
word = vectorizer.get_feature_names()
weight = tfidf.toarray()
#print(weight)
for i in range(len(weight)):
print u"-------这里输出第", i, u"类文本的词语tf-idf权重------"
for j in range(len(word)):
print word[j], weight[i][j]
我 来到 北京 清华大学 。
他 来到 了 网易 杭研 大厦
小明 硕士 毕业 于 中国科学院
我 爱 北京 天安门
--------
-------这里输出第 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
-------这里输出第 1 类文本的词语tf-idf权重------
中国科学院 0.0
北京 0.0
大厦 0.525472749264
天安门 0.0
小明 0.0
来到 0.414288751166
杭研 0.525472749264
毕业 0.0
清华大学 0.0
硕士 0.0
网易 0.525472749264
-------这里输出第 2 类文本的词语tf-idf权重------
中国科学院 0.5
北京 0.0
大厦 0.0
天安门 0.0
小明 0.5
来到 0.0
杭研 0.0
毕业 0.5
清华大学 0.0
硕士 0.5
网易 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
这时我们会发现问题,如果用传统的TF-IDF与余弦相似性的应用(一):自动提取关键词 中计算方法,笔算之后结果和程序结果完全不同,相差很大,在确定自己笔算无误后,debug调试研究计算的中间过程,我们发现计算过程中加入了tfidf平滑处理:
if self.use_idf:
n_samples, n_features = X.shape
df = _document_frequency(X) # perform idf smoothing if required 平滑处理
df += int(self.smooth_idf) #df+1 1处
n_samples += int(self.smooth_idf) #n_samples+1 2处
# log+1 instead of log makes sure terms with zero idf don't get
# suppressed entirely.
idf = np.log(float(n_samples) / df) + 1.0 #idf+1 3处
self._idf_diag = sp.spdiags(idf, diags=0, m=n_features,
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:文本特征抽取与向量化)
TF-IDF学习笔记的更多相关文章
- 文本分类学习(三) 特征权重(TF/IDF)和特征提取
上一篇中,主要说的就是词袋模型.回顾一下,在进行文本分类之前,我们需要把待分类文本先用词袋模型进行文本表示.首先是将训练集中的所有单词经过去停用词之后组合成一个词袋,或者叫做字典,实际上一个维度很大的 ...
- Elasticsearch学习之相关度评分TF&IDF
relevance score算法,简单来说,就是计算出,一个索引中的文本,与搜索文本,他们之间的关联匹配程度 Elasticsearch使用的是 term frequency/inverse doc ...
- Oracle学习笔记三 SQL命令
SQL简介 SQL 支持下列类别的命令: 1.数据定义语言(DDL) 2.数据操纵语言(DML) 3.事务控制语言(TCL) 4.数据控制语言(DCL)
- Vue.js学习笔记(2)vue-router
vue中vue-router的使用:
- Tensorflow学习笔记2:About Session, Graph, Operation and Tensor
简介 上一篇笔记:Tensorflow学习笔记1:Get Started 我们谈到Tensorflow是基于图(Graph)的计算系统.而图的节点则是由操作(Operation)来构成的,而图的各个节 ...
- Android学习笔记(二)——探究一个活动
//此系列博文是<第一行Android代码>的学习笔记,如有错漏,欢迎指正! 活动(Activity)是最容易吸引到用户的地方了,它是一种可以包含用户界面的组件,主要用于和用户进行交互.一 ...
- EasyARM i.mx28学习笔记——开箱试用总结
0 前言 本月初(2014年8月)购买了周立功的EasyARM开发板,主控为EasyARM i.mx287.出于下面几个理由购买了该开发板. [1]主要原因,有人约我一起学习一起使用该 ...
- CSS学习笔记——盒模型,块级元素和行内元素的区别和特性
今天本来打算根据自己的计划进行前端自动化的学习的,无奈早上接到一个任务需求需要新增一个页面.自从因为工作需要转前端之后,自己的主要注意力几 乎都放在JavaScript上面了,对CSS和HTML这方面 ...
- tf–idf算法解释及其python代码实现(下)
tf–idf算法python代码实现 这是我写的一个tf-idf的简单实现的代码,我们知道tfidf=tf*idf,所以可以分别计算tf和idf值在相乘,首先我们创建一个简单的语料库,作为例子,只有四 ...
- ESP32学习笔记(一) 环境搭建与下载
ESP32学习笔记(一) 环境搭建与下载 作者:Nevel 博客:nevel.cnblogs.com 转载请保留出处 前几天刚入手了ESP32模块,趁着放假有时间,我们先把ESP32的编译环境搭建好 ...
随机推荐
- python3与python2的编码问题
在讲这个问题之前,我们先说说unicode的工作原理.unicode包含了跟全球所有国家编码的映射关系,就是不管你用哪个国家的编码,unicode都能找到它在unicode中的编码.那么无论你用什么编 ...
- FIFO buffer 和普通buffer区别
1.FIFO可以说一块具体的硬件存储设备,也可以说程序在内存中开辟的一段内存区域.而buffer往往就是一段缓冲的数据区域 2.FIFO的数据是先进先出的,而buffer没有这个限制,可以全局访问 3 ...
- NXP低功耗蓝牙集成芯片QN9080C的时钟配置
/*************************************************************************************************** ...
- react技术栈实践(1)
本文来自网易云社区 作者:汪洋 背景 最近开发一个全新AB测试平台,思考了下正好可以使用react技术开发. 实践前技术准备 首先遇到一个概念,redux.这货还真不好理解,大体的理解:Store包含 ...
- Selenium WebDriver-通过页面标题切换窗口
selenium webdriver可以通过获取页面标题,再跟据标题去切换浏览器窗口,代码如下: #encoding=utf-8 import unittest import time import ...
- javascript是脚本语言?javascript万物皆对象?
呵呵哒!带你见识下js面对对象的魅力 是的是的,退后,朕要开始装逼了- 这是什么鸟东西?是的是的,装逼开始,2016年度最佳JS编译器,ES6标准出来后,小伙伴们对新特性摩拳擦掌,奈何浏览器支持把我们 ...
- [python IO学习篇] 补充.py文件是中文, .ini文件内容是中文
python 代码文件的编码.py文件默认是ASCII编码,中文在显示时会做一个ASCII到系统默认编码的转换,这时就会出错:SyntaxError: Non-ASCII character.需要在代 ...
- RabbitMQ的应用场景以及基本原理介绍(转)
1.背景 RabbitMQ是一个由erlang开发的AMQP(Advanved Message Queue)的开源实现. 2.应用场景 2.1异步处理 场景说明:用户注册后,需要发注册邮件和注册短信, ...
- restful的nginx配置方法
location /{ root /webserver/www/a.tk.com; index index.html index.htm index.php; if ( $document_uri ~ ...
- bzoj 2819 Nim dfn序+树状数组维护区间异或值
题目大意 著名游戏设计师vfleaking,最近迷上了Nim.普通的Nim游戏为:两个人进行游戏,N堆石子,每回合可以取其中某一堆的任意多个,可以取完,但不可以不取.谁不能取谁输.这个游戏是有必胜策略 ...