Scikit-learn TfidfTransformer结果错误?

2 投票
1 回答
896 浏览
提问于 2025-04-18 09:01

我在使用scikit-learn的Tfidf转换器时,得到了“奇怪”的结果。通常情况下,我会认为一个在所有文档中都出现的词,它的idf值应该是0(我没有使用任何平滑或归一化的方法),因为我用的公式是文档总数的对数,除以包含这个词的文档数量。然而,显然(如下所示)scikit-learn的实现比我手动计算的每个idf值都多加了1。有没有人知道这是为什么?再说一次,我已经把平滑和归一化设置为None/False。

In [101]: from sklearn.feature_extraction.text import TfidfTransformer

In [102]: counts
Out[102]: 
array([[3, 0, 1],
       [2, 0, 0],
       [3, 0, 0],
       [4, 0, 0],
       [3, 2, 0],
       [3, 0, 2]])

In [103]: transformer = TfidfTransformer(norm=None, smooth_idf=False)

In [104]: transformer
Out[104]: 
TfidfTransformer(norm=None, smooth_idf=False, sublinear_tf=False,
         use_idf=True)

In [105]: tfidf = transformer.fit_transform(counts)

In [106]: tfidf.toarray()
Out[106]: 
array([[ 3.        ,  0.        ,  2.09861229],
       [ 2.        ,  0.        ,  0.        ],
       [ 3.        ,  0.        ,  0.        ],
       [ 4.        ,  0.        ,  0.        ],
       [ 3.        ,  5.58351894,  0.        ],
       [ 3.        ,  0.        ,  4.19722458]])

In [107]: transformer.idf_
Out[107]: array([ 1.        ,  2.79175947,  2.09861229])

In [108]: idf1 = np.log(6/6)

In [109]: idf1
Out[109]: 0.0

In [110]: idf2 = np.log(6/1)

In [111]: idf2
Out[111]: 1.791759469228055

In [112]: idf3 = np.log(6/2)

In [113]: idf3
Out[113]: 1.0986122886681098

我找不到任何能解释为什么idf值要加1的资料。我使用的scikit-learn版本是'0.14.1'。

顺便说一下,除了scikit-learn的其他解决方案对我来说并不太有用,因为我需要为网格搜索构建一个scikit-learn的管道。

1 个回答

7

这不是一个错误,而是一个功能

# log1p instead of log makes sure terms with zero idf don't get
# suppressed entirely
idf = np.log(float(n_samples) / df) + 1.0

这里提到的 +1 是用来让 idf 的标准化变得弱一些,否则那些在所有文档中都出现的元素会被完全去掉(因为它们的 idf=0,所以整个 tfidf=0)

撰写回答