web-dev-qa-db-ja.com

NLTKでBag-of-Words Naive-Bayes分類器を実装する

基本的に この男と同じ質問 ..ナイーブベイズ分類器の NLTKブックの例 は、Wordがドキュメントに機能として出現するかどうかのみを考慮します。これは、単語の頻度を調べる機能( "bag-of-words")とは見なしません。

回答の1つ は、組み込みのNLTK分類器ではこれを実行できないことを示唆しているようです。それは事実ですか?頻度/単語のバッグNB NLTKで分類するにはどうすればよいですか?

23
bgcode

scikit-learn には 多項式の単純ベイズの実装 があり、これはこの状況での単純ベイズの正しい変形です。ただし、サポートベクターマシン(SVM)の方がおそらくうまく機能します。

ケンがコメントで指摘したように、NLTKには scikit-learn分類器の素敵なラッパー があります。ドキュメントから変更された、TF-IDF重み付けを行い、chi2統計に基づいて1000の最良の特徴を選択し、それを多項式の単純ベイズ分類器に渡す、やや複雑なものを次に示します。 (NLTKやscikit-learnのどちらにも精通していないので、これは多少不器用だと思います。)

import numpy as np
from nltk.probability import FreqDist
from nltk.classify import SklearnClassifier
from sklearn.feature_extraction.text import TfidfTransformer
from sklearn.feature_selection import SelectKBest, chi2
from sklearn.naive_bayes import MultinomialNB
from sklearn.pipeline import Pipeline

pipeline = Pipeline([('tfidf', TfidfTransformer()),
                     ('chi2', SelectKBest(chi2, k=1000)),
                     ('nb', MultinomialNB())])
classif = SklearnClassifier(pipeline)

from nltk.corpus import movie_reviews
pos = [FreqDist(movie_reviews.words(i)) for i in movie_reviews.fileids('pos')]
neg = [FreqDist(movie_reviews.words(i)) for i in movie_reviews.fileids('neg')]
add_label = lambda lst, lab: [(x, lab) for x in lst]
classif.train(add_label(pos[:100], 'pos') + add_label(neg[:100], 'neg'))

l_pos = np.array(classif.classify_many(pos[100:]))
l_neg = np.array(classif.classify_many(neg[100:]))
print "Confusion matrix:\n%d\t%d\n%d\t%d" % (
          (l_pos == 'pos').sum(), (l_pos == 'neg').sum(),
          (l_neg == 'pos').sum(), (l_neg == 'neg').sum())

これは私のために印刷されました:

Confusion matrix:
524     376
202     698

完璧ではありませんが、まともな問題ではありません。非常に簡単な問題ではなく、100/100でのみトレーニングされています。

31
Dougal

NLTKベイ分類器の特徴は、数値ではなく「公称」です。つまり、有限数の離散値(ラベル)を取ることができますが、頻度として扱うことはできません。

したがって、ベイズ分類器では、次のことはできません直接単語の頻度を機能として使用-機能セットとして各テキストから50のより頻繁な単語を使用するようなことを行うことができますが、それはまったく異なります

しかし、NLTKには、頻度に依存する他の分類子があるかもしれません。わからないけど見た?チェックアウトする価値があると思います。

7
alexis
  • 見ている文字列を単語に分けてリストに入れる
  • リストの各アイテムについて尋ねる:このアイテムは、機能リストにある機能ですか?.
  • そうである場合は、通常どおりログ確率を追加し、そうでない場合は無視します。

あなたの文が同じWordを複数回持っている場合、それは確率を複数回追加するだけです。 Wordが同じクラスで複数回出現する場合、トレーニングデータはWordカウントにそれを反映する必要があります。

精度を高めるために、すべてのバイグラム、トライグラムなどを個別の機能として数えます。

自分の分類子を手動で記述して、何が起こっているか、正確さを向上させるために何をする必要があるかを正確に理解できるようにします。事前にパッケージ化されたソリューションを使用していて、十分に機能しない場合、それについてできることはあまりありません。

3
Matt