2014-01-01: CPAN にアップロードしたので追記。
要旨
Search::Fulltext という大変シンプルな全文検索モジュールがリリースされていたので、N-gram トークナイザを提供する Search::Fulltext::Tokenizer::Ngram を書きました。
これを使うと日本語として怪しい表現でもとりあえずヒットするような全文検索ができます。
動機
大変シンプルなモジュールだったのでシンプルに使ってみようと思ったら現在のところ日本語のトークナイザは Search::Fulltext::Tokenizer::MeCab のみでした。Text::MeCab のインストールが億劫なのと、ワンダー日本語が跋扈している Web 文書なんかの検索だと N-gram の方が都合が良いこともあるので作ってみました。
念の為: N-gram って何
テキストを N 文字毎に区切ったもの。e.g., "色彩を持たない多崎つくると、彼の巡礼の年" から 2-gram を作ると "色彩", "彩を", "を持", ... "の年" といった具合になる。 要は文書中に出現する N 文字の組合せを網羅するので、N-gram を使ってインデックスを作ると N 文字以上のクエリにヒットする文書は一切取り零さなくなる。 短所は形態素の区切りを知らないので "京都" というクエリで "東京都" という語を含んだ文書までヒットする、N 文字以下のクエリは一切ヒットしない、N が小さいとインデックスが大きくなるなど。
使い方
インストール
cpanm などを使ってインストールできます:cpanm Search::Fulltext::Tokenizer::Ngram
git clone git@github.com:sekia/Search-Fulltext-Tokenizer-Ngram.git
cd Search-Fulltext-Tokenizer-Ngram
dzil test
dzil install
使用例
1-gram, 2-gram, 3-gram が使えます。
use strict;
use warnings;
use utf8;
use Search::Fulltext;
use Search::Fulltext::Tokenizer::Unigram; # 1-gram tokenizer
use Search::Fulltext::Tokenizer::Bigram; # 2-gram tokenizer
use Search::Fulltext::Tokenizer::Trigram; # 3-gram tokenizer
my $search_engine = Search::Fulltext->new(
docs => [
'ハンプティ・ダンプティ 塀の上',
'ハンプティ・ダンプティ 落っこちた',
'王様の馬みんなと 王様の家来みんなでも',
'ハンプティを元に 戻せなかった',
],
# 3-gram を使う
tokenizer => q/perl 'Search::Fulltext::Tokenizer::Trigram::create_token_iterator_generator'/,
);
# search はヒットした文書のインデックスを返す。ここでは [0, 1, 3]。
my $hit_documents1 = $search_engine->search('ハンプティ');
# ヒットしない。
# インデックスが 3-gram で構築されているため2文字の "王様" は載っていない。
my $hit_documents2 = $search_engine->search('王様')
4文字以上の N-gram が必要なら Search::Fulltext::Tokenizer::Ngram を継承して作ることができます:
package MyTokenizer::42gram {
use parent qw/Search::Fulltext::Tokenizer::Ngram/;
sub create_token_iterator_generator {
sub { __PACKAGE__->new(42)->create_token_iterator(@_) };
}
}
my $search_engine = Search::Fulltext->new(
docs => [ ... ],
tokenizer => q/perl 'MyTokenizer::42gram::create_token_iterator_generator'/,
);
TODO
Documentation.Upload to CPAN.
まとめ
大変シンプルなモジュールを大変シンプルに使うことができるようになりました。Enjoy!
Search::Fulltextの作者です.
返信削除Search::Fulltext::Tokenizer::* をどなたかが作ってくださるのを期待していたので,大変嬉しく思っております.
よろしければ,Search::Fulltext::Tokenizer::NgramをCPANにアップロードなさいませんか?
大まかな手順としてはこちらのサイトが参考になります.
http://blog.livedoor.jp/sasata299/archives/51284970.html
Search::Fulltext::Tokenizer::* に期待されるREADME(Pod)の書き方などはこちらをご覧いただければと思います.
https://github.com/laysakura/Search-Fulltext-Tokenizer-MeCab
楽な作業とは言えませんが,是非ご検討くださいませ.