了解 TfidfVectorizer 输出

Posted

技术标签:

【中文标题】了解 TfidfVectorizer 输出【英文标题】:Understanding TfidfVectorizer output 【发布时间】:2021-05-26 18:13:45 【问题描述】:

我正在用简单的例子测试TfidfVectorizer,但我无法弄清楚结果。

corpus = ["I'd like an apple",
          "An apple a day keeps the doctor away",
          "Never compare an apple to an orange",
          "I prefer scikit-learn to Orange",
          "The scikit-learn docs are Orange and Blue"]
vect = TfidfVectorizer(min_df=1, stop_words="english")
tfidf = vect.fit_transform(corpus)

print(vect.get_feature_names())    
print(tfidf.shape)
print(tfidf)

输出:

['apple', 'away', 'blue', 'compare', 'day', 'docs', 'doctor', 'keeps', 'learn', 'like', 'orange', 'prefer', 'scikit']
(5, 13)
  (0, 0)    0.5564505207186616
  (0, 9)    0.830880748357988
  ...

我正在计算第一句话的tfidf,我得到了不同的结果:

第一个文档 ("I'd like an apple") 仅包含 2 个单词(删除停用词后(根据 vect.get_feature_names() 的打印(我们保留:“like”、“apple”))李> TF("apple", Doucment_1) = 1/2 = 0.5 TF("like", Doucment_1) = 1/2 = 0.5 apple这个词在语料库中出现了3次。 like 这个词在语料库中出现了 1 次。 IDF (“苹果”) = ln(5/3) = 0.51082 IDF(“喜欢”)= ln(5/1) = 1.60943

所以:

tfidf("apple") 在 document1 = 0.5 * 0.51082 = 0.255 != 0.5564 tfidf("like") 在 document1 = 0.5 * 1.60943 = 0.804 != 0.8308

我错过了什么?

【问题讨论】:

【参考方案1】:

您的计算存在几个问题。

首先,关于如何计算TF有多种约定(见Wikipedia entry); scikit-learn not 使用文档长度对其进行规范化。来自user guide:

[...] 词频,一个词在给定文档中出现的次数 [...]

所以,这里是TF("apple", Document_1) = 1,而不是 0.5

第二,关于IDF的定义——来自docs:

如果smooth_idf=True(默认值),则将常量“1”添加到 idf 的分子和分母中,就好像看到一个额外的文档只包含集合中的每个术语一次,这样可以防止零除法:idf( t) = log [ (1 + n) / (1 + df(t)) ] + 1.

所以,我们将有

IDF ("apple") = ln(5+1/3+1) + 1 = 1.4054651081081644

因此

TF-IDF("apple") = 1 * 1.4054651081081644 =  1.4054651081081644

第三,使用默认设置norm='l2',进行额外的标准化;再次来自文档:

norm='l2' 时归一化为“c”(余弦),norm=None 时为“n”(无)。

从您的示例中明确删除这种额外的规范化,即

vect = TfidfVectorizer(min_df=1, stop_words="english", norm=None)

'apple'

(0, 0)  1.4054651081081644

即已经手动计算了

有关在norm='l2'(默认设置)时归一化如何影响计算的详细信息,请参阅用户指南的Tf–idf term weighting 部分;他们自己承认:

在 scikit-learn 的 TfidfTransformerTfidfVectorizer 中计算的 tf-idfs 与标准教科书符号略有不同

【讨论】:

以上是关于了解 TfidfVectorizer 输出的主要内容,如果未能解决你的问题,请参考以下文章

在 TfidfVectorizer 中如何计算词频?

了解python scikit-learn中的文本特征提取TfidfVectorizer

如何将 TfidfVectorizer 的输出馈送到 Sklearn 中的 LinearSVC 分类器?

将 Sklearn TFIDF 与其他数据相结合

Scikit - TF-IDF 空词汇

将提取的向量加载到 TfidfVectorizer