[toc]
1. 为什么要引入TF-IDF
通过计算文本之间的余弦相似度来衡量文本之间的相似程度有以下几个问题:
- 词频向量的维度会很大:词多,同时无用词多
- 形成稀疏矩阵,导致计算开销大:也是由于上面的问题引起的
因此,需要解决的问题包括:
- 降低词维度
- 抓住其关键信息
这个时候,引入TF-IDF来解决上述的问题,它通过计算每个词的TF-IDF值,筛选出每个文档中最关键一些词。
2. TF-IDF关键思想
作为一个文档中的关键词,我想应该同时满足如下2个特征:
- 特征1:出现次数多,存在感强;
- 特征2:作为某文档的关键词,它尽可能只在这一个文档中出现。类似“的”、“是”、“在”...这样的词,存在感强的都感知不到它的存在了,原因就是因为它——不够关键,因此,关键词要尽可能的唯一。
基于上面的想法,提出了下面的理论:
2.1 TF
TF=\frac{count_i}{count_{all}}
-
:某词在文档中出现的次数
-
:文档的总词数
2.2 IDF
IDF=log(\frac{corpus_{all}}{corpus_{in}+1})
这里,
-
:语料库的文档总数
-
:包含该词的文档数
当IDF值越大,说明在语境中包含该词的文档树越少,这个词越具有唯一性代表性,某种意义上说,它越关键。
注意:在scikit-learn的TfidfTransformer()方法中,如果声明TfidfTransformer(smooth_idf=false),那么IDF的计算就变为:
IDF=log(\frac{corpus_{all}}{corpus_{in}}+1)
3. 用TF-IDF计算文本相似度
用TF-IDF计算文本相似度的一般步骤为:
- 获取原始文本内容信息
- 转换成纯小写,按空格把文章分成独立的词组成的list
- 去除噪音符号: [""","=","\","/",":","-","(",")",",",".","\n"]等
- 去除停用词
- 提取词干,把相近的词转换为标准形式,比如把文章中的go,going,went,goes统一成go
- wordcount,统计每个词出现的次数,去掉出现次数较少的词,比如在一百篇文档中,只出现了1~2次的词,显然是没有意义的
- 训练IDF模型
- 对输入的每篇测试文章计算其tfidf向量,然后可以利用TF-IDF向量求文章之间的相似度(比如用欧拉距离,余弦相似度,Jaccard系数等方法)
这里,Jaccard 系数定义为A与B交集的大小与A与B并集的大小的比值,定义如下:
[图片上传失败...(image-cac059-1542251132067)]
4. TF-IDF实现
Scikit-Learn中TF-IDF权重计算方法主要用到两个类:CountVectorizer和TfidfTransformer。
4.1 CountVectorizer
其代码如下:
# coding:utf-8
from sklearn.feature_extraction.text import CountVectorizer
#语料
corpus = [
'This is the first document.',
'This is the second second document.',
'And the third one.',
'Is this the first document?',
]
#将文本中的词语转换为词频矩阵
vectorizer = CountVectorizer()
#计算个词语出现的次数
X = vectorizer.fit_transform(corpus)
#获取词袋中所有文本关键词
word = vectorizer.get_feature_names()
print(word)
#查看词频结果
print(X.toarray())
4.2 TfidfTransformer
TfidfTransformer用于统计vectorizer中每个词语的TF-IDF值。
其代码如下:
# coding:utf-8
from sklearn.feature_extraction.text import CountVectorizer
#语料
corpus = [
'This is the first document.',
'This is the second second document.',
'And the third one.',
'Is this the first document?',
]
#将文本中的词语转换为词频矩阵
vectorizer = CountVectorizer()
#计算个词语出现的次数
X = vectorizer.fit_transform(corpus)
#获取词袋中所有文本关键词
word = vectorizer.get_feature_names()
print word
#查看词频结果
print X.toarray()
from sklearn.feature_extraction.text import TfidfTransformer
#类调用
transformer = TfidfTransformer()
print transformer
#将词频矩阵X统计成TF-IDF值
tfidf = transformer.fit_transform(X)
#查看数据结构 tfidf[i][j]表示i类文本中的tf-idf权重
print tfidf.toarray()
4.3 NLTK实现TF-IDF
import nltk
from nltk.corpus import brown
def main():
'''
1.使用nltk自带的数据集
'''
text=brown.words(categories='news')#转化为Text对象
docs=[text[0:100],text[100:200],text[200:300]]#需要多个文档
#2.使用自己的数据的时候转化为下面的形式
'''
docs = [
['明天','的','天气','是','晴天'],
['今天','的','天气','是','阴天'],
['昨天','的','天气','是','刮大风']]
'''
collection = nltk.TextCollection(docs)#collection是一个nltklearning的集合,其参数必须是list类型的
uniqTerms = list(set(collection))#构建一个词的list,该list包含所有的词,但只出现一次
for doc in docs:
print("Start====================")
for term in uniqTerms:
#if collection.tf_idf(term, doc)>0.00001:
print("%s : %f" % (term, collection.tf_idf(term, doc)))
print("%s : %f" % (term, collection.tf(term, doc)))
print("End======================")
if __name__ == '__main__':
main()
5.向量空间模型VSM
向量空间模型(Vector Space Model,简称VSM)表示通过向量的方式来表征文本。一个文档(Document)被描述为一系列关键词(Term)的向量:
V(d)=(t_1 W_1(d);...;t_n W_n(d))
常用的向量空间公式见下图:
网友评论