我们用以下计数为例。第一个词元出现了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-idf向量 \(\text{tf-idf}_{\text{raw}} = [3, 0, 2.0986].\) 然后,应用欧几里得(L2)范数,我们得到文档1的以下tf-idf值 \(\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值,而二进制出现信息则更稳定。 通常,调整特征提取参数的最佳方法是使用交叉验证网格搜索,例如通过将特征提取器与分类器进行流水线操作 文本特征提取和评估的示例流水线