如何解决了解 TfidfVectorizer 输出
我正在用简单的示例测试 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
”、“{ {1}}") - TF("apple",Doucment_1) = 1/2 = 0.5
- TF("like",Doucment_1) = 1/2 = 0.5
- 单词
apple
在语料库中出现了 3 次。 - 单词
apple
在语料库中出现了 1 次。 - IDF(“苹果”)= ln(5/3) = 0.51082
- IDF(“喜欢”)= ln(5/1) = 1.60943
所以:
-
like
在文档 1 = 0.5 * 0.51082 = 0.255 != 0.5564 -
tfidf("apple")
在文档 1 = 0.5 * 1.60943 = 0.804 != 0.8308
我错过了什么?
解决方法
你的计算有几个问题。
首先,关于如何计算 TF 有多种约定(参见 Wikipedia entry); scikit-learn 不会不用文档长度对其进行标准化。来自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 的 TfidfTransformer
和 TfidfVectorizer
中计算的 tf-idfs 与标准教科书符号略有不同
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。