使用scikit-learn和hand计算的tf-idf矩阵值的差异

use*_*422 6 python machine-learning matrix tf-idf

我正在玩scikit-learn找到tf-idf价值观.

我有一套documents像:

D1 = "The sky is blue."
D2 = "The sun is bright."
D3 = "The sun in the sky is bright."
Run Code Online (Sandbox Code Playgroud)

我想创建一个这样的矩阵:

   Docs      blue    bright       sky       sun
   D1 tf-idf 0.0000000 tf-idf 0.0000000
   D2 0.0000000 tf-idf 0.0000000 tf-idf
   D3 0.0000000 tf-idf tf-idf tf-idf
Run Code Online (Sandbox Code Playgroud)

所以,我的代码Python是:

import nltk
import string

from sklearn.feature_extraction.text import TfidfVectorizer
from nltk.corpus import stopwords

train_set = ["sky is blue", "sun is bright", "sun in the sky is bright"]
stop_words = stopwords.words('english')

transformer = TfidfVectorizer(stop_words=stop_words)

t1 = transformer.fit_transform(train_set).todense()
print t1
Run Code Online (Sandbox Code Playgroud)

我得到的结果矩阵是:

[[ 0.79596054  0.          0.60534851  0.        ]
 [ 0.          0.4472136   0.          0.89442719]
 [ 0.          0.57735027  0.57735027  0.57735027]]
Run Code Online (Sandbox Code Playgroud)

如果我做手计算,那么矩阵应该是:

            Docs  blue      bright       sky       sun
            D1    0.2385    0.0000000  0.0880    0.0000000
            D2    0.0000000 0.0880     0.0000000 0.0880
            D3    0.0000000 0.058      0.058     0.058 
Run Code Online (Sandbox Code Playgroud)

我正在计算如同blueas tf= 1/2 = 0.5idfas log(3/1) = 0.477121255.因此tf-idf = tf*idf = 0.5*0.477 = 0.2385.这样,我正在计算其他tf-idf值.现在,我想知道为什么我在手计算矩阵和Python矩阵中得到不同的结果?哪个给出了正确的结果?我在手工计算中做错了什么,或者我的Python代码中有什么问题?

lej*_*lot 11

有两个原因:

  1. 你忽略了在这种情况下经常出现的平滑现象
  2. 你假设基数为10的对数

根据来源 sklearn不使用这样的假设.

首先,它平滑文档计数(所以没有0,永远):

df += int(self.smooth_idf)
n_samples += int(self.smooth_idf)
Run Code Online (Sandbox Code Playgroud)

它使用自然对数(np.log(np.e)==1)

idf = np.log(float(n_samples) / df) + 1.0
Run Code Online (Sandbox Code Playgroud)

l2应用了默认规范化.简而言之,scikit-learn在计算tfidf时会做更多"好看,小事".这些方法(他们或你的)都不好.他们只是更先进.