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”):

  1. tf的计算很简单,数就行了,tf("Chinese")=2tf("Beijing")=1。可以注意到我前面的用词,是词的频数,虽然英语是frequency(频率)。
  2. 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为底的。
  3. 最后,我们使用公式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∣∣2​v​,或者叫做归一化。变成:(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相关推荐

  1. sklearn中的KMeans算法

    1.聚类算法又叫做**"无监督分类"**,其目的是将数据划分成有意义或有用的组(或簇).这种划分可以基于我们的业务需求或建模需求来完成,也可以单纯地帮助我们探索数据的自然结构和分布 ...

  2. 8.4 自定义 Git - 使用强制策略的一个例子

    使用强制策略的一个例子 在本节中,你将应用前面学到的知识建立这样一个 Git 工作流程:检查提交信息的格式,并且指定只能由特定用户修改项目中特定的子目录. 你将编写一个客户端脚本来提示开发人员他们的推 ...

  3. word2vec预训练词向量+通俗理解word2vec+CountVectorizer+TfidfVectorizer+tf-idf公式及sklearn中TfidfVectorizer

    文章目录 文分类实(一) word2vec预训练词向量 2 数据集 3 数据预处理 4 预训练word2vec模型 canci 通俗理解word2vec 独热编码 word2vec (Continuo ...

  4. TF-IDF在sklearn中TfidfVectorizer的使用

    TF-IDF 以下内容部分摘录于百度百科. 什么是TF-IDF? TF-IDF(term frequency–inverse document frequency)是一种用于信息检索与数据挖掘的常用加 ...

  5. tfidf处理代码_tf idf公式及sklearn中TfidfVectorizer

    在文本挖掘预处理之向量化与Hash Trick中我们讲到在文本挖掘的预处理中,向量化之后一般都伴随着TF-IDF的处理,那么什么是TF-IDF,为什么一般我们要加这一步预处理呢?这里就对TF-IDF的 ...

  6. R语言使用lm构建线性回归模型、并将目标变量对数化(log10)实战:可视化模型预测输出与实际值对比图、可视化模型的残差、模型预测中系统误差的一个例子 、自定义函数计算R方指标和均方根误差RMSE

    R语言使用lm构建线性回归模型.并将目标变量对数化(log10)实战:可视化模型预测输出与实际值对比图.可视化模型的残差.模型预测中系统误差的一个例子 .自定义函数计算R方指标和均方根误差RMSE 目 ...

  7. python中self_一个例子带你入门Python装饰器

    ============ 欢迎关注我的公众号:早起python ============ 前言 在还未正式发布的python3.9中,有一个新功能值得关注,那就是任意表达式可以作为装饰器,如果你还不知 ...

  8. C++中const——由一个例子想到的

    前天同学实现了<C++ Primer>中关于虚函数的一个例子,拿过来问我,代码如下: #include<iostream> #include<string> usi ...

  9. 一个例子带你搞懂python作用域中的global、nonlocal和local

    在编程中,只要接触过函数的,我相信都理解什么是全局变量和局部变量,概念比较简单,这里就不做解释了.在python中,用global语句就能将变量定义为全局变量,但是最近又发现有个nonlocal,一时 ...

最新文章

  1. SD-WAN开源优势是什么?
  2. mongodb 索引去重_PostgreSQL13新特性解读Btree索引去重Deduplication
  3. 解决Ubuntu“下载额外数据文件失败 ttf-mscorefonts-installer”的问题 (转载)
  4. RTS寻路相关资料收集
  5. java中什么泛型_【原创】java中的泛型是什么,有什么作用
  6. VB:如何选定文件或文件夹
  7. xss挖掘思路分享_XSS学习(三)挖掘思路
  8. java 修饰符 访问控制符_《Java基础知识》Java访问修饰符(访问控制符)
  9. SQL2000系統表的應用
  10. jdk HashMap源码解读
  11. Atitit 基于sql编程语言的oo面向对象大规模应用解决方案attilax总结
  12. 考研天勤 数据结构 图(自用回顾)
  13. 虚拟机上用U盘安装系统
  14. 推荐几款好用的网站CMS管理系统
  15. 【5G核心网】 NGAP 消息
  16. K60的FTM的PWM、输入捕获、正交解码
  17. 组织结构图用什么做最简单?树图网组织结构图在线制作简单又漂亮
  18. 深入理解iOS App的启动过程
  19. java 发送网易邮箱邮件
  20. 通达信指标公式编写常用函数(六)——SUM、IF

热门文章

  1. 科学世界的人文关怀:开源科学与人工智能
  2. Coda, 去中心化的简洁(succint)的可拓展的加密货币
  3. ​李明轩:提升大数据素养,辅助电力系统实时决策研究 | 提升之路系列(八)...
  4. 独家 | 带你认识HDFS和如何创建3个节点HDFS集群(附代码案例)
  5. 剑指offer: 变态跳台阶 python实现
  6. 比尔盖茨宣布离开微软董事会:昔日全球首富致力于改变世界
  7. 你发表情包全靠他,GIF压缩算法发明者之一获IEEE最高荣誉奖
  8. 强强联手!这所C9高校与西湖大学签约
  9. 网站上传到服务器mysql数据库,网站上传到服务器mysql数据库吗
  10. 5300亿参数的「威震天-图灵」,微软、英伟达合力造出超大语言模型