2016-04-26 12 views
0

私はpythonでtfidfを計算する小さなプログラムを構築しようとしています。私が使用している2つの非常に素晴らしいチュートリアルがありますが、コードが正常に動作するようです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] 

(私はhereからコードとkaggleから別の機能を持っている)が、その後、私は結果を見てみましょう。

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

TFIDFがちょうどn * 0.204であるため、IDFはすべての単語で同じように見えます。私はtfidf.idf_ とチェックしており、これが当てはまるようです。

正しく実装されていない方法がありますか? idf_sが同じ理由を知っていますか?

+1

あなたのコードを調べてみると、何が間違っているのかは確かに見つかりませんでした。私は奇妙な何かを見つけた。なぜあなたはストップワードを2回ストリッピングしていますか?一旦あなたの 'review_to_words()'関数に入り、 'TfidfVectorizer'を初期化するときにも。 –

答えて

0

1つのドキュメントを含むリストを提供したので、すべての用語idfsは等しい「バイナリ頻度」を持ちます。

idfは、ドキュメントセット(または反転されたドキュメント周波数)上の反転ターム周波数です。すべてではないにしても、ほとんどのidf式は文書内の用語の存在をチェックするだけなので、文書ごとに何回出現するかは関係ありません。

たとえば3つの異なるドキュメントをリストに追加すると、idfsが同じにならない場合があります。

0

用語tの逆文書頻度は、次のように計算されます。

enter image description here

N書類やdf_tの総数は用語tが表示された文書の数です。

この場合、プログラムには1つの文書(str変数)があります。 したがって、Nとdf_tの両方は1になります。 その結果、すべての用語のIDFは同じになります。

関連する問題