如何在TfidfVectorizer中计算术语频率?

时间:2017-02-24 14:03:37

标签: python-3.x scikit-learn tf-idf

我搜索了很多,但是我无法理解。我了解默认情况下,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}

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

1 个答案:

答案 0 :(得分:2)

好的,现在让我们一步一步地完成documentation I gave in comments

文件:

`ખુબ વખાણ કરે છે
 ખુબ વધારે છે`
  1. 获取所有唯一条款(features):['કરે', 'ખુબ', 'છે.', 'વખાણ', 'વધારે']
  2. 计算文件中每个词的频率: -

    一个。文档1 [ખુબ વખાણ કરે છે]中存在的每个术语都存在一次,并且વધારે不存在。

    湾所以术语频率向量(根据特征排序):[1 1 1 1 0]

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

    d。所以我们的最终术语 - 频率向量是[[1 1 1 1 0], [0 1 1 0 1]]

    注意:这是您想要的术语频率

  3. 现在找到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..
    

    注意:这与您展示的数据相对应。

  4. 现在计算TF-IDF(这再次按文档计算,根据特征排序计算):

    一个。对于document1:

     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]

    湾现在正常化(l2 Euclidean):

    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...
    

    用dividor划分tf-idf数组的每个元素,我们得到:

    [0.6088445 0.3595948 0.3595948548 0.6088445 0]

    注意:这是您发布的第一份文件的tfidf。

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

    [ 0. 0.453294 0.453294 0. 0.767494]

  5. 更新:关于sublinear_tf = True OR False

    您的原始术语频率向量为[[1 1 1 1 0], [0 1 1 0 1]],您的理解是正确的,即使用sublinear_tf = True将更改术语频率向量。

    new_tf = 1 + log(tf)
    

    现在上面的行只适用于term-frequentcny中的非零元素。因为对于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获得差异。

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