当我们分析文本数据时,经常遇到的问题就是:一个单词出现在两种类型的多个文档中。这种频繁出现的单词通常不包含有用或具备辨识度的信息。在本小节中,我们将学习一种称为词频-逆文档频率(term frequency-inverse document frequency,tf-idf)的技术,它可以用于解决特征向量中单词频繁出现的问题。tf-idf可以定义为词频与逆文档频率的乘积:
tf-idf(t,d)=tf(t,d)×idf(t,d)
其中,tf(t,d)是我们上一节中介绍的词频,而逆文档频率idf(t,d)可通过如下公式计算:
这里的nd为文档的总数,df(d,t)为包含词汇t的文档d的数量。请注意,分母中加入常数1是可选的,对于没有出现在任何训练样本中的词汇,它能保证分母不为零;取对数是为了保证文档中出现频率较低的词汇不会被赋予过大的权重。
scikit-learn还实现了另外一个转换器:TfidfTransformer,它以CountVectorizer的原始词频作为输入,并将其转换为tf-idf:
在上一小节中我们看到,is在第三个文档中具有最高的词频,它是文档中出现得最为频繁的单词。但是在将特征向量转换为tf-idf后,单词is在第三个文档中只得到了一个相对较小的tf-idf(0.48),这是由于第一和第二个文档中都包含单词is,因此它不太可能包含有用或是有辨识度的信息。
不过,如果我们人工计算特征向量中单个条目的tf-idf值,就会发现,TfidfTrans-former中对tf-idf的计算方式与我们此前定义的标准计算公式不同。scikit-learn中实现的idf和tf-idf分别为:
在scikit-learn中使用的tf-idf公式为:
tf-idf(t,d)=tf(t,d)×(idf(t,d)+1)
通常在计算tf-idf之前都会对原始词频进行归一化处理,TfidfTransformer就直接对tf-idf做了归一化。默认情况下(norm='l2'),scikit-learn中的TfidfTransformer使用L2归一化,它通过与一个未归一化特征向量L2范数的比值,使得返回向量的长度为1:
为确保读者能够理解TfidfTransformer的工作方式,在此我们给出一个例子,计算第三个文档中单词is的tf-idf。
在文档3中,单词is的词频为2(tf=2),由于is在三个文档中都出现过,因此它的文档频率为3(df=3)。由此,idf的计算方法如下:
为了计算tf-idf,我们需要为逆文档频率的值加1,并且将其与词频相乘:
tf-idf("is",d3)=2×(0+1)=2
如果我们对第三个文档中的所有条目重复此过程,将会得到如下tf-idf向量:[1.69,2.00,1.29,1.29,1.29,2.00,1.29]。大家应该注意到了,这里得到的特征向量的值不同于此前我们使用TfidfTransformer得到的值。最后还缺少一个对tf-idf进行L2归一化的步骤,计算方式如下:
可以看到,现在的结果与使用scikit-learn中TfidfTransformer得到的值相同。既然已经理解了tf-idf的计算方式,我们进入下一节,将这些概念应用于电影评论数据集。