【问题标题】:Python tfidf returning same values regardless of idf无论 idf 如何,Python tfidf 返回相同的值
【发布时间】:2016-04-26 16:27:23
【问题描述】:

我正在尝试构建一个在 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 是一样的吗?

【问题讨论】:

  • 检查您的代码我还没有确定可能有什么问题。不过我确实发现了一些奇怪的东西。你为什么要两次剥离停用词?一旦进入您的review_to_words() 函数以及初始化TfidfVectorizer

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


【解决方案1】:

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

idf 是文档集上的倒置词频(或只是倒置文档频率)。大多数(如果不是全部)idf 公式仅检查文档中是否存在术语,因此每个文档出现多少次并不重要。

例如,尝试提供一个包含 3 个不同文档的列表,这样 idf 将不一样。

【讨论】:

    【解决方案2】:

    一个词t的逆文档频率计算如下。

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

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

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2020-11-08
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2016-03-07
      • 2014-02-21
      • 2016-03-30
      • 1970-01-01
      相关资源
      最近更新 更多