3

私はベクトル空間モデル (VSM) の初心者です。そして、このサイトのコードを試しました 。これは VSM の非常に優れた紹介ですが、どうにかして著者とは異なる結果を得ることができました。導入が書かれてからscikit Learnが大きく変更されたように見えるので、互換性の問題が原因である可能性があります。私も説明を誤解していたのかもしれません。
以下のコードを使用して間違った答えを得ました。誰かがそれの何が悪いのか理解できますか? 以下のコードの結果と下の正しい答えを投稿します

私は手で計算を行ったので、ウェブサイトの結果が良いことを知っています. 同じコードを使用する別のStackoverflow の質問がありますが、Web サイトと同じ結果は得られません。

import numpy, scipy, sklearn

train_set = ("The sky is blue.","The sun is bright.")
test_set = ("The sun is the sky is bright.", "We can see the shining sun, the bright sun.")

from sklearn.feature_extraction.text import CountVectorizer
vectorizer = CountVectorizer(stop_words= 'english')

vectorizer.fit_transform(train_set)


smatrix = vectorizer.transform(test_set)


from sklearn.feature_extraction.text import TfidfTransformer


tfidf = TfidfTransformer(norm='l2', sublinear_tf=True)


tfidf.fit(smatrix)
#print smatrix.todense()
print tfidf.idf_

tf_idf_matrix = tfidf.transform(smatrix)
print tf_idf_matrix.todense()

tf-idf
#[ 2.09861229 1. 1.40546511 1. ]の結果ベクトル

tf-idf
#[0.69314718, -0.40546511, -0.40546511, 0]の右ベクトル

結果 tf_idf_matrix
#[[ 0. 0.50154891 0.70490949 0.50154891]
#[ 0. 0.50854232 0. 0.861037 ]]

正解
# [[ 0. -0.70710678 -0.70710678 0. ]
# [ 0. -0.89442719 -0.4472136 0. ]]

4

1 に答える 1

4

それはあなたのせいではありません。現在使用されている式sklearnとチュートリアルで使用されている式が異なるためです。

の現在のバージョンでは、次のsklearn式を使用しています ( source ):

idf = log ( n_samples / df ) + 1

ここで、n_samplesはドキュメントの総数 (|D|チュートリアル内) をdf指し、用語が表示されるドキュメントの数(チュートリアル内) を指し{d:t_1 \in D}ます。

ゼロ除算を処理するために、デフォルトでスムージング ( のオプションsmooth_idf=TrueドキュメントTfidfVectorizerを参照) を使用してとの値を次のように変更するため、これらの値は少なくとも 1 になります。dfn_samples

df += 1
n_samples += 1

チュートリアルのものはこの式を使用していますが:

idf = log ( n_samples / (1+df) )

そのため、ソース コードの式を変更しない限り、チュートリアルとまったく同じ結果を得ることはできません。

編集

厳密に言えば、正しい式は ですlog(n_samples/df)が、実際にはゼロ除算の問題が発生するため、人々は式を修正して、すべての場合に使用できるようにしようとします。最も一般的なのはあなたが言ったようなものですが、事前に平滑化されていることを考えるとlog(n_samples/(1+df))、式を使用することも間違っていません. log(n_samples/df)+1しかし、コード履歴を読むと、IDF 値が負にならないようにそうしているようです (このプル リクエストで説明され、後でこの修正で更新されます)。負の IDF 値を削除する別の方法は、単純に負の値を 0 に変換することです。どの方法がより一般的に使用されているかはまだわかりません。

彼らは、自分たちのやり方が標準的なやり方ではないことに同意しました。log(n_samples/(1+df))したがって、それが正しい方法であると安全に言うことができます。

数式を編集するには、コードを使用するすべてのユーザーに影響することを最初に警告する必要があります。何をしているのかを確認してください。

ソース コード (Unix の場合: に/usr/local/lib/python2.7/dist-packages/sklearn/feature_extraction/text.pyあります。Windows の場合: 現在 Windows を使用していませんが、"text.py" ファイルを検索できます) に移動して、式を直接編集できます。使用するプラットフォームによっては、管理者/ルート アクセスが必要になる場合があります。

追記

追加の注意として、語彙の用語の順序も(少なくとも私のマシンでは)異なるため、まったく同じ結果を得るには(式が同じ場合)、まったく同じ語彙を次のように渡す必要があります。チュートリアルに示されています。だからあなたのコードを使用して:

vocabulary = {'blue':0, 'sun':1, 'bright':2, 'sky':3}
vectorizer = CountVectorizer(vocabulary=vocabulary) # You don't need stop_words if you use vocabulary
vectorizer.fit_transform(train_set)
print 'Vocabulary:', vectorizer.vocabulary_
# Vocabulary: {'blue': 0, 'sun': 1, 'bright': 2, 'sky': 3}
于 2013-09-09T06:25:36.713 に答える