web-dev-qa-db-ja.com

scikit-learnのTFIDFVectorizerはどのように機能するのですか?

Scikit-learnのTfIDFVectorizerクラスを使用して、特定のドキュメントに特有の単語を取得しようとしています。すべてのドキュメントのすべての単語とそのスコアを含むtfidfマトリックスを作成しますが、一般的な単語もカウントするようです。これは私が実行しているコードの一部です:

vectorizer = TfidfVectorizer()
tfidf_matrix = vectorizer.fit_transform(contents)
feature_names = vectorizer.get_feature_names()
dense = tfidf_matrix.todense()
denselist = dense.tolist()
df = pd.DataFrame(denselist, columns=feature_names, index=characters)
s = pd.Series(df.loc['Adam'])
s[s > 0].sort_values(ascending=False)[:10]

私はこれがドキュメント「Adam」の特徴的な単語のリストを返すことを期待していましたが、それがすることは一般的な単語のリストを返します:

and     0.497077
to      0.387147
the     0.316648
of      0.298724
in      0.186404
with    0.144583
his     0.140998

私はそれを完全に理解していないかもしれませんが、私が理解するように、tf-idfはコーパス内の1つのドキュメントに特有の単語を見つけることになっています。ここでは、andが他のドキュメントに頻繁に登場するため、ここで高い値を返す理由がわかりません。

これを生成するために使用している完全なコードは このJupyterノートブックで です。

NLTKを使用して各Wordのスコアを計算し、半手動でtf/idfsを計算すると、適切な結果が得られます。 「アダム」文書の場合:

fresh        0.000813
prime        0.000813
bone         0.000677
relate       0.000677
blame        0.000677
enough       0.000677

これらは「アダム」文書に現れる単語であるが、コーパスの他の文書にはそれほど多くないため、これは正しいと思われる。これを生成するために使用される完全なコードは this Jupyter Notebook にあります。

Scikitコードに何か問題がありますか?適切な結果を返すこのクラスを初期化する別の方法はありますか?もちろん、stop_words = 'english'を渡すことでストップワードを無視することもできますが、これは実際の問題を解決するものではありません。

26
Jonathan

あなたの問題は、異なるストップワードリストの使用にあると思います。 Scikit-learnとNLTKはデフォルトで異なるストップワードリストを使用します。 scikit-learnの場合、通常、カスタムのstop_wordsリストをTfidfVectorizerに渡すことをお勧めします。

my_stopword_list = ['and','to','the','of']
my_vectorizer = TfidfVectorizer(stop_words=my_stopword_list)

TfidfVectorizerクラスのドキュメントページ:[ http://scikit-learn.org/stable/modules/generated/sklearn.feature_extraction.text.TfidfVectorizer.html] [1]

7
Rabbit

Scikit-learnドキュメントから:

Tf–idfはテキスト機能に非常によく使用されるため、CountVectorizerとTfidfTransformerのすべてのオプションを単一のモデルに結合するTfidfVectorizerという別のクラスもあります。

ご覧のとおり、- TfidfVectorizerCountVectorizer の後に TfidfTransformer が続きます。

おそらく探しているのは TfidfTransformer ではなく TfidfVectorizer です

6
Sagar Waghmode

以下のコードを使用すると、はるかに良い結果が得られます

vectorizer = TfidfVectorizer(sublinear_tf=True, stop_words='english')

出力

sustain    0.045090
bone       0.045090
thou       0.044417
thee       0.043673
timely     0.043269
thy        0.042731
prime      0.041628
absence    0.041234
rib        0.041234
feel       0.040259
Name: Adam, dtype: float64

そして

thee          0.071188
thy           0.070549
forbids       0.069358
thou          0.068068
early         0.064642
earliest      0.062229
dreamed       0.062229
firmness      0.062229
glistering    0.062229
sweet         0.060770
Name: Eve, dtype: float64
3
realmq

なぜそれがデフォルトではないのか分かりませんが、おそらくsublinear_tf=True TfidfVectorizerの初期化。私はあなたのレポを分岐し、おそらくあなたが望むものにより似ている例でPRをあなたに送りました。

2
Randy