2016-04-20 72 views
3

我认为函数TfidfVectorizer不能正确计算IDF因子。 例如,复制从tf-idf feature weights using sklearn.feature_extraction.text.TfidfVectorizer代码:使用来自sklearn.feature_extraction.text.TfidfVectorizer的TfidfVectorizer计算IDF

from sklearn.feature_extraction.text import TfidfVectorizer 
corpus = ["This is very strange", 
      "This is very nice"] 
vectorizer = TfidfVectorizer(
         use_idf=True, # utiliza o idf como peso, fazendo tf*idf 
         norm=None, # normaliza os vetores 
         smooth_idf=False, #soma 1 ao N e ao ni => idf = ln(N+1/ni+1) 
         sublinear_tf=False, #tf = 1+ln(tf) 
         binary=False, 
         min_df=1, max_df=1.0, max_features=None, 
         strip_accents='unicode', # retira os acentos 
         ngram_range=(1,1), preprocessor=None,    stop_words=None, tokenizer=None, vocabulary=None 
      ) 
X = vectorizer.fit_transform(corpus) 
idf = vectorizer.idf_ 
print dict(zip(vectorizer.get_feature_names(), idf)) 

输出为:

{u'is': 1.0, 
u'nice': 1.6931471805599454, 
u'strange': 1.6931471805599454, 
u'this': 1.0, 
u'very': 1.0}` 

但应该是:

{u'is': 0.0, 
u'nice': 0.6931471805599454, 
u'strange': 0.6931471805599454, 
u'this': 0.0, 
u'very': 0.0} 

不是吗?我究竟做错了什么?

鉴于IDF的计算中,根据http://www.tfidf.com/,是:

IDF(t) = log_e(Total number of documents/Number of documents with term t in it) 

因此,当术语 '这个', '是' 和 '非常' 出现在两个句子,的IDF = log_e(2/2)= 0.

术语'奇怪'和'好'只出现在两个文档中的一个中,所以log_e(2/1)= 0,69314。

+0

嘿普里西拉。我不是一个Python用户,但你能澄清你想要做什么以及遇到的问题吗?如果他们明白你的确切目标,你为什么试图获得专家用户的回应到达它,为什么输出是错误的。祝你好运得到一个答案,并欢迎来到堆栈溢出 –

+0

我真的需要明白我能做些什么来获得正确的tf-idf值使用sklearn函数,因为他们正在返回 –

回答

5

两个事情发生,你可能不会在sklearn执行力度预计:

  1. TfidfTransformer具有smooth_idf=True作为默认PARAM
  2. 它总是加1重量

所以正在使用:

idf = log(1 + samples/documents) + 1 

这是源:

https://github.com/scikit-learn/scikit-learn/blob/master/sklearn/feature_extraction/text.py#L987-L992

编辑: 你可以继承的标准TfidfVectorizer类是这样的:

import scipy.sparse as sp 
import numpy as np 
from sklearn.feature_extraction.text import (TfidfVectorizer, 
              _document_frequency) 
class PriscillasTfidfVectorizer(TfidfVectorizer): 

    def fit(self, X, y=None): 
     """Learn the idf vector (global term weights) 
     Parameters 
     ---------- 
     X : sparse matrix, [n_samples, n_features] 
      a matrix of term/token counts 
     """ 
     if not sp.issparse(X): 
      X = sp.csc_matrix(X) 
     if self.use_idf: 
      n_samples, n_features = X.shape 
      df = _document_frequency(X) 

      # perform idf smoothing if required 
      df += int(self.smooth_idf) 
      n_samples += int(self.smooth_idf) 

      # log+1 instead of log makes sure terms with zero idf don't get 
      # suppressed entirely. 
      ####### + 1 is commented out ########################## 
      idf = np.log(float(n_samples)/df) #+ 1.0 
      ####################################################### 
      self._idf_diag = sp.spdiags(idf, 
             diags=0, m=n_features, n=n_features) 

     return self 
+0

我已经将所有参数设置为false,但答案仍然不正确 –

+0

公式末尾的'+ 1'不能在参数中更改如果您想获得预期的答案,请使用'smooth_idf =假'和减1. – zemekeneng

+0

非常感谢。 –