一个例子来使用sklearn中的TfidfVectorizer
TfidfVectorizer
作用
将文本进行向量化表示。
原理
这里的tf
(term frequency)是词的频数,idf
(inverse document frequency)是这个词的逆文档频率。
假设有文档集合如下:
train = ["Chinese Beijing Chinese","Chinese Chinese Shanghai","Chinese Macao","Tokyo Japan Chinese"]
其中列表中的每个元素都是一个文档,所以上面一共有4个文档。第一个文档为"Chinese Beijing Chinese"。
那么我们如何将这些文档变成向量呢?
老方法,我们先统计所有文档中的词汇量。一共有{“Chinese",“Beijing”,“Shanghai”,“Macao”,“Tokyo”,“Japan”}6个词汇。
然后我们将我们的每一个文档都用一个6维向量来表示,但是问题是每一维向量上我们应该填什么数?
第一种方法
我们可以使用one-hot编码,那么第二个文档就会被编码成(1,0,1,0,0,0),因为第一个文档只有{“Chinese”,“Shanghai”}两个词汇。
第二种方法
我们发现方法一不是0就是1,我们是否可以改进一下?使得这个向量代表更多信息?可以使用tf-idf
。
我们先看idf的公式:
以第一个文档为例(“Chinese Beijing Chinese”):
tf
的计算很简单,数就行了,tf("Chinese")=2
,tf("Beijing")=1
。可以注意到我前面的用词,是词的频数,虽然英语是frequency(频率)。idf
的计算稍微复杂一些。我们需要查看整个文档,计算idf("Chinese")
,我们先统计"Chinese”在整个文档集合中出现的次数,我们发现4个文档中都有"Chinese”,即df(d,"Chinese")=4df(d,"Chinese")=4df(d,"Chinese")=4,而ndn_dnd表示文档集的文档个数,所以nd=4n_d=4nd=4。将以上两项带入idf
公式,有idf("Chinese")=log(5/5)+1=0+1=1
。同理idf("Beijing")=log(5/2)+1=1.916290731874155
,注意这里的对数是以eee为底的。- 最后,我们使用公式tfidf(t)=tf(t)∗idf(t)tfidf(t)=tf(t)*idf(t)tfidf(t)=tf(t)∗idf(t)得到
tfidf("Chinese")=2*1=2
,tfidf("Beijing")=1*1.916290731874155=1.916290731874155
。最终得到第一个文档的向量化表示(2, 1.916290731874155, 0, 0, 0, 0 )。当然,接着我们可以规范标准化表示,即v′=v∣∣v∣∣2v'=\frac{v}{||v||_2}v′=∣∣v∣∣2v,或者叫做归一化。变成:(0.722056, 0.691834610, 0, 0, 0, )
我们使用sklearn
来进行验证
from sklearn.feature_extraction.text import TfidfVectorizer
#训练数据
train = ["Chinese Beijing Chinese","Chinese Chinese Shanghai","Chinese Macao","Tokyo Japan Chinese"]#将训练数据转化为向量。tv=TfidfVectorizer()#初始化一个空的tv。
tv_fit=tv.fit_transform(train)#用训练数据充实tv,也充实了tv_fit。
print("fit后,所有的词汇如下:")
print(tv.get_feature_names())
print("fit后,训练数据的向量化表示为:")
print(tv_fit.toarray())
结果如下:
这和我们计算的是一样的(注意这里的词汇表是按字典顺序排的,所以第一个是"Beijing",我们要对号入座)。
紧接着,充实好了tv
之后。我们如何将测试文档转化为向量表示呢?使用transform
函数
test=["Chinese Beijing shanghai"]tv_test=tv.transform(test)#测试数据不会充实或者改变tv,但这步充实了tv_test。
print("所有的词汇如下:")
print(tv.get_feature_names())
print("测试数据的向量化表示为:")
print(tv_test.toarray())
结果如下:
再次强调,测试数据是不会影响tv
的,也就是说,原来训练的时候文档集是4个文档,现在计算idf
的时候,ndn_dnd还是为4,而不是变成5个文档。类似的,idf
公式中的df(d,t)
也是查找单词t
出现在原来4篇中的多少篇文档中。
结束
最后,我们可以用得到的向量,进行分类
或者计算文档之间的相似度(比如使用余弦相似度)进行聚类
等等。
补充
TfidfVectorizer中有一些参数或许我们会用得上,比如:
(一)
stop_words
这个是停用词,停用词就是说一些无关紧要的词,比如中文中{"的“,”地“}等等。你可以提供一个停用词的库给tv
,那么tv
将在文档中自动忽略这些停用词,相当于对文档做了一个预处理,删除了这些文档中的所有停用词。
from sklearn.feature_extraction.text import TfidfVectorizer
#训练数据
train = ["Chinese Beijing Chinese","Chinese Chinese Shanghai","Chinese Macao","Tokyo Japan Chinese"]#将训练数据转化为向量。tv=TfidfVectorizer(stop_words=["chinese"])#停用词注意要用小写,因为train会被自动转成小写。
tv_fit=tv.fit_transform(train)#用训练数据充实tv,也充实了tv_fit。
print("fit后,所有的词汇如下:")
print(tv.get_feature_names())
结果:
即没有了"chinese”这个停用词,词汇量少了一个。
我们再看另外一个值(直接指定为"english")。
stop_words="english"
这表示,sklearn中内部有一个大家普遍都认同的英语停用词库,比如"the"等。注意这是sklearn内置的,中文没有。
from sklearn.feature_extraction.text import TfidfVectorizer
#训练数据
train = ["the Chinese Beijing Chinese","Chinese Chinese Shanghai","Chinese Macao","Tokyo Japan Chinese"]#将训练数据转化为向量。tv=TfidfVectorizer(stop_words="english")#初始化一个空的tv。
tv_fit=tv.fit_transform(train)#用训练数据充实tv,也充实了tv_fit。
print("fit后,所有的词汇如下:")
print(tv.get_feature_names())
我们发现"the“作为停用词被自动删除了。
(二)
ngram_range
直接给个例子就明白了。
from sklearn.feature_extraction.text import TfidfVectorizer
#训练数据
train = ["Chinese Beijing Chinese","Chinese Chinese Shanghai","Chinese Macao","Tokyo Japan Chinese"]#将训练数据转化为向量。tv=TfidfVectorizer(ngram_range=(1,2))#初始化一个空的tv。
tv_fit=tv.fit_transform(train)#用训练数据充实tv,也充实了tv_fit。
print("fit后,所有的词汇如下:")
print(tv.get_feature_names())
结果:
我们发现,比之前多了一些词汇,现在两个单词组合在一起也被认为是一个词汇了。这是自然语言处理中的2元短语。在此处,这个参数表示将1元短语(单词),2元短语都看作总词汇表中的1项。
类似的你可以随便改参数,例如:
ngram_range=(2,2)#表示只要2元短语作为词汇表项。
(三)
max_df=0.9, min_df=2#如果是整数,那么就是含有该词的绝对文档数,如果是小数,就是含有该词的文档比例。
这个df应该还记得把?就是文档频率,但是注意不是逆(倒数)的,比如在上面"Shanghai"出现在4篇文档中的1篇,那么其频率就是0.25。
这个参数的意思就是删去那些在90%以上的文档中都会出现的词,同时也删去那些没有出现在至少2篇文档中的词。
比如:
from sklearn.feature_extraction.text import TfidfVectorizer
#训练数据
train = ["Chinese Beijing Chinese","Chinese Chinese Shanghai","Chinese Macao","Tokyo Japan Chinese"]#将训练数据转化为向量。tv=TfidfVectorizer(max_df=0.9,min_df=0.25)#初始化一个空的tv。
tv_fit=tv.fit_transform(train)#用训练数据充实tv,也充实了tv_fit。
print("fit后,所有的词汇如下:")
print(tv.get_feature_names())
结果:
我们发现,这没有了"Chinese",因为其文档频率为df(d,"Chinese")=4/4=1>0.9
。相当于是停用词,被忽略了。
(四)
vocabulary=[],指明你想要捕获的单词,其实相当于指定了一个文档的向量维度。
比如:
from sklearn.feature_extraction.text import TfidfVectorizer
#训练数据
train = ["Chinese Beijing Chinese","Chinese Chinese Shanghai","Chinese Macao","Tokyo Japan Chinese"]#将训练数据转化为向量。
v=["chinese","beijing"]
tv=TfidfVectorizer(vocabulary=v)#初始化一个空的tv。
tv_fit=tv.fit_transform(train)#用训练数据充实tv,也充实了tv_fit。
print("fit后,所有的词汇如下:")
print(tv.get_feature_names())
print("fit后,训练数据的向量化表示为:")
print(tv_fit.toarray())
结果:
我们发现,就一个文档只有两个维度了,这四个文档要对这两个维度("chinese","beijing")
分别计算tf-idf
。
注意一下一个坑:默认的话所有文档会转成小写,所以你指定的vocabulary
得是小写的单词。否则如下:
from sklearn.feature_extraction.text import TfidfVectorizer
#训练数据
train = ["Chinese Beijing Chinese","Chinese Chinese Shanghai","Chinese Macao","Tokyo Japan Chinese"]#将训练数据转化为向量。
v=["Chinese","Beijing"]
tv=TfidfVectorizer(vocabulary=v)#初始化一个空的tv。
tv_fit=tv.fit_transform(train)#用训练数据充实tv,也充实了tv_fit。
print("fit后,所有的词汇如下:")
print(tv.get_feature_names())
print("fit后,训练数据的向量化表示为:")
print(tv_fit.toarray())
结果:
即所有文档都不与这个大写的维度匹配,所以计算tf-idf
的时候是0
。
(五)analyzer=“char”
这个可以将文档在字符级别转成向量,平常都是单词级别转成向量。
from sklearn.feature_extraction.text import TfidfVectorizer
#标签是字符串
a=['h',"e","l","l","oe"]
atv=TfidfVectorizer(analyzer="char")
atv_fit=atv.fit_transform(a)#下面这行代码是打印标签对应哪一列为1,这个TfidfVectorizer是按字母顺序排序的a-z。
print(atv.get_feature_names())
av=atv_fit.toarray()
av
结果如下:
一个例子来使用sklearn中的TfidfVectorizer相关推荐
- sklearn中的KMeans算法
1.聚类算法又叫做**"无监督分类"**,其目的是将数据划分成有意义或有用的组(或簇).这种划分可以基于我们的业务需求或建模需求来完成,也可以单纯地帮助我们探索数据的自然结构和分布 ...
- 8.4 自定义 Git - 使用强制策略的一个例子
使用强制策略的一个例子 在本节中,你将应用前面学到的知识建立这样一个 Git 工作流程:检查提交信息的格式,并且指定只能由特定用户修改项目中特定的子目录. 你将编写一个客户端脚本来提示开发人员他们的推 ...
- word2vec预训练词向量+通俗理解word2vec+CountVectorizer+TfidfVectorizer+tf-idf公式及sklearn中TfidfVectorizer
文章目录 文分类实(一) word2vec预训练词向量 2 数据集 3 数据预处理 4 预训练word2vec模型 canci 通俗理解word2vec 独热编码 word2vec (Continuo ...
- TF-IDF在sklearn中TfidfVectorizer的使用
TF-IDF 以下内容部分摘录于百度百科. 什么是TF-IDF? TF-IDF(term frequency–inverse document frequency)是一种用于信息检索与数据挖掘的常用加 ...
- tfidf处理代码_tf idf公式及sklearn中TfidfVectorizer
在文本挖掘预处理之向量化与Hash Trick中我们讲到在文本挖掘的预处理中,向量化之后一般都伴随着TF-IDF的处理,那么什么是TF-IDF,为什么一般我们要加这一步预处理呢?这里就对TF-IDF的 ...
- R语言使用lm构建线性回归模型、并将目标变量对数化(log10)实战:可视化模型预测输出与实际值对比图、可视化模型的残差、模型预测中系统误差的一个例子 、自定义函数计算R方指标和均方根误差RMSE
R语言使用lm构建线性回归模型.并将目标变量对数化(log10)实战:可视化模型预测输出与实际值对比图.可视化模型的残差.模型预测中系统误差的一个例子 .自定义函数计算R方指标和均方根误差RMSE 目 ...
- python中self_一个例子带你入门Python装饰器
============ 欢迎关注我的公众号:早起python ============ 前言 在还未正式发布的python3.9中,有一个新功能值得关注,那就是任意表达式可以作为装饰器,如果你还不知 ...
- C++中const——由一个例子想到的
前天同学实现了<C++ Primer>中关于虚函数的一个例子,拿过来问我,代码如下: #include<iostream> #include<string> usi ...
- 一个例子带你搞懂python作用域中的global、nonlocal和local
在编程中,只要接触过函数的,我相信都理解什么是全局变量和局部变量,概念比较简单,这里就不做解释了.在python中,用global语句就能将变量定义为全局变量,但是最近又发现有个nonlocal,一时 ...
最新文章
- SD-WAN开源优势是什么?
- mongodb 索引去重_PostgreSQL13新特性解读Btree索引去重Deduplication
- 解决Ubuntu“下载额外数据文件失败 ttf-mscorefonts-installer”的问题 (转载)
- RTS寻路相关资料收集
- java中什么泛型_【原创】java中的泛型是什么,有什么作用
- VB:如何选定文件或文件夹
- xss挖掘思路分享_XSS学习(三)挖掘思路
- java 修饰符 访问控制符_《Java基础知识》Java访问修饰符(访问控制符)
- SQL2000系統表的應用
- jdk HashMap源码解读
- Atitit 基于sql编程语言的oo面向对象大规模应用解决方案attilax总结
- 考研天勤 数据结构 图(自用回顾)
- 虚拟机上用U盘安装系统
- 推荐几款好用的网站CMS管理系统
- 【5G核心网】 NGAP 消息
- K60的FTM的PWM、输入捕获、正交解码
- 组织结构图用什么做最简单?树图网组织结构图在线制作简单又漂亮
- 深入理解iOS App的启动过程
- java 发送网易邮箱邮件
- 通达信指标公式编写常用函数(六)——SUM、IF
热门文章
- 科学世界的人文关怀:开源科学与人工智能
- Coda, 去中心化的简洁(succint)的可拓展的加密货币
- ​李明轩:提升大数据素养,辅助电力系统实时决策研究 | 提升之路系列(八)...
- 独家 | 带你认识HDFS和如何创建3个节点HDFS集群(附代码案例)
- 剑指offer: 变态跳台阶 python实现
- 比尔盖茨宣布离开微软董事会:昔日全球首富致力于改变世界
- 你发表情包全靠他,GIF压缩算法发明者之一获IEEE最高荣誉奖
- 强强联手!这所C9高校与西湖大学签约
- 网站上传到服务器mysql数据库,网站上传到服务器mysql数据库吗
- 5300亿参数的「威震天-图灵」,微软、英伟达合力造出超大语言模型