让我们以以下计数为例。第一个术语在 100% 的时间里出现,因此不是很重要。另外两个特征只在不到 50% 的时间里出现,因此可能更能代表文档的内容
>>> counts = [[3, 0, 1],
... [2, 0, 0],
... [3, 0, 0],
... [4, 0, 0],
... [3, 2, 0],
... [3, 0, 2]]
...
>>> tfidf = transformer.fit_transform(counts)
>>> tfidf
with 9 stored elements and shape (6, 3)> >>> tfidf.toarray() array([[0.81940995, 0. , 0.57320793], [1. , 0. , 0. ], [1. , 0. , 0. ], [1. , 0. , 0. ], [0.47330339, 0.88089948, 0. ], [0.58149261, 0. , 0.81355169]]) 每行都被标准化为具有单位欧几里得范数 \(v_{norm} = \frac{v}{||v||_2} = \frac{v}{\sqrt{v{_1}^2 + v{_2}^2 + \dots + v{_n}^2}}\) 例如,我们可以按如下方式计算 counts 数组中第一个文档中第一个术语的 tf-idf \(n = 6\) \(\text{df}(t)_{\text{term1}} = 6\) \(\text{idf}(t)_{\text{term1}} = \log \frac{n}{\text{df}(t)} + 1 = \log(1)+1 = 1\) \(\text{tf-idf}_{\text{term1}} = \text{tf} \times \text{idf} = 3 \times 1 = 3\) 现在,如果我们对文档中的其余 2 个术语重复此计算,我们得到 \(\text{tf-idf}_{\text{term2}} = 0 \times (\log(6/1)+1) = 0\) \(\text{tf-idf}_{\text{term3}} = 1 \times (\log(6/2)+1) \approx 2.0986\) 和原始 tf-idfs 向量 \(\text{tf-idf}_{\text{raw}} = [3, 0, 2.0986].\) 然后,应用欧几里得 (L2) 范数,我们得到文档 1 的以下 tf-idfs \(\frac{[3, 0, 2.0986]}{\sqrt{\big(3^2 + 0^2 + 2.0986^2\big)}} = [ 0.819, 0, 0.573].\) 此外,默认参数 smooth_idf=True 会在分子和分母中添加“1”,就好像看到了一个包含集合中每个术语恰好一次的额外文档,这可以防止零除法 \(\text{idf}(t) = \log{\frac{1 + n}{1+\text{df}(t)}} + 1\) 使用此修改,文档 1 中第三个术语的 tf-idf 变为 1.8473 \(\text{tf-idf}_{\text{term3}} = 1 \times \log(7/3)+1 \approx 1.8473\) L2-标准化 tf-idf 更改为 \(\frac{[3, 0, 1.8473]}{\sqrt{\big(3^2 + 0^2 + 1.8473^2\big)}} = [0.8515, 0, 0.5243]\): >>> transformer = TfidfTransformer() >>> transformer.fit_transform(counts).toarray() array([[0.85151335, 0. , 0.52433293], [1. , 0. , 0. ], [1. , 0. , 0. ], [1. , 0. , 0. ], [0.55422893, 0.83236428, 0. ], [0.63035731, 0. , 0.77630514]]) 通过 fit 方法调用计算出的每个特征的权重存储在模型属性中 >>> transformer.idf_ array([1., 2.25, 1.84]) 由于 tf-idf 经常用于文本特征,因此还有另一个名为 TfidfVectorizer 的类,它将 CountVectorizer 和 TfidfTransformer 的所有选项组合在一个模型中 >>> from sklearn.feature_extraction.text import TfidfVectorizer >>> vectorizer = TfidfVectorizer() >>> vectorizer.fit_transform(corpus) with 19 stored elements and shape (4, 9)> 虽然 tf-idf 标准化通常非常有用,但在某些情况下,二进制出现标记可能提供更好的特征。这可以通过使用 CountVectorizer 的 binary 参数来实现。特别是,一些估计器,如伯努利朴素贝叶斯,明确地建模离散布尔随机变量。此外,非常短的文本可能具有嘈杂的 tf-idf 值,而二进制出现信息更稳定。 像往常一样,调整特征提取参数的最佳方法是使用交叉验证网格搜索,例如通过将特征提取器与分类器进行管道连接 文本特征提取和评估的示例管道