SciPy および scikit-learn を使用して、バイナリテキスト分類用の多項単純ベイズ分類器をトレーニングおよび適用します。正確には、モジュール _sklearn.feature_extraction.text.CountVectorizer
_ を使用して、テキストからの単語の特徴数を保持するスパース行列を作成し、モジュール _sklearn.naive_bayes.MultinomialNB
_ をトレーニングの分類子実装として使用します。トレーニングデータの分類器とテストデータへの適用。
CountVectorizer
への入力は、Unicode文字列として表されるテキストドキュメントのリストです。トレーニングデータは、テストデータよりもはるかに大きくなります。私のコードは次のようになります(簡略化):
_vectorizer = CountVectorizer(**kwargs)
# sparse matrix with training data
X_train = vectorizer.fit_transform(list_of_documents_for_training)
# vector holding target values (=classes, either -1 or 1) for training documents
# this vector has the same number of elements as the list of documents
y_train = numpy.array([1, 1, 1, -1, -1, 1, -1, -1, 1, 1, -1, -1, -1, ...])
# sparse matrix with test data
X_test = vectorizer.fit_transform(list_of_documents_for_testing)
# Training stage of NB classifier
classifier = MultinomialNB()
classifier.fit(X=X_train, y=y_train)
# Prediction of log probabilities on test data
X_log_proba = classifier.predict_log_proba(X_test)
_
問題:MultinomialNB.predict_log_proba()
が呼び出されるとすぐに、_ValueError: dimension mismatch
_が返されます。以下のIPythonスタックトレースによると、エラーはSciPyで発生します。
_/path/to/my/code.pyc
--> 177 X_log_proba = classifier.predict_log_proba(X_test)
/.../sklearn/naive_bayes.pyc in predict_log_proba(self, X)
76 in the model, where classes are ordered arithmetically.
77 """
--> 78 jll = self._joint_log_likelihood(X)
79 # normalize by P(x) = P(f_1, ..., f_n)
80 log_prob_x = logsumexp(jll, axis=1)
/.../sklearn/naive_bayes.pyc in _joint_log_likelihood(self, X)
345 """Calculate the posterior log probability of the samples X"""
346 X = atleast2d_or_csr(X)
--> 347 return (safe_sparse_dot(X, self.feature_log_prob_.T)
348 + self.class_log_prior_)
349
/.../sklearn/utils/extmath.pyc in safe_sparse_dot(a, b, dense_output)
71 from scipy import sparse
72 if sparse.issparse(a) or sparse.issparse(b):
--> 73 ret = a * b
74 if dense_output and hasattr(ret, "toarray"):
75 ret = ret.toarray()
/.../scipy/sparse/base.pyc in __mul__(self, other)
276
277 if other.shape[0] != self.shape[1]:
--> 278 raise ValueError('dimension mismatch')
279
280 result = self._mul_multivector(np.asarray(other))
_
このエラーが発生する理由がわかりません。誰かが私にそれを説明し、この問題の解決策を提供できますか?よろしくお願いします!
トレーニングデータセットは語彙を修正するため、テストデータセットにvectorizer.transform
を使用する必要があるように思えます(結局、トレーニングセットを含む完全な語彙を知ることはできません)。明確にするために、それはvectorizer.transform
の代わりにvectorizer.fit_transform
です。
別の解決策は vector.vocabulary を使用することです
# after trainning the data
vector = CountVectorizer()
vector.fit(self.x_data)
training_data = vector.transform(self.x_data)
bayes = MultinomialNB()
bayes.fit(training_data, y_data)
# use vector.vocabulary for predict
vector = CountVectorizer(vocabulary=vector.vocabulary)
text_vector = vector.transform(text)
trained_model.predict_prob(text_vector)