namazu-ml(avocado)


[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

a tool to exclude phrases from kakasidict



高林です

w3-searchメイリングリストの記事に触発されて kakasidict からフレイ
ズを除外するツールを作ってみました。

いきさつ
| >「バックボーン」という単語はkakasi -wをかけた時に、
| >「バックボーン」という一つの単語にされてしまうので、
| >「バック」や「ボーン」では検索できないようです。
| 
| (snip)
| 
| >kakasiをつかっているnamazuやSSEはどうなっているのでしょうね?
| 
| 同じです。KAKASI はカタカナには弱いので「バックボーン」は解決しま
| せんが、日本語のフレイズについては辞書に含まれる連語をすべて除外す
| るとずいぶん変わってくるはずです。たとえば
| 
|     せんたんかがくぎじゅつ / 先端科学技術
| 
| はフレイズを構成する「先端」「科学」「技術」がそれぞれ辞書に登録さ
| れているので削除します。このようにすると、「先端」や「科学」で検索
| したときに「先端科学技術」が漏れることはなくなります。
| 
| フレイズ検索が可能ならばこの方針は悪くないと思います。 Namazuのフ
| レイズ検索は半分インチキなのでちょっとあれですけど。
| 
| 試しに kakasidict から連語を除外する Perlスクリプトを作ったので興
| 味のある方はお試しください。メイルの末尾に添付しておきます。
| 
|     $ ./pexclude kakasidict 2> warning > result
| 
| のように実行すると result に連語が除外された辞書ができます (csh系
| はリダイレクトの方法が異なるでしょう)。warning にはなにかしらのメッ
| セージが残ります。Pentium 133 MHz, Memory 64 MB のマシンで 2分 30
| 秒程度かかります。

いかがなものでしょう。
 
-- Satoru Takabayashi

#!/usr/bin/perl
#
# pexclude - exclude phrases from kakasidict
#
# by Satoru Takabayashi <satoru@xxxxxxxxxxxxx>
# Copyright (C) 1998 Satoru Takabayashi  All rights reserved.
#     This is free software with ABSOLUTELY NO WARRANTY.
#
# You can redistribute it and/or modify it under the terms of 
# the GNU General Public License version 2.
#

use strict;
use IO::File;
require 5.003;
my $CHAR = "(?:[\x21-\x7e]|[\xa1-\xfe][\xa1-\xfe])";
my $NONKANJI = "(?:[\x21-\x7e]|[\xa1-\xaf][\xa1-\xfe])";
# my $HIRAGANA = "(?:[\xa4][\xa1-\xf3])";
# my $KATAKANA = "(?:[\xa4][\xa1-\xf6])";
# my $CHOON    = "(?:[\xa1][\xbc])";
# my $NUMBER   = "(?:[\xa3][\xb0-\xb9])";
# my $LOWALPHA = "(?:[\xa3][\xe1-\xfa])";
# my $UPPALPHA = "(?:[\xa3][\xc1-\xda])";
# my $KANJI    = "(?:[\xb0-\xfe][\xa1-\xfe])";


die if @ARGV == 0;

STDOUT->autoflush(1);
STDERR->autoflush(1);

print STDERR "start: ", scalar(localtime), "\n";
my %dict;

{
    my $dictfile = $ARGV[0];
    my ($fh) = new IO::File;

    $fh->open("$dictfile") || die "$!: $dictfile\n";
    while (<$fh>) {
	next if /^;/;

	/^(.*?) +(.*)$/;
	if (defined($dict{$2})) { # conflict
	    print STDERR "'$2 ($1)' is already defined as '$2 ($dict{$2})'!\n";
	    next;
	}
	$dict{$2} = $1;
    }
}

{
    my @list =  sort {length($b) <=> length($a)} keys %dict;

  LOOP1:
    for (@list) {
	my $hyoki = $_;
	my $hyoki_rest = $hyoki;
	my @konkyo = ();

	if (length($hyoki) <= 4) {
	    print "$dict{$hyoki} $hyoki\n";
	    next;
	}
	while (length($hyoki_rest) > 0) {
	    my $tmp = $hyoki_rest;
	    my $try = "";
	    my $hyoki_match = "";

	    while (length($tmp) > 0) {
		$tmp =~ /^($CHAR)/;
		$try .= $1;
		if (defined($dict{$try}) && $try ne $hyoki) {
		    $hyoki_match = $try;
		} 
		$tmp =~ s/^$CHAR//;
	    }
	    if (length($hyoki_match) > 0) {
		$hyoki_rest =~ s/^$hyoki_match//;
		push(@konkyo, $hyoki_match);
	    } elsif ($hyoki_rest =~ /^($NONKANJI+)/) { 
		my $hyoki_match = $1;
		$hyoki_rest =~ s/^$hyoki_match//;
		push(@konkyo, $hyoki_match);
	    } else {
		print "$dict{$hyoki} $hyoki\n";
		next LOOP1;
	    }
	}
	my $tmp = join(', ', @konkyo);
	print STDERR "Removed: $hyoki [$tmp]\n";
	undef $dict{$hyoki};
    }
}
print STDERR "finish: ", scalar(localtime), "\n";