bsfileter+chasenメモ全体に公開
2012年11月17日22:09
ベイジアンフィルターにchasenを導入してみた。
でも結構苦労したのでメモ。

■rubyのバージョン
bsfilterはruby1.9じゃないと対応していない。
一方でchasenのrubyバインディングは1.8のしかなさそう。
そこでこちらのページを参考にchasen.c、Makefileを書き換える。
http://qiita.com/items/38b8c625feb6c072bdca

リンク切れるといやなので申し訳ないけど転記。
diff --git Makefile Makefile
index 9cd4044..e668785 100644
--- Makefile
+++ Makefile
@@ -215,5 +215,5 @@ chasen.o: chasen.c $(hdrdir)/ruby/ruby.h \
$(arch_hdrdir)/ruby/config.h \
$(hdrdir)/ruby/defines.h \
$(hdrdir)/ruby/intern.h \
- $(hdrdir)/ruby/rubyio.h
+ $(hdrdir)/ruby/io.h

diff --git chasen.c chasen.c
index 177a52c..e41ed48 100644
--- chasen.c
+++ chasen.c
@@ -18,7 +18,7 @@
************************************************/

#include "ruby.h"
-#include "rubyio.h"
+#include "ruby/io.h"

#include <chasen.h>

@@ -27,10 +27,10 @@ f_chasen_getopt(int argc, VALUE *argv, VALUE class){
int i;
char **opt = ALLOCA_N(char*, argc + 2);

- opt[0] = "chasen.so";
+ opt[0] = RSTRING_PTR("chasen.so");
for (i = 0; i < argc; i++){
- Check_SafeStr(argv[i]);
- opt[i + 1] = RSTRING(argv[i])->ptr;
+ SafeStringValue(argv[i]);
+ opt[i + 1] = RSTRING_PTR(argv[i]);
}
opt[argc + 1] = NULL;

@@ -41,13 +41,13 @@ f_chasen_getopt(int argc, VALUE *argv, VALUE class){

static VALUE
f_chasen_sparse_tostr(VALUE obj, VALUE str){
- Check_SafeStr(str);
- return rb_str_new2(chasen_sparse_tostr(RSTRING(str)->ptr));
+ SafeStringValue(str);
+ return rb_str_new2(chasen_sparse_tostr(RSTRING_PTR(str)));
}

static VALUE
f_chasen_fparse_tostr(VALUE obj, VALUE io){
- OpenFile *fp;
+ rb_io_t *fp;
char *buf;
VALUE dst = Qnil;

@@ -56,7 +56,7 @@ f_chasen_fparse_tostr(VALUE obj, VALUE io){
rb_io_check_readable(fp);
dst = rb_str_new(NULL, 0);

- while ((buf = chasen_fparse_tostr(fp->f)) != NULL) {
+ while ((buf = chasen_fparse_tostr(rb_io_stdio_file(fp))) != NULL) {
rb_str_cat(dst, buf, strlen(buf));
}
return dst;

■文字コード
私の環境ではchasenの文字コードはutf-8にしている。
辞書もutf-8で作っているので簡単に変えられない。
一方でbsfilterはeucを前提にしているっぽい。
そこで、bsfilterからchasenを呼び出す部分と、chasenから結果を受け取る部分を修正した。

--- bsfilter_org 2012-08-08 14:26:46.000000000 +0900
+++ bsfilter 2012-11-17 21:50:07.000000000 +0900
@@ -1048,5 +1048,5 @@
end
when "chasen"
- Chasen.getopt("-F", '%H %m\n', "-j")
+ Chasen.getopt("-F", '%H %m\n', "-i","w")
@method = Proc::new {|s| chasen(s)}
when "kakasi"
@@ -1119,12 +1119,13 @@
def chasen(str)
str = str.gsub(/[\x00-\x7f]/, ' ')
+ strutf = str.encode(CODESET_UTF8)
if (str =~ /\A +\z/)
return []
end
array = Array::new
- Chasen.sparse(str).split("\n").each do |hinshi_token|
+ Chasen.sparse(strutf).split("\n").each do |hinshi_token|
if (hinshi_token =~ /(.*) (.*)/)
- hinshi = $1
- token = $2
+ hinshi = $1.encode(CODESET_EUCJP,CODESET_UTF8)
+ token = $2.encode(CODESET_EUCJP,CODESET_UTF8)
if (hinshi == "\xcc\xbe\xbb\xec")
if ((token =~ Reg_kanji_katakana) || (token.length > 2))

これでなんとか動いたっぽい。

コメント