7.2.特征提取#

7.2.特征提取#

让我们以以下计数为例。第一个术语在 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 值,而二进制出现信息更稳定。

像往常一样,调整特征提取参数的最佳方法是使用交叉验证网格搜索,例如通过将特征提取器与分类器进行管道连接

文本特征提取和评估的示例管道

相关推荐

七种诱捕甲鱼的绝技和秘诀2014-07-28 22:09:47 中国钓鱼人网 来源:野钓技巧
澳大利亚vs秘鲁
bt365在线投注

澳大利亚vs秘鲁

📅 08-12 👀 1530
仙剑奇侠传6
bt365在线投注

仙剑奇侠传6

📅 07-05 👀 5624
方舟生存进化生菜怎么得?(方舟 生菜)
bt365在线投注

方舟生存进化生菜怎么得?(方舟 生菜)

📅 11-01 👀 136