2023年12月1日金曜日

漢字の部首を調査した

こども漢字辞書 を改善するために、漢字の部首を調査しました。

漢字の部首を取得できるリソースは MJ 文字KanjiVGJoyoKanji の 3つがありますが、厳密なチェックをしたことはありませんでした。 部首は表記の仕方がバラバラなのでチェックをするのが思ったより大変でした。

部首の表記ゆれ

たとえば部首の「食部(しょくぶ)」は 「食 飠」の2 表記があります。 このとき「食→ショク」、「飢→しょくへん」と分かれるはずだと考えるのが KanjiVG です。 他のリストは康熙字典 214 部首を表示しているだけで、どちらが正確かと言えば、これは間違いなく KanjiVG です。 なぜなら康熙字典 214 部首だけだと、食「しょく」なのか飠「しょくへん」なのか判別できないからです。

他にも黒部を示す部首に「黑 黒」のどちらを使うかという問題もあります。 これも 日本の新字体は「黒」のように囲いの内部を「十」としている。なお、表外漢字においては康熙字典に従い「黑」を用いる。 のが正解です。 あと「内」くらいの簡単な漢字でさえ「入部」と「冂部」のどちらもあり得たりして、部首そのものが適当すぎるので困ります。 そんなとき、たいていのネット辞書は文献が不明であまり信頼性がないという問題が起きるのですが、 KanjiVG は JIS漢字字典を利用しているという明確な信頼性があります。 やはり少なくともネットの部首情報よりは KanjiVG のほうが信頼できるというのが現状ではないでしょうか。

とはいえどれくらい他のデータが使えて、どのくらい安定した部首の情報を提供できるか知りたいと思いました。 そこでまずは表記ゆれのある部首漢字を 康熙字典 214 部首にする関数を作りました。 これは思ったより大変で、大量の variant をサポートする必要がありした。

部首の読みの表記ゆれ

部首の漢字に表記ゆれがあるように、部首の読みにも表記ゆれがあります。 たとえば「心 こころ したごころ」のように場所によって部首名が変わるケースがあります。 このへんを真面目にやっている辞書はなさそうなので、 KanjiVG から kvg:position="bottom" などをチェックして、正しい読みを得られるようにできるようにしたいと思いました。

偏旁 を考慮して自動で名前を付けられないかと一瞬思いましたが、例外が多すぎてたぶん無理です。 特にいい方法はないので、康熙字典 214 部首に位置情報を付けたデータを用意し、読みを返す関数を作りました。 実際に作ってみると、やはり「人部」などのコンポーネント情報だけだと、部首名を決めるのは難しいことがわかりました。 たとえば「从」は部首の位置自体は左にあるはずですが、どう見ても「亻 にんべん」ではないので、「ひと」が正しいと思います。 つまり「人 亻」をきちんと分けて登録していないと、分類できないとわかります。 KanjiVG 以外の部首データは不完全ということになります。

しかし KanjiVG もまだまだ精度には課題がありそうで、kvg:element と kvg:original が一致しないことが結構あります。 部首「士」が「土」起源とか、「儿」が「八」起源になってたり、他にも多数の間違いが見受けられるので、kvg:original は明らかに多数のバグがあるように思っています。 ただ扱いは難しくて、正しいかも?と思えるケースもあります。 たとえば「冲」ですが、これは「沖」から派生した漢字で、kvg:element「冫」の意味する氷とは関連がないので、kvg:originalが「水」になっているようです。 英語のほうが日本語より正確というね…。しかしこの登録は紛らわしいだけのような気もします。 とりあえず部首を考えるだけなら kvg:element だけを見るのが安全そうで、kvg:original は見ないほうが良さそうです。 月部と肉部の見分けくらいには使えますが、間違いが多すぎる問題があります。 難しスギィ!

CJK 漢字の部首情報

KanjiVG で変換した結果を見ていて気付いたのですが、Unicode の漢字配列は康熙字典 214 部首の順序で並んでいます。 実際に CJK 統合漢字を漢字配列だけで康熙字典 214 部首に変換している人もいました。 知らなかった…。 という訳で @marmooo/kanji に同様の機能を付けました。 以下のように使えます。
import { Kanji, Unicode1RadicalStrokes, Unicode1Radical } from "@marmooo/kanji";

const radicalStrokes = new Kanji(Unicode1RadicalStrokes);
radicalStrokes.getGrade("学"); // --> 3

