2016-04-26 5 views
0

Я пытаюсь создать небольшую программу, которая вычисляет tfidf в python. Есть две очень хорошие учебники, которые я использовал (У меня есть код от here и другую функцию от kaggle)Python tfidf возвращает одинаковые значения независимо от idf

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 кажутся одинаковыми для всех слов, поскольку TFIDFs являются только n * 0.204. Я проверил с tfidf.idf_ , и это, похоже, имеет место.

Есть ли что-то в методе, который я не реализовал правильно? Вы знаете, почему idf_s одинаковы?

+1

Изучив ваш код, я не нашел наверняка, что может быть неправильным. Однако я нашел что-то странное. Почему вы дважды останавливаете слова остановки? Один раз в вашей функции 'review_to_words()', а также при инициализации 'TfidfVectorizer'. –

ответ

0

Поскольку вы предоставили список, содержащий 1 документ, все термины idfs будут иметь равную «двоичную частоту».

idf - это частота перевернутого периода по набору документов (или только частота перевернутого документа). Большинство, если не все формулы idf проверяют только наличие термина в документе, поэтому не имеет значения, сколько раз оно появляется на одном документе.

Попробуйте подать список с помощью трех различных документов, например, idfs не будут одинаковыми.

0

Частота обратного документа в терминах t рассчитывается следующим образом.

enter image description here

N- общее количество документов и df_t это количество документов, где появляется термин т.

В этом случае ваша программа имеет один документ (переменная str). Следовательно, оба N и df_t равны 1. В результате IDF для всех условий одинаковы.

 Смежные вопросы

  • Нет связанных вопросов^_^