如何通过scikit-learn TfidfVectorizer计算TF-IDF

pra*_*nth 15 nlp tf-idf scikit-learn

我运行以下代码将文本矩阵转换为TF-IDF矩阵.

text = ['This is a string','This is another string','TFIDF computation calculation','TfIDF is the product of TF and IDF']

from sklearn.feature_extraction.text import TfidfVectorizer
vectorizer = TfidfVectorizer(max_df=1.0, min_df=1, stop_words='english',norm = None)

X = vectorizer.fit_transform(text)
X_vovab = vectorizer.get_feature_names()
X_mat = X.todense()
X_idf = vectorizer.idf_
Run Code Online (Sandbox Code Playgroud)

我得到以下输出

X_vovab =

[u'calculation',
 u'computation',
 u'idf',
 u'product',
 u'string',
 u'tf',
 u'tfidf']
Run Code Online (Sandbox Code Playgroud)

和X_mat =

  ([[ 0.        ,  0.        ,  0.        ,  0.        ,  1.51082562,
      0.        ,  0.        ],
    [ 0.        ,  0.        ,  0.        ,  0.        ,  1.51082562,
      0.        ,  0.        ],
    [ 1.91629073,  1.91629073,  0.        ,  0.        ,  0.        ,
      0.        ,  1.51082562],
    [ 0.        ,  0.        ,  1.91629073,  1.91629073,  0.        ,
      1.91629073,  1.51082562]])
Run Code Online (Sandbox Code Playgroud)

现在我不明白这些分数是如何计算的.我的想法是,对于文本[0],仅计算"字符串"的得分,并且在第5列中有得分.但由于TF_IDF是项频率为2的乘积,而log(4/2)的IDF是1.39而不是1.51,如矩阵所示.如何在scikit-learn中计算TF-IDF分数.

Rab*_*bit 15

TF-IDF由Scikit Learn的TfidfVectorizer分多步完成,实际上使用TfidfTransformer并继承CountVectorizer.

让我总结一下它所做的步骤,使其更直接:

  1. tfs由CountVectorizer的fit_transform()计算
  2. idf由TfidfTransformer的fit()计算
  3. tfidf由TfidfTransformer的transform()计算

您可以在此处查看源代码.

回到你的例子.以下是对第5个词汇表(第1个文档(X_mat [0,4])的tfidf权重进行的计算:

首先,第一个文档中的'string'的tf:

tf = 1
Run Code Online (Sandbox Code Playgroud)

第二,'string'的idf,启用平滑(默认行为):

df = 2
N = 4
idf = ln(N + 1 / df + 1) + 1 = ln (5 / 3) + 1 = 1.5108256238
Run Code Online (Sandbox Code Playgroud)

最后,(文档0,功能4)的tfidf权重:

tfidf(0,4) = tf * idf = 1 * 1.5108256238 = 1.5108256238
Run Code Online (Sandbox Code Playgroud)

我注意到你选择不规范化tfidf矩阵.请记住,对tfidf矩阵进行归一化是一种常见且通常推荐的方法,因为大多数模型都需要对特征矩阵(或设计矩阵)进行归一化.

默认情况下,TfidfVectorizer将L-2标准化输出矩阵,作为计算的最后一步.将其标准化意味着它只有0到1之间的权重.

  • 这个回答真的很好!!我花了一整天的时间来理解这一点。@Rabbit 你能在这个例子中展示如何应用规范化吗? (2认同)

Chr*_*sch 5

精确的计算公式在文档中给出:

用于tf-idf的实际公式是tf*(idf + 1)= tf + tf*idf,而不是tf*idf

通过在文档频率中添加一个来平滑idf权重,就好像看到一个额外的文档只包含集合中的每个术语一次.

这意味着1.51082562获得1.51082562=1+ln((4+1)/(2+1))