const radicals = new Kanji(Unicode1Radical);
radicals.getGrade("学"); // --> 9
ちなみに CJK 統合漢字だけでなく CJK統合漢字拡張A, B も部首順で並んでいるようなので、将来的にはサポートするかも知れません。 ひとまず MJ 文字、KanjiVG、joyoKanji の康熙字典 214 部首の精度を調査すると、以下になりました
$ deno run -A check-radicals.js
check 2136 kanjis:
diff kanjivg: 33
diff joyoKanji: 56
diff mojikiban: 67
KanjiVG は頑張ればもう少し精度を挙げられそうですが、明らかな間違いもいくつかあり、実装も面倒です。 思ったより一致しないなあ…という感はありますが、たいていの漢字は一致するとわかったので、検証した甲斐はありました。 データを眺めてみた感想としても、やはり基本多言語面のほうが正確な印象があります。 一部「つき ふなづき にくづき」に違和感はあり、たとえば「服」は「にくづき」では?と思ったりしますが、「つき」で問題ないようです。 「亀」なども「乙部」として処理するかどうかで辞書の原典がわかりそうです。「黽部」は旧自体「黽」を対象としているため、新字体「亀」はたぶん含まないです。 まあこれは康熙字典に基づく考え方なので、より新しい辞書だと解釈が変わる可能性はあります。 このように基本多言語面のデータは多少の違和感があっても、実際には問題がないものばかりと思っています。 しかしその他のデータは明らかな間違いがいくつかあるので、基本多言語面に合わせるのが良い、が個人的な結論です。 また部首の解釈が今後ねじ曲がったとしても、康熙字典 214 部首の起源は変わらないので、より安定的なデータとも言えます。


真面目な部首データを作った

巷のデータは康熙字典 214 部首しかサポートしていませんが、学校ではより詳細な部首を習います。 「木部 きぶ」のような部首グループは習わず、「きへん」と部首名を習うはずですが、それを実現できるネット辞書はありません。 KanjiVG を使えばまあまあのデータが作れるのはわかりましたが、処理が面倒すぎますし、結局はどこかで手作業が必要になります。 それならいっそのこと CJK 統合漢字すべてにきちんとした部首を付けてやる!と思って、Unicode 1.1 の 20,902 文字へ部首データを付けました

一見大変そうで、実際大変ですが、思っているほど大変ではありません。 部首グループがわかっているので、事前に部首名のパターンをすべて用意しておけば、3パターンくらいから 1パターンを選ぶだけです。 部首名の情報は漢字の形を見ながらコピペしていくだけなので、1000文字くらいはサクッとアノテーションできます。 また偏→旁→繞→冠などの見分けやすい順序でアノテーションすればミスはまったく起きないので、気楽にできます。 vim だと pjpjpjpjpj… と押していくだけでアノテーションできるので、単調作業が大嫌いな私でも 1分で最低 50 個はアノテーションできました。 解釈に困らない漢字なら 2倍はいけます。

真面目にアノテーションしていると、やはりネット情報は色々な間違いらしきものが見つかるのですが、なるべく解釈がシンプルになるように作っています。 「大部」「小部」「尸部」「戈部」あたりが難しかったかな。まずは「構」かどうかを判定するのがなかなか難しいです。 あと「繞」は存在しないものが多いです 「攴部」には「ぼくにょう ぼんにょう」、「凵部」には「かんにょう」、「几部」には「きにょう つくえきにょう」「文部」には「ぶんにょう」という「繞」があると言われますが、実際には存在しません。 「夊部」の「すいにょう すいにゅう」も「処」を「すいにょう すいにゅう」判定にしないと存在しないらしいです。 でも「処」は「几部」なので要するに存在しません。部首はそれくらいいい加減な存在とも言えますね…。 他にも部首名は「てへん」のように確定的なものと、「ほこがまえ」「たすき かほのこ」のように非確定的なものがあるのが、難しいところです。


その他の部首情報

後から気付いたのですが、部首っぽいものを決定できる仕組みとして、漢字構成記述文字 (IDS: Ideographic Description Characters) があることを知りました。 IDS を使って部首を調べられないかなと思ったのですが、今のところ cjkvi-ids くらいしか方法はないみたいです。 cjkvi-ids の IDS 情報は CHISE Projet に依存しているみたいで、これはこれで面倒臭いなあという印象があります。 他にもいくつかリソースはありますが、あまり使い勝手の良いものはなさそう。 cjkvi-ids を使って部首を決定する場合、康熙字典 214 部首でブロックを分けて、IDS と一致させるような処理が必要になります。 だいたいのデータはパースできそうと思いましたが、いくつかのデータはパースできない、または一致しないことがわかっています。 部首以外のコンポーネントを使えるのは面白いのですが、結局は自作で良いのかなと思っています。

他にもIVD (Ideographic Variation Database) はうまく使えば活かせる気もしましたが、 今のところいい方法は浮かんでいません。


0 件のコメント: