あれこれ備忘録@はてなブログ

勉強したことやニュースや出来事を備忘録として書いていきます

このブログには広告が含まれます

Anthyの辞書強化がうまくいっていない。原因らしきものについて

arekorebibouroku.hateblo.jp

先日、Anthyの辞書を強化してみた。

しかし、どうも登録したはずの単語が変換で出てこない。

ちょっと調べてみたところ、以下の不審な点が見つかった。

「/etc/anthy/diclist」に「/usr/share/anthy/dic」ディレクトリに入れた辞書ファイルの名前を登録した。

この後、

update-anthy-dics

コマンドを実行すると、「/var/lib/anthyディレクトリにまとまった辞書ファイル「anthy.dic」や「anthy.wdic」ができあがる。

update-anthy-dicsコマンドを実行した過程で、「/etc/anthy/dict.args」ファイルが更新される。

ここにはdiclistに書かれた辞書ファイル名と読み込む際の文字コードが指定されているようだ。

しかし、このファイルを見たところ

set_input_encoding eucjp
read /usr/share/anthy/dic/gcanna.ctd
read /usr/share/anthy/dic/gcannaf.ctd
read /usr/share/anthy/dic/gtankan.ctd
read /usr/share/anthy/dic/adjust.t
read /usr/share/anthy/dic/compound.t
read /usr/share/anthy/dic/extra.t
read /usr/share/anthy/dic/2ch.t
(中略)
set_input_encoding utf8
read /usr/share/anthy/dic/g_fname.t
build_reverse_dict
read_uc /usr/share/anthy/dic/udict
set_dict_encoding utf8
write anthy.wdic
done

となっていた。

Cannaの辞書ファイルである「.ctd」ファイルはEUC-JPで問題ないが、「.t」ファイルのほとんどはUTF-8のはずである。

なのにEUC-JPとして読み込まれているようなのだ。

これではうまくいくはずがない。

「/usr/share/anthy/dic」ディレクトリで以下のコマンド(シェルスクリプト)を実行してみた。

for f in `ls -1 .`; do echo $f : `nkf --guess $f`; done

追記

こんなことをしなくても

nkf --guess *

で良かった…。

追記終わり


すると

2ch.t : CP51932 (LF)
adjust.t : EUC-JP (LF)
anthy_userdic.t : UTF-8 (LF)
base.t : EUC-JP (LF)
bushu.t : UTF-8 (LF)
cc0jinmei.t : UTF-8 (LF)
cc0jisyo.t : UTF-8 (LF)
chimei.t : UTF-8 (LF)
compound.t : EUC-JP (LF)
extra.t : EUC-JP (LF)
(中略)
udict : EUC-JP (LF)
utf8.t : UTF-8 (LF)
x-conv2self-std.t : UTF-8 (LF)
zipcode.t : EUC-JP (LF)

となった。

Anthy用辞書である「.t」ファイルにもEUC-JPのものが結構あるようだ。

そして、意味不明なのが「2ch.t」である。

EUC-JPでもUTF-8でも、Shift-JISでもCP932でもなく、CP51932なのである。

eucJP-ms と CP51932 の違い コードページ932/ウェブリブログ

うっかりEUC(CP51932)とUTF-8化 - 十日日記(2009-04-02)

EUC-JPにWindowsの外字や機種依存文字が入った拡張された文字コードらしい。

これはもともと「/usr/share/anthy/dic」ディレクトリに入っていたはずだが、このままでAnthyは辞書として利用できるのだろうか?

今回は「.ctd」ファイルはそのままにして、「.t」ファイルをUTF-8に変換することにした。

「/usr/share/anthyディレクトリに「dic_utf8」という名前のディレクトリを作って、「/usr/share/anthy/dic」ディレクトリ以下で以下のシェルスクリプトを実行した。

for f in `ls -1 *.t`; do nkf -w $f > ../dic_utf8/`echo $f | sed 's/\.[^\.]*$//'`_utf8.t; done

「dic_utf8」ディレクトリ以下に

2ch_utf8.t
2ch_utf8_utf8.t
adjust_utf8.t
anthy_userdic_utf8.t
base_utf8.t
bushu_utf8.t
cc0jinmei_utf8.t
cc0jisyo_utf8.t
chimei_utf8.t
compound_utf8.t
extra_utf8.t
(中略)
utf8_utf8.t
x-conv2self-std_utf8.t
zipcode_utf8.t

ディレクトリを分けているのだから別にファイル名を変える必要はなかったことに気づいた・・・。

また、元々UTF-8であるファイルは変換しても同じで意味のない変換だ。

元の「dic」ディレクトリを名前を変更して、バックアップしておく。

そしてその元のディレクトリから「.ctd」ファイルと「dic_utf8」ディレクトリにコピーする。

「dic_utf8」ディレクトリを「dic」ファイルにリネーム。

「/etc/anthy/diclist」を名前を変えてバックアップ。

「/usr/share/anthy/dic」ディレクトリで

ls -1 > /etc/anthy/diclist

でファイル名一覧を「etc/anthy/diclist」に書き込む。

diclistに書き込まれると困るので上を実行したあとに、元のディレクトリから「udict」ファイルを「dic」ディレクトリにコピーする。

全部、先にコピーして

ls -1 |grep -v udict > /etc/anthy/diclist

でも大丈夫だと思う。

grep -v udict

でlsコマンドの出力からudictを除外している。

