はてなキーワードをIMEに辞書登録してみる その1

GoogleIMEの衝撃とでも言うのでしょうか、「くだらない言葉」が変換できる快適さに慣れると、なかなか離れられません。しかし、このGoogleIME、IMEとしての使いやすさはイマイチ。文節区切りすると一気に馬鹿になるし、再変換(確定戻し)も出来ない、キーバインドも(簡単には)変えられない。
さて、困った、ということで、使い慣れたATOKに「くだらない言葉」を登録すればいいじゃん、というのを発端として行動スタート。

で、ATOKなんですが、おりしも、
ATOK×ニコニコ動画「ニコニコ日本語入力 powered by ATOK」ダウンロード|ATOK定額制サービス ATOK for Windows / ATOK for Mac
なんてキャンペーンをやっており、ニコニコはどうでもいいのですが、このキャンペーンだと普段は30日間の体験版が90日まで使えるというお得感。
早速インストールして、何となくニコニコ動画由来の「くだらない言葉」が予測変換される体験をしてるのですが、そのあまりのくだらなさにウンザリ。
もっとオーセンティックな「くだらない言葉」を求めて、
[044692]はてなキーワード辞書 for ATOK
に辿り着くも、UserIDが無いとダウンロード出来ないようです。ATOKの体験版はID発行されないんですよね、当然ながら。

さて、そうなると「元ネタ」にあたるのがよいだろうということで、
はてなダイアリーキーワードふりがなリストを公開しました - はてなダイアリー日記
を辞書化すればいいじゃん、という、ようやく本題に辿り着きます。

「こういうベタな作業なら誰かがやってるに違いない、車輪の再発明をすることはない」と高をくくってたのですが、これが意外と先駆者がいない。かろうじてSKKからみで多少のノウハウはあるものの、MS-IMEの辞書化するなんていう誰でも思いつきそうなことを誰もやってない。
ここで一抹の不安が。「誰でも思いつくのに誰もやっていないことは、どこかに致命的な欠陥がある」という格言が頭をよぎるも、たいした手間でもないしやってみることに。

元ネタのファイル keywordlist_furigana.csv文字コードEUC-JPのタブ区切り。これをMS-IME用のデータに変換してやる。MS-IME辞書ならATOKでも読み込めるので、互換性重視です。
で、この元ネタのキーワード、多少の癖があるので、全角半角コンバートや、コンバート後のダブり除去なんかもオプション搭載する。
あと、これは個人差有ると思いますが、たとえば「AK47」なんてターゲットを「えーけーよんじゅうなな」なんて打ち込んで変換することがあるか?って話です。普通、英数モードに切り替えて、そのまんま入力でしょう。いや、個人差有りますけどね。その辺もオプション搭載。いっそのこと、英数字含んでるのはモード切り替えて直入力するので、そういう単語いらない、なんてのもオプション搭載。

オプションまとめ

  • eiji #'ANAマイレージクラブ'のようなアルファベットを含む単語も登録対象とする
  • alleiji #AK47のようなアルファベットだけの単語も登録対象とする
  • zenkaku #全角英数字を保持

辞書は標準出力に、登録しなかったキーワードはerror.txtに吐きます

実行例
perl hatena2dic.pl [-eiji] [-alleiji] [-zenkaku] keywordlist_furigana.csv > msime.txt

んで、ソース

#!/usr/bin/perl -w
use strict;
use Jcode;
use Getopt::Long;

#'ANAマイレージクラブ'のようなアルファベットを含む単語も登録対象とする
my $eiji = 0;
#AK47のようなアルファベットだけの単語も登録対象とする
my $allEiji = 0;
#全角英数字を保持
my $keepzenkaku = 0;

GetOptions('eiji' => \$eiji, 'alleiji' => \$allEiji, 'zenkaku' => \$keepzenkaku);

#ダミーのヘッダ
my $mshead  = '!Microsoft IME Dictionary Tool
!Version:
!Format:WORDLIST
!User Dictionary Name: http://d.hatena.ne.jp/images/keyword/keywordlist_furigana.csv
!Output File Name: 
!DateTime: 

';

print jcode($mshead)->sjis;

#無視単語軍
open(my $FH, ">","error.txt") || die "FILE open ERROR :$!";

my $count = 0;
my $pre = "";

while(<>){
    chop;
    my @a = split("\t");
    
    if($a[0] ne ""){
	my $yomi = jcode($a[0])->sjis;
	my $moji = $a[1];
	my $from = '[0-9A-Za-z&]';
	my $to = '[0-9A-Za-z&]';

	#zenkaku EIJI to hankaku EIJI
	if(!$keepzenkaku){
	    $moji = jcode($moji)->tr(jcode($from)->euc , jcode($to)->euc)->euc;
	}

	if($allEiji){
	    #全て英字の単語は無視 (ex. 'EARTH WIND AND FIRE')
	    if( $moji =~ /^[\x00-\x7F]+$/){
		print $FH $moji . "\n";
		next;
	    }
	} elsif ($eiji){
	    #do nothing 
	} else {
	    #英字を含む単語は無視(デフォルト)
	    if( $moji =~ /[\x00-\x7F]/){
		print $FH $moji . "\n";
		next;
	    }
	}

	#ダブりは無視
	if ($pre eq $moji){
	    print $FH "double : " . $moji . "\n";
	    next;
	}
	$pre = $moji;

	#品詞は決めうち
	my $hinsi = jcode('固有名詞')->sjis;
	print $yomi . "\t" . jcode($moji)->sjis .  "\t". $hinsi . "\n";
	$count++;
    }
}

close($FH);

うまく生成できたら、それを各IMEの辞書管理ツールに食わせてやるだけ。
ちなみに、ATOKは省入力データにも同じものが使えるので、普通の辞書と2重に登録してやる感じになります。

さて、これで効率は上がるのか?

次回に続く予定