TF-IDF

TF-IDF概述

TF-IDF是Term Frequency -  Inverse Document Frequency的缩写,即“词频-逆文本频率”。它由两部分组成,TF和IDF。

前面的TF也就是我们前面说到的词频,我们之前做的向量化也就是做了文本中各个词的出现频率统计,并作为文本特征,这个很好理解。关键是后面的这个IDF,即“逆文本频率”如何理解。在上一节中,我们讲到几乎所有文本都会出现的"to"其词频虽然高,但是重要性却应该比词频低的"China"和“Travel”要低。我们的IDF就是来帮助我们来反应这个词的重要性的,进而修正仅仅用词频表示的词特征值。

概括来讲, IDF反应了一个词在所有文本中出现的频率,如果一个词在很多的文本中出现,那么它的IDF值应该低,比如上文中的“to”。而反过来如果一个词在比较少的文本中出现,那么它的IDF值应该高。比如一些专业的名词如“Machine Learning”。这样的词IDF值应该高。一个极端的情况,如果一个词在所有的文本中都出现,那么它的IDF值应该为0。

上面是从定性上说明的IDF的作用,那么如何对一个词的IDF进行定量分析呢?这里直接给出一个词

的IDF的基本公式如下:

其中,N代表语料库中文本的总数,而N(x)代表语料库中包含词x的文本总数。为什么IDF的基本公式应该是是上面这样的而不是像N/N(x)这样的形式呢?这就涉及到信息论相关的一些知识了。感兴趣的朋友建议阅读吴军博士的《数学之美》第11章。

上面的IDF公式已经可以使用了,但是在一些特殊的情况会有一些小问题,比如某一个生僻词在语料库中没有,这样我们的分母为0, IDF没有意义了。所以常用的IDF我们需要做一些平滑,使语料库中没有出现的词也可以得到一个合适的IDF值。平滑的方法有很多种,最常见的IDF平滑后的公式之一为:


在scikit-learn中,有两种方法进行TF-IDF的预处理。
第一种方法是在用CountVectorizer类向量化之后再调用TfidfTransformer类进行预处理。第二种方法是直接用TfidfVectorizer完成向量化与TF-IDF预处理。
首先我们来看第一种方法,CountVectorizer+TfidfTransformer的组合,代码如下:


 
 
  1. from sklearn.feature_extraction.text import TfidfTransformer
  2. from sklearn.feature_extraction.text import CountVectorizer
  3. corpus=[ "I come to China to travel",
  4. "This is a car polupar in China",
  5. "I love tea and Apple ",
  6. "The work is to write some papers in science"]
  7. vectorizer=CountVectorizer()
  8. transformer = TfidfTransformer()
  9. tfidf = transformer.fit_transform(vectorizer.fit_transform(corpus))
  10. print tfidf
现在我们用TfidfVectorizer一步到位,代码如下:

 
 
  1. from sklearn.feature_extraction.text import TfidfVectorizer
  2. tfidf2 = TfidfVectorizer()
  3. re = tfidf2.fit_transform(corpus)
  4. print re
输出的各个文本各个词的TF-IDF值和第一种的输出完全相同。大家可以自己去验证一下。
由于第二种方法比较的简洁,因此在实际应用中推荐使用,一步到位完成向量化,TF-IDF与标准化。

完整例子:
1 安装scikit-learn包
pip install scikit-learn  
 
 
2 中文分词采用的jieba分词,安装jieba分词包
pip install jieba  
 
 
3  关于jieba分词的使用非常简单,参考这里,关键的语句就是(这里简单试水,不追求效果4 )

 
 
  1. import jieba.posseg as pseg
  2. words=pseg.cut( "对这句话进行分词")
  3. for key in words:
  4. print key.word,key.flag
输出结果:
对 p
这 r
句 q
话 n
进行 v
分词 n

4 采用scikit-learn包进行tf-idf分词权重计算关键用到了两个类:CountVectorizer和TfidfTransformer,具体参见这里
一个简单的代码如下:

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

-------这里输出第 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
网易 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.0
网易 0.525472749264
-------这里输出第 2 类文本的词语tf-idf权重------           #该类对应的原文本是: "小明硕士毕业于中国科学院“
中国 0.4472135955
北京 0.0
大厦 0.0
天安门 0.0
小明 0.4472135955
来到 0.0
杭研 0.0
毕业 0.4472135955
清华大学 0.0
硕士 0.4472135955
科学院 0.4472135955
网易 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
网易 0.0

TF-IDF小结
TF-IDF是非常常用的文本挖掘预处理基本步骤,但是如果预处理中使用了Hash Trick,则一般就无法使用TF-IDF了,因为Hash Trick后我们已经无法得到哈希后的各特征的IDF的值。使用了IF-IDF并标准化以后,我们就可以使用各个文本的词特征向量作为文本的特征,进行分类或者聚类分析。
当然TF-IDF不光可以用于文本挖掘,在信息检索等很多领域都有使用。因此值得好好的理解这个方法的思想。

参考:

http://www.cnblogs.com/pinard/p/6693230.html

http://blog.csdn.net/liuxuejiang158blog/article/details/31360765

http://www.ruanyifeng.com/blog/2013/03/tf-idf.html

http://blog.csdn.net/eastmount/article/details/50323063

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值