試しにこれで

update-anthy-dics

を実行してみる。

「/etc/anthy/dict.args」ファイルを見てみたがやっぱりおかしい。

どうも基本的にすべてのファイルをEUC-JPとして読み込んでいるようだ。

その上、変換されて存在しないはずの「g_fname.t」ファイルをUTF-8として読み込んでいる。

これだと逆にすべての「.t」ファイルをEUC-JPに変換した方がうまくいきそうだ。

XenialDogには「locate」コマンドは無かったが、「whereis」コマンドがあったので「update-anthy-dics」の場所を調べてみたら、「/usr/sbin」ディレクトリにあった。

以下のリンク先は同じシェルスクリプトだと思う。

/usr/sbin/update-anthy-dics

どうやらいくつかのファイルはあらかじめ指定されているようだ。

「social-ime.ctd」とか「wikipedia.ctd」とか無いファイルが指定されている。

あったら欲しいところだ・・・。

これを書き換えて別のファイル名で保存して実行してみることにした。

変数「CANNADIC」に「/usr/share/anthy/dic」にある「.ctd」ファイルを書く。

「EXTRADIC」や「EXTRADIC_UTF8」はいらないので消す。

「addondics」と書かれている箇所とその下のfor文をutf-8で読み込む場所へ移動する。

「addondics」として読み込むファイル名一覧のうち、「.ctd」はすで読み込んだので、「.t」ファイルだけ読み込むように、「grep '.t'」を追加した。

ちょっと行がずれたところがあって、おかしなところはあるが差分はこんな感じになる。

--- /usr/sbin/update-anthy-dics 2015-03-15 20:37:34.000000000 +0900
+++ /root/apps/update-anthy-dics2   2017-09-28 22:26:13.332746412 +0900
@@ -2,9 +2,7 @@

 set -e

-CANNADIC='gcanna.ctd gcannaf.ctd gtankan.ctd social-ime.ctd wikipedia.ctd'
-EXTRADIC='adjust.t compound.t extra.t'
-EXTRADIC_UTF8='g_fname.t'
+CANNADIC='g_fname.ctd gcanna.ctd gcannaf.ctd gkuten.ctd gt_okuri.ctd gtankan.ctd'

 DICDIR=/var/lib/anthy
 METADICDIR=/usr/share/anthy/dic
@@ -27,7 +25,7 @@


 echo "set_input_encoding eucjp" >> $TMPDICTCONFIG
-for file in $CANNADIC $EXTRADIC
+for file in $CANNADIC
 do
   if [ -f $file ]; then
     echo "read $METADICDIR/$file" >> $TMPDICTCONFIG
@@ -35,20 +33,14 @@
 done


-addondics=$(sort -u $CONFIG| tr '\n' ' '| sed 's/\ $//')
+# start adding utf8 dict
+echo "set_input_encoding utf8" >> $TMPDICTCONFIG
+addondics=$(sort -u $CONFIG|grep '\.t'| tr '\n' ' '| sed 's/\ $//')
 for file in $addondics; do
    if [ -f $file ]; then
        echo "read $METADICDIR/$file" >> $TMPDICTCONFIG
    fi
 done
-
-
-# start adding utf8 dict
-echo "set_input_encoding utf8" >> $TMPDICTCONFIG
-for utf_dict in $EXTRADIC_UTF8
-do
-  echo "read $METADICDIR/$utf_dict" >> $TMPDICTCONFIG
-done
 # end adding utf8 dict

 echo "build_reverse_dict" >> $TMPDICTCONFIG

変更して作ったファイルは実行権をつける。


追記

「.ctd」ファイルはあらかじめ読み込むように「CANNADIC」に書いたので、「/etc/anthy/diclist」に「.t」ファイルだけ書き込むようにすれば、シェルスクリプトの中で「.t」ファイルだけを読み込むようにするコマンドはいらなかった。

ls -1 |grep -v udict |grep -v '\.ctd' > /etc/anthy/diclist

で良いかと思う。

追記終わり


これで実行してみた。

とりあえず、「/etc/anthy/dict.args」ファイルの内容は正しくなった。

再起動して、いくつか語句を入力してみたが、上手くいっている様だ。

2ch.t」ファイルにある「きたー」の変換語句「キタ━━━━━━━━(゜∀゜)━━━━━━━━━!!」も出る。

「しょぼーん」で「(´・ω・`)ショボーン」も出る。

幾つかの顔文字も「ヾ(*´∀`*)ノ」「(*°∀°)=3」などという形で追加された。

国会議員菅直人氏を揶揄した「姦直人」や「韓直人」も出て来てちょっと汚い言葉もおぼえてしまったのが気になる。

若干、余計な学習がされていて変換がおかしくなっている気もする・・・。

しばらく、これで様子を見てみよう。

それにしても、検索した範囲ではこの問題を指摘したものがないようだ。

通常の方法では、「.ctd」ファイルと一部の 「.t」ファイルだけが有効になっているはずだ。

Cannadic改の一部程度の強化でみんな「Anthyの変換精度が上がった」と思っていることになる。

これってバグとか改善点として、修正されるべきものでは無いかな?

「.t」ファイルをすべてEUC-JPにすれば問題ないということなのだろうが…。

ただし、「.ctd」ファイルが2回読み込まれる問題は残る。

「.ctd」ファイルは「/etc/anthy/diclist」には書かないというのが正しい指定方法なのだろう。