単語のバッグアプローチを使用するだけでなく、単語の順序を考慮してテキストを分類するにはどうすればよいですか?


10

メッセージボード上のスパム投稿を分類するために、bag-of-words手法を使用する単純ベイズ分類器を作成しました。それは機能しますが、私のモデルが単語の順序とフレーズを考慮した場合、はるかに良い結果が得られると思います。(例:「ライブガール」がジャンクである可能性が最も高いとしても、「ガール」と「ライブ」は高いスパムスコアをトリガーしない場合があります)。単語の順序を考慮したモデルを構築するにはどうすればよいですか?

私はn-gram(check-out-these、out-these-live、these-live-girls)を保存することを検討しましたが、これはスコアを保持する辞書のサイズを根本的に増やして、非常に言葉遣いは似ていますが、順序が異なります。

私はベイジアン分類に縛られていませんが、統計に強いバックグラウンドがない人が手に入れて実装できるものを望んでいます。


n-gramモデルは、単語の順序を検討する場合によく使用されます。en.wikipedia.org/wiki/N-gramを
ブレントランス

回答:


6

既存のBag-of-Wordsモデル実装に単語の順序を組み込む非常に単純なハックがあります。頻繁に発生するバイグラム(ニューヨークなど)などのフレーズの一部を1つの単位として扱います。つまり、個別のエンティティとして扱うのではなく、1つの単語として扱います。これにより、「ニューヨーク」と「ヨークニュー」が確実に異なります。n = 3、4などの高次の単語の帯状疱疹を定義することもできます。

Lucene ShingleFilterを使用して、前処理ステップとしてドキュメントテキストを帯状疱疹に分解し、この分解されたテキストに分類子を適用できます。

import java.io.*;
import org.apache.lucene.analysis.core.*;
import org.apache.lucene.analysis.*;
import org.apache.lucene.analysis.shingle.ShingleFilter;
import org.apache.lucene.analysis.standard.*;
import org.apache.lucene.util.*;
import org.apache.lucene.analysis.util.*;
import org.apache.lucene.analysis.tokenattributes.CharTermAttribute;
import org.apache.lucene.analysis.charfilter.*;
import org.apache.lucene.analysis.core.WhitespaceTokenizer;

class TestAnalyzer extends Analyzer {

    TestAnalyzer() {
        super();
    }

    protected TokenStreamComponents createComponents( String fieldName, Reader reader ) {
        String token;
        TokenStream result = null;

        Tokenizer source = new WhitespaceTokenizer( Version.LUCENE_CURRENT, reader );
        result = new ShingleFilter(source, 2, 2);

        return new TokenStreamComponents( source, result );

    }
}

public class LuceneTest {

    public static void main(String[] args) throws Exception {

        TestAnalyzer analyzer = new TestAnalyzer();

        try {
            TokenStream stream = analyzer.tokenStream("field", new StringReader("This is a sample sentence."));
            CharTermAttribute termAtt = stream.addAttribute(CharTermAttribute.class);

            stream.reset();

            // print all tokens until stream is exhausted
            while (stream.incrementToken()) {
                System.out.println(termAtt.toString());
            }

            stream.end();
            stream.close();
         }
         catch (Exception ex) {
             ex.printStackTrace();
         }

    }
}


2

テクニックはたくさんあります。あなたはすでにnグラムについて言及しました、そして単語の組み合わせなどがあります。ただし、主な問題(少なくともユーザーの観点から)は、機能が(n-gramのように)より複雑になると、機能数が劇的に増加することです。これは扱いやすいです。基本的に、分類の前に、機能にスコアを付け、特定のスコアでしきい値を設定する必要があります。このようにして、特定のレベルを下回ってスコア付けされた機能(または、あなたの場合はn-gram)が省略され、機能の数が管理可能になります。得点も。機能をスコアリングする方法は多数あります(どの方法を選択するかはアプリケーションによって異なります)。「BiNormal分離」、「カイ二乗」、「情報ゲイン」などから始めることができます。この答えがあなたに役立つかどうかはわかりませんが、興味があれば詳しく説明できます...

単語の組み合わせで、サイズmのウィンドウをテキストに置き、n単語の各組み合わせを抽出するのを忘れました。もちろんn

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.