2016-04-20 87 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

非常感謝。 –