既存の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();
}
}
}