33

トピック カテゴリでタグ付けされた約 30 万のドキュメントが Postgres データベースに格納されています (合計で約 150 のカテゴリがあります)。まだカテゴリがないドキュメントが 15 万件あります。プログラムでそれらを分類する最良の方法を見つけようとしています。

私はNLTKとその Naive Bayes Classifier を調べてきました。良い出発点のように思えます (このタスクのためのより良い分類アルゴリズムを提案できるなら、私はすべて耳にします)。

私の問題は、NaiveBayesClassifier を 150 カテゴリ/300k ドキュメントすべてで一度にトレーニングするのに十分な RAM がないことです (5 つのカテゴリでトレーニングすると 8GB が使用されます)。さらに、より多くのカテゴリでトレーニングするにつれて、分類器の精度が低下するようです (2 つのカテゴリで 90% の精度、5 で 81%、10 で 61% の精度)。

一度に 5 つのカテゴリで分類器をトレーニングし、150,000 のドキュメントすべてを分類器で実行して、一致するかどうかを確認する必要がありますか? これはうまくいくように思えますが、どのカテゴリにも実際には一致しないドキュメントが、利用可能な最良の一致であるという理由だけで分類子によって押し付けられるという多くの誤検知があることを除いて... ありますか?ドキュメントがどのカテゴリにも当てはまらない場合に備えて、分類子に「上記のいずれでもない」オプションを設定する方法はありますか?

ここに私のテストクラスがあります http://gist.github.com/451880

4

3 に答える 3

33

ドキュメントをTF-log(1 + IDF)ベクトルに変換することから始めます。用語の頻度はまばらなので、用語をキーとしてpython dictを使用し、値としてカウントしてから、合計カウントで割ってグローバル頻度を取得する必要があります。

別の解決策は、たとえばabs(hash(term))を正の整数キーとして使用することです。次に、Pythondictよりも線形代数演算を実行するのに便利で効率的なscipy.sparseベクトルを使用します。

また、同じカテゴリに属する​​すべてのラベル付きドキュメントの頻度を平均して、150の頻度ベクトルを作成します。 次に、ラベルを付ける新しいドキュメントについて、ドキュメントベクトルと各カテゴリベクトルの間の余弦類似度を計算し、ドキュメントのラベルとして最も類似したカテゴリを選択できます。

これが十分でない場合は、このscikit-learnので説明されているようにL1ペナルティを使用してロジスティック回帰モデルをトレーニングする必要があります(これは@ephesで説明されているliblinearのラッパーです)。ロジスティック回帰モデルのトレーニングに使用されるベクトルは、良好なパフォーマンス(適合率と再現率)を得るために、以前に導入されたTD-log(1 + IDF)ベクトルである必要があります。scikit learn libは、特定のモデルと特定のデータセットのスコアを計算するルーチンを備えたsklearn.metricsモジュールを提供します。

大規模なデータセットの場合:大規模なドキュメント分類の問題では、おそらく地球上で最速のウサギであるvowpal wabbitを試す必要があります(ただし、PythonラッパーAFAIKを使用するのは簡単ではありません)。

于 2010-06-24T21:55:16.733 に答える
11

あなたの文書はどれくらいの大きさ(単語数)ですか?150Kのtrainingdocsでのメモリ消費は問題にはなりません。

ナイーブベイズは、トレーニング例が少ない、またはトレーニングデータが非常にノイズの多いカテゴリが多数ある場合に特に適しています。しかし、一般的に、線形サポートベクターマシンのパフォーマンスははるかに優れています。

問題はマルチクラス(ドキュメントは1つのカテゴリにのみ属している)ですか、それともマルチラベル(ドキュメントは1つ以上のカテゴリに属している)ですか?

精度は、分類器のパフォーマンスを判断するための適切な選択ではありません。適合率vs再現率、適合率再現率損益分岐点(prbp)、f1、aucを使用し、信頼度しきい値の値に基づいて適合率(x)が適合率(y)に対してプロットされている適合率vs再現率曲線を確認する必要があります。 (ドキュメントがカテゴリに属しているかどうか)。通常、カテゴリごとに1つのバイナリ分類子を作成します(1つのカテゴリのポジティブトレーニング例と、現在のカテゴリに属していない他のすべてのトレーニング例)。カテゴリごとに最適な信頼度のしきい値を選択する必要があります。カテゴリごとのこれらの単一の測定値をグローバルなパフォーマンス測定値に結合する場合は、マイクロ(すべての真陽性、偽陽性、

数千万のドキュメント、数百万のトレーニング例、数千のカテゴリ(マルチラベル)のコーパスがあります。トレーニング時間の深刻な問題に直面しているため(1日あたりのドキュメントの新規、更新、削除の数が非常に多い)、liblinearの修正バージョンを使用します。ただし、liblinearのPythonラッパーの1つ( liblinear2scipyまたはscikit-learn )を使用する小さな問題の場合は、正常に機能するはずです。

于 2010-06-24T20:45:05.283 に答える
2

ドキュメントがどのカテゴリにも当てはまらない場合に備えて、分類子に「上記のどれでもない」オプションを設定する方法はありますか?

この効果は、毎回「上記のどれでもない」疑似カテゴリをトレーニングするだけで得られる可能性があります。トレーニングできる最大数が5つのカテゴリである場合(RAMを大量に消費する理由はわかりませんが)、実際の2Kドキュメントからそれぞれ4つの実際のカテゴリをトレーニングし、2Kドキュメントで「上記のどれでもない」カテゴリをトレーニングします。他のすべての146のカテゴリからランダムに取得されます(「層化サンプリング」アプローチが必要な場合は、それぞれから約13〜14で、より健全な場合があります)。

それでも少し厄介な感じがするので、まったく異なるアプローチを使用したほうがよい場合があります。300Kの事前タグ付きドキュメントを150の合理的に分離可能なクラスターに定義する多次元ドキュメントメジャーを見つけて、それぞれを割り当てます。 -このように決定された適切なクラスターへのタグなしドキュメント。NLTKには、この種のことをサポートするために直接利用できるものはないと思いますが、ねえ、NLTKは非常に急速に成長しているので、何かを見逃している可能性があります...;-)

于 2010-06-24T20:42:55.973 に答える