在 TfidfVectorizer 中如何计算词频?

Posted

技术标签:

【中文标题】在 TfidfVectorizer 中如何计算词频?【英文标题】:How term frequency is calculated in TfidfVectorizer? 【发布时间】:2017-07-15 09:39:35 【问题描述】:

为了理解这一点,我进行了很多搜索,但我无法做到。我了解默认情况下 TfidfVectorizer 将在词频上应用 l2 归一化。 This文章解释了它的方程式。我在用古吉拉特语写的文本上使用 TfidfVectorizer。以下是有关它的输出的详细信息:

我的两个文件是:

ખુબ વખાણ કરે છે

ખુબ વધારે છે

我使用的代码是:

vectorizer = TfidfVectorizer(tokenizer=tokenize_words, sublinear_tf=True, use_idf=True, smooth_idf=False)

这里,tokenize_words 是我用于标记单词的函数。 我的数据的TF-IDF列表是:

[[ 0.6088451   0.35959372  0.35959372  0.6088451   0.        ]
 [ 0.          0.45329466  0.45329466  0.          0.76749457]]

功能列表:

['કરે', 'ખુબ', 'છે.', 'વખાણ', 'વધારે']

idf的值:

'વખાણ': 1.6931471805599454, 'છે.': 1.0, 'કરે': 1.6931471805599454, 'વધારે': 1.6931471805599454, 'ખુબ': 1.0

请在这个例子中解释一下我的两个文档中每个术语的术语频率。

【问题讨论】:

可以参考scikit-learn.org/stable/modules/… 我也提到过。归一化后取不到值。 在此处发布您已展示 TF-IDF 的原始数据...它有 2 个文档。 @VivekKumar 感谢您的及时回复。我通过添加两个文档文本更新了我的问题。 【参考方案1】:

好的,现在让我们一步一步看一下documentation I gave in comments:

文件:

`ખુબ વખાણ કરે છે
 ખુબ વધારે છે`
    获取所有唯一术语 (features):['કરે', 'ખુબ', 'છે.', 'વખાણ', 'વધારે']

    计算文档中每个词条的频率:-

    一个。 document1 [ખુબ વખાણ કરે છે] 中存在的每个术语都存在一次,而 વધારે 不存在。`

    b.所以词频向量(按特征排序):[1 1 1 1 0]

    c。在document2上应用步骤a和b,我们得到[0 1 1 0 1]

    d。所以我们最终的词频向量是[[1 1 1 1 0], [0 1 1 0 1]]

    注意:这是您想要的词频

    现在找到 IDF(这是基于特征,而不是基于文档):

    idf(term) = log(number of documents/number of documents with this term) + 1

    将 1 添加到 idf 值以防止零除法。它由"smooth_idf" 参数控制,默认为True。

    idf('કરે') = log(2/1)+1 = 0.69314.. + 1 = 1.69314..
    
    idf('ખુબ') = log(2/2)+1 = 0 + 1 = 1
    
    idf('છે.') = log(2/2)+1 = 0 + 1 = 1
    
    idf('વખાણ') = log(2/1)+1 = 0.69314.. + 1 = 1.69314..
    
    idf('વધારે') = log(2/1)+1 = 0.69314.. + 1 = 1.69314..
    

    注意:这对应于您显示的数据。

    现在计算 TF-IDF(这又是按文档计算,根据特征排序计算):

    一个。对于文档 1:

     For 'કરે', tf-idf = tf(કરે) x idf(કરે) = 1 x 1.69314 = 1.69314
    
     For 'ખુબ', tf-idf = tf(કરે) x idf(કરે) = 1 x 1 = 1
    
     For 'છે.', tf-idf = tf(કરે) x idf(કરે) = 1 x 1 = 1
    
     For 'વખાણ', tf-idf = tf(કરે) x idf(કરે) = 1 x 1.69314 = 1.69314
    
     For 'વધારે', tf-idf = tf(કરે) x idf(કરે) = 0 x 1.69314 = 0
    

    所以对于document1,最终的tf-idf向量是[1.69314 1 1 1.69314 0]

    b.现在标准化完成(l2 欧几里得):

    dividor = sqrt(sqr(1.69314)+sqr(1)+sqr(1)+sqr(1.69314)+sqr(0))
             = sqrt(2.8667230596 + 1 + 1 + 2.8667230596 + 0)
             = sqrt(7.7334461192)
             = 2.7809074272977876...
    

    将 tf-idf 数组的每个元素用除数除,我们得到:

    [0.6088445 0.3595948 0.3595948548 0.6088445 0]

    注意:这是您发布的第一个文档的 tfidf。

    c。现在对文档 2 执行相同的步骤 a 和 b,我们得到:

    [ 0. 0.453294 0.453294 0. 0.767494]

更新:关于sublinear_tf = True OR False

您的原始词频向量是[[1 1 1 1 0], [0 1 1 0 1]],您的理解是正确的,即使用 sublinear_tf = True 会改变词频向量。

new_tf = 1 + log(tf)

现在上面的行只适用于 term-frequecny 中的非零元素。因为对于 0,log(0) 是未定义的。

所有非零条目都是 1。log(1) 是 0 和 1 + log(1) = 1 + 0 = 1`。

您会看到值为 1 的元素的值将保持不变。所以您的 new_tf = [[1 1 1 1 0], [0 1 1 0 1]] = tf(original)

由于sublinear_tf,您的词频发生了变化,但仍保持不变。

因此,如果您使用 sublinear_tf=Truesublinear_tf=False,以下所有计算将相同,输出也相同。

现在,如果您更改术语频率向量包含 1 和 0 以外的元素的文档,您将使用 sublinear_tf 获得差异。

希望您的疑虑现在得到解决。

【讨论】:

谢谢。但一种混乱。我设置了sublinear_tf = True。这意味着tf 应计算为1 + log(tf)。这是真的吗? 请发布您用于查找 tfidf 的整个代码。 你也在用smooth_idf=False吗? 是的。 smooth_idf=False。所以,就这么理解了。我只是对sublinear_tf 感到困惑。此参数的TrueFalse 中的值均未更改。我在我的问题中添加了一行代码。 哦。愚蠢的我。这真的很明显。我的错。谢谢维维克。它消除了我的疑虑。

以上是关于在 TfidfVectorizer 中如何计算词频?的主要内容,如果未能解决你的问题,请参考以下文章

Python中的TfidfVectorizer参数解析

机器学习入门-文本数据-构造Tf-idf词袋模型(词频和逆文档频率) 1.TfidfVectorizer(构造tf-idf词袋模型)

机器学习入门-文本数据-构造Tf-idf词袋模型(词频和逆文档频率) 1.TfidfVectorizer(构造tf-idf词袋模型)

如何从 TfidfVectorizer 计算余弦相似度?

如何从TfidfVectorizer计算余弦相似度?

如何同时计算大文件中的词频?