2016-04-22 5 views
13

私はscikit-learnのTfIDFVectorizerクラスを使って特定の文書の特徴を表す言葉を得ようとしています。すべての文書にすべての単語とそのスコアを含むtfidf行列を作成しますが、一般的な単語も数えているようです。これは私が実行しているコードの一部です:scikit-learnのTFIDFVectorizerはどのように動作するはずですか?

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] 

私は、これは、文書のための独特の言葉「アダム」のリストを返すことが期待されるが、それが何をするか、それは一般的な単語のリストを返す:

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

私はそれを完全には理解していないかもしれませんが、理解しているように、tf-idfはコーパス内の1つの文書に特徴的な単語を見つけ、1つの文書に頻繁に出現するが他の文書には出現しない単語を探します。ここでは、andが他のドキュメントに頻繁に出てくるので、ここでなぜそれが高い価値を返すのか分かりません。

これを生成するために使用している完全コードはin this Jupyter notebookです。

半手動でtf/idfsを計算し、NLTKを使って各単語のスコアを計算すると、適切な結果が得られます。これらは「アダムの文書に出現する単語であるため、権利については見えるが、コーパス内の他の文書に限りません

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'を渡すことによってストップワードを無視することができますが、それは本当に問題を解決するものではありません。

答えて

3

scikit学習のドキュメントから:

TF-IDFは、非常に多くの場合、テキスト機能のために使用されているように、単一のモデルにCountVectorizerとTfidfTransformerのすべてのオプションを組み合わせTfidfVectorizerと呼ばれる別のクラスもあります。

このように、TfidfVectorizerCountVectorizerで、それに続いてTfidfTransformerです。あなたはおそらく探しているものを

は、私はあなたの問題は別のストップワードリストを使用することにあると考えているTfidfTransformerなくTfidfVectorizer

+0

TfidfTransformerはCountVectorizerの出力を変換するので、CountVectorizerを実行してからTfidfTransformerを実行できますが、これはTfidfVectorizerを実行しているのと同じです。とにかく、最初にCountVectorizerを実行する必要がある場合は、TfidfTransformerが必要であると私は確信していません。同じ結果を返しませんか? – Jono

2

です。 Scikit-learnとNLTKはデフォルトで異なるストップワードリストを使用します。 scikit-学ぶため、例えば、TfidfVectorizerに渡されたカスタムstop_wordsリストを持っていることは通常は良いアイデアです:

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]

+0

これは知っておいてよかったですが、どうしてなぜストップワードを削除する必要があるのか​​混乱していると思います。すべての文書で 'and'または 'the'が頻繁に発生する場合、なぜtf-idf値が高いのでしょうか? tf-idfのポイントは、すべての文書で用語の頻度を調整することであるため、コーパス全体で頻繁に発生する用語はリストの一番上には表示されません。 – Jono

+0

@ジョノ、あなたの直感は、TFIDFが稀有な用語に恩恵を受けるべきだと思います。これは真実ですTFIDFは、文書内の用語頻度であるTFと、ドキュメント全体にわたる逆用語頻度であるIDFとの2つの主要事項を考慮する。 TFは頻繁に利益を得る一方で、IDFは稀な利益をもたらします。これらの2つは、ほぼ反対の措置であり、TFIDFをバランスの取れた指標にしています。 – Rabbit

+0

また、ストップワードの削除は、ベクトル空間表現を使用する場合の非常に一般的な方法です。このように考えることができます:ほとんどのアプリケーションでは、重要な用語では重要度が高く、重要ではない場合には低/ゼロのメトリックが必要です。あなたの表現(この場合はTFIDF)がそれをしなければ、それはあなたのモデルを助けず、潜在的に損害を与える用語を削除することによってこれに対抗します。 – Rabbit

2

が、私はわからないんだけどデフォルトですが、おそらくsublinear_tf=TrueがTfidfVectorizerの初期化に必要です。私はあなたのレポをフォークし、おそらくあなたが望むもののように見える例でPRを送った。

+0

素晴らしいです。それは大きな改善です。しかし、すべての文字ではなく、より小さな文字セットで実行すると、よく使われる単語のリストが再び得られます:https://github.com/JonathanReeve/milton-analysis/blob/v0.2/tfidf- scikit.ipynb "and"、 "to"、 "the"、 "of"はアダムとイーヴにとって最高のtf-idfsを持つ単語ですが、それらはコーパス全体で頻繁に出現する単語なので、わかりませんなぜ彼らはここでハイスコアを得ているのですか? – Jono

+0

これで、文書数が大幅に減りました。したがって、IDFは、その用語が文書内で見つかった回数(すなわち、文書数*あたりの数)が増えても、4つの文書(任意の用語では4以下)で非常に大きくならず、十分な "統計力"を持っていない。 – fnl

関連する問題