无论idf如何,Python tfidf都会返回相同的值

时间:2016-04-26 16:27:23

标签: python scikit-learn nltk tf-idf kaggle

我正在尝试构建一个计算python中tfidf的小程序。我使用了两个非常好的教程(我有来自here的代码和来自kaggle的另一个函数)

import nltk
import string
import os
from bs4 import *
import re
from nltk.corpus import stopwords # Import the stop word list
import numpy as np

from sklearn.feature_extraction.text import TfidfVectorizer
from nltk.stem.porter import PorterStemmer

path = 'my/path'
token_dict = {}
stemmer = PorterStemmer()

def stem_tokens(tokens, stemmer):
    stemmed = []
    for item in tokens:
        stemmed.append(stemmer.stem(item))
    return stemmed

def tokenize(text):
    tokens = nltk.word_tokenize(text)
    stems = stem_tokens(tokens, stemmer)
    return stems

def review_to_words( raw_review ):
    # 1. Remove HTML
    review_text = BeautifulSoup(raw_review).get_text() 
    # 2. Remove non-letters        
    letters_only = re.sub("[^a-zA-Z]", " ", review_text) 
    # 3. Convert to lower case, split into individual words
    words = letters_only.lower().split()                             
    # 4. In Python, searching a set is much faster than searching
    #   a list, so convert the stop words to a set
    stops = set(stopwords.words("english"))                  
    # 5. Remove stop words
    meaningful_words = [w for w in words if not w in stops]   
    # 6. Join the words back into one string separated by space, 
    # and return the result.
    return( " ".join( meaningful_words ))  



for subdir, dirs, files in os.walk(path):
    for file in files:
        file_path = subdir + os.path.sep + file
        shakes = open(file_path, 'r')
        text = shakes.read()
        token_dict[file] = review_to_words(text)

tfidf = TfidfVectorizer(tokenizer=tokenize, stop_words='english')
tfs = tfidf.fit_transform(token_dict.values())


str = 'this sentence has unseen text such as computer but also king  lord lord  this this and that lord juliet'#teststring
response = tfidf.transform([str])

feature_names = tfidf.get_feature_names()
for col in response.nonzero()[1]:
    print feature_names[col], ' - ', response[0, col]

代码似乎工作正常,但我看看结果。

thi  -  0.612372435696
text  -  0.204124145232
sentenc  -  0.204124145232
lord  -  0.612372435696
king  -  0.204124145232
juliet  -  0.204124145232
ha  -  0.204124145232
comput  -  0.204124145232

所有单词的IDF似乎都相同,因为TFIDF只是n * 0.204。我查看了tfidf.idf_ 而这似乎就是这种情况。

方法中有什么东西我没有正确实现吗? 你知道为什么idf_s是一样的吗?

2 个答案:

答案 0 :(得分:0)

由于您提供了包含1个文档的列表,因此所有术语idfs将具有相同的“二进制频率”。

idf是文档集上的反转术语频率(或仅反转文档频率)。大多数(如果不是全部)idf公式只检查文档中的术语存在,因此每个文档出现的次数无关紧要。

尝试输入一个包含3个不同文档的列表,这样idfs就不一样了。

答案 1 :(得分:0)

项t的逆文档频率计算如下。

enter image description here

N是文档总数,df_t是术语t出现的文档数。

在这种情况下,您的程序有一个文档(str变量)。 因此,N和df_t都等于1。 因此,所有条款的IDF都是相同的。