Dartsを試してみた
ダブル配列なTrie構造を実装するためのライブラリであるDartsを試してみました。
DartsはMeCabの作者として知られる工藤 拓氏の作品で、もともとMeCabに組み込まれていたDouble-Arrayのコード部分を、工藤氏が改めてリパッケージしてものだそうです。
なおDartsそのものはC++ライブラリなので、これを他の言語から使うにはバインディングが必要となります。perlから使うにはCPANにText::Dartsというモジュールがあがっているので、これを使わせてもらいます。
なおText::Dartsは、これまた有名なid:dankogai氏の作品です。
で、これらを試してみたのですが、結論から言うと
Dartsを使うには
- Text::Darts 0.03は現時点でDarts0.32に対応していないっぽい。makeでコケる。なのでDarts0.31を使うべし。
- Dartsに付属のmkdartsは g++ -o mkdart mkdarts.cpp としてコンパイルすればOK。
- 対象のキーワードファイルは事前にソートしておく必要があるが、export LANG="" してからsortしないとダメ。
ということがわかりました。
1つ目のText::DartsがDarts0.32に対応していない件ですが、makeするとこんなエラーがでました。
Darts.xs:21: error: invalid conversion from `char**' to `const char**'
Darts.xs:21: error: initializing argument 2 of `int Darts::DoubleArrayImpl::build(size_t, const node_type_**, const size_t*, const array_type_*, int (*)(size_t, size_t)) [with node_type_ = char, node_u_type_ = unsigned char, array_type_ = int, array_u_type_ = unsigned int, length_func_ = Darts::Length ]'
Dartsの0.32の更新履歴をチェックしてみたら「細かいコードのクリーンナップ (const をできるだけ付けるようにした) 」という記述を発見。
たぶんこの「const化」の変更によってText::Darts 0.03のXSでは対応できなくなったんではないでしょうか。
やっぱり更新履歴を表記しておくことって大事なんだな、と思いつつ、
Darts0.32対応版のText::Darts、はやくCPANに登場しないかな〜、と軽くid:dankogaiさんにONEDARIしてみる実験。
ちなみにサーバの環境は RedHat ES4, perl 5.8.8, gcc 3.4.6-3 です。
2つ目のmkdartsの件は、単純に自分でコンパイルしないとバイナリでは付属されてないよ。というだけの意味です。
3つ目のソートの件はあやうくドはまりするところだった!
LANG=ja_JP.UTF-8 にしている場合に「文字列をbyte sequenceとみたときの大小順」が異なるようです。ここのブログで一発解決でした → http://blog.livedoor.jp/imsut/archives/50129131.html
ほんと、ハマる前にググってよかった〜。
以上の点に注意すると、めでたくText::DartsからDartsが呼び出せるようになります。
ですが、perldoc Text::Dartsで例示されているのは、はてなキーワードみたいに「もとのテキストをマッチした部分だけ加工して置き換える」事例だったので、純粋に「マッチしたキーワードをピックアップしたい」場合にどうすればよいのは一瞬わからなかったんですが、下記のようなスクリプトでやりたいことはできました。
use strict; use Text::Darts; use LWP::Simple; my $url = "http://hoge/index.html"; my $text = get($url); my $data; my $td = Text::Darts->open("keyword.idx"); $td->gsub( $text, sub { $data->{ $_[0] }++; } ); for( sort { $data->{$a} <=> $data->{$b} } keys %$data ){ print $_, "\t", $data->{$_}, "\n"; }
gsubのところの使い方がイメージと合ってない気もするんですが、こんなんでいいのかな?
一応期待したキーワードがうまく抽出できてるし、速度面でも問題ないようです。
それにしても、こんな便利なライブラリを公開してくれている工藤さん、あとperlから便利に使えるようにしてくれているid:dankogaiさん、ご両名ともグレイト。