卿少納言

卿少納言

JavaScript & Japanese, Python & Polyglot, TypeScript & Translate.
zhihu
github
email
x

hunspell_ja_JP プロジェクトファイルを例に、goldendict の構詞法ルールを浅く分析する

要約:hunspell_ja_JP プロジェクトファイルを例に、goldendict の構詞法ルールを浅く分析します。(まあ、この文章はちょっと硬いので、要約の書き方がわからない 2333

前書き#

この記事では、MrCorn0-0/hunspell_ja_JP: Hunspell morphology dictionary for Japanese used in GoldenDict. (github.com)プロジェクト(以下「原プロジェクト」)の構詞法ファイルを例に、Linux hunspell 公式サイトが提供する man 4 hunspell PDF ファイル(以下「マニュアル」)を参考にして、基本的な構詞法ルールを説明します。

あらかじめ声明しますが、私は知識が乏しく、原プロジェクトの構詞法ファイルの一部ルールを大まかに理解しただけで、間違いがあるかもしれませんので、皆さんは冷静に読んで、友好的に交流していただければと思います。また、原プロジェクトは日本語のみを対象としており、他の言語の構詞法に関する問題についてはお答えできないかもしれませんので、マニュアルを自分で参照してください。

GoldenDict の構詞法機能で使用される技術は主に Hunspell で、これは元々Linux 端のスペルチェックツールです。そのため、GoldenDict とドイツ語系学生に hunspell を紹介するで言及されているものとは若干異なります。GoldenDict の構詞法は、以下で説明する.dic.affの 2 つのファイルのみで、.morph.good.wrong.sugの拡張子を持つファイルは存在しませんが、.dic.affファイルのルールは Hunspell のマニュアルと完全に一致しています。

これら 2 つのファイルの役割について、ドイツ語系学生に hunspell を紹介するの説明を引用します:

  • .dic 辞書ファイルで、内容は紙の辞書にある語頭(lexem)に似ています。
  • .aff 復元ルールセットで、接頭辞や接尾辞を加えた複雑な形を辞書に存在する語頭に変換するための多くのルールが記載されています。

dic ファイルの基本形式#

dic ファイルは比較的シンプルで、以下のような形式です(最初の数字は dic ファイルに収録された語彙の数を示します)

450851





高い/XA

一部の単語には/があり、その後に見た目が文字化けのようなものがありますが、この書き方は単語の品詞をソフトウェアに伝えるためのもので、この単語にはXAという変形ルールがあることを示しています。後で詳しく説明しますが、ここでは dic ファイル内で単語の品詞を指定できることを知っておけば十分です。

また、GoldenDict の dic ファイルに収録された単語は、構詞法機能を有効にした際に最終的な検索結果に影響を与えるため、このファイル内の単語には慎重に対処し、安易に変更しない方が良いでしょう。

aff ファイル#

aff ファイルのルールは非常に複雑で、以下では原プロジェクトで使用されているルールのみを説明します。他の言語や異なるニーズを持つ方は、Linux プロジェクトの man 4 Hunspell マニュアルを自分で参照してください。(重要なことを繰り返しますが、私の英語は四級レベルで、マニュアルを読むのは非常に苦労しました。完全に推測と検証で結論を導き出したもので、マニュアルを読んで理解したわけではありません。皆さんは日本語専門の英語学習者に期待するより、自分で試してみた方が良いでしょう:)

MAP#

まず、最も理解しやすい MAP ルールを例で紹介します:

#スペルの変異
MAP	89
MAP	あア
MAP	かカ
MAP	さサ
MAP	たタ

MAP 89は、これから 89 の MAP ルールがあることを示しています。

MAP ルールは、指定された文字の違いを無視することを簡単に理解できます。例えば、MAP あアは、入力として処理されることを示しています。このルールは原プロジェクトで日本語の擬声語や擬態語の書き方の習慣を処理するために使用されています。例えば、チョコチョコはほとんどの権威ある辞書にはありませんが、ルールに置き換えられたちょこちょこは多くの辞書にあります。

ただし、原プロジェクトの最後の部分には、私がまだ完全に理解していない式があります:

MAP	(ゃ)(ャ)

マニュアルによれば、Use parenthesized groups for character sequences (eg. for composed Unicode characters):(複数の文字で構成された特殊文字を処理するために括弧で囲まれたグループを使用します)とのことなので、これらのルールは拗音に関連しているはずです。チョロチョロの場合、コンピュータはの 3 つの文字を使用して表現しますので、置き換えの際には特別に一緒に置き換える必要があるのでしょうか?しかし、私はまだ理解できていません。

また、以下のようなルールはあまり意味がないように思えます。なぜなら、多くの辞書には腕きゞのような語彙が収録されていないからです。置き換えがあってもなくても実際には問題ありません。本当に踊り字による問題を解決したいのであれば、正規表現を利用する必要があるかもしれません(ふふ、私は自慢しているだけです〜《日本語非辞書形辞典 v3》は前のバージョンで完璧にサポートしています)

MAP	(ゝ)(ヽ)
MAP	(ゞ)(ヾ)

(こうするとわかりづらいかもしれませんが、画像を見ればもっとわかりやすいです。最初の列の記号には小さな勾がついています)

REP#

次に、MAP ルールに非常に似た REP ルールを紹介します:

REP 12
REP かけ  掛け
REP かか  掛か

(原プロジェクトではREP かけ 掛け かけと書かれていますが、間違っている可能性があります……)

MAP と同様に、REP 12はこれから 12 の REP ルールがあることを示していますが、MAP とは異なり、REP かけ 掛けかけは入力で、掛けが置き換えの結果です(MAP の順序とは逆です)。さらに、REP ルールは複数の文字の置き換えを実現できます。(タブでパラメータを区切ることができ、MAP は()を使用する制限があります)

aff の基本形式#

次に、aff ファイルの基本形式について説明します。すべての aff ファイルは以下のように始まるべきです:

SET UTF-8
LANG ja
FLAG long
# https://github.com/MrCorn0-0/hunspell_ja_JP/

SETはファイルのエンコーディングを設定します;

LANGはルールが適用される言語を指定します。他の言語についてはマニュアルを参照してください;

FLAG longは、ルールに名前を付ける際に 2 つの ASCII コードの文字を使用する必要があることを示します。例えば、後で例として使用するルールでは、XA がルール名です。:

SFX	XA	Y	1	
SFX	XA	い	く	い

数字を使って直接ルールに番号を付けたい場合は、マニュアルに従って、FLAG numと書いてから、以下のようなスタイルで名前を付けることができます:

# 形容詞く
SFX	001	Y	1	
SFX	001	い	く	い

将来的に修正を容易にするために、数字で命名する場合は、コメントを通じて説明を加えることが最善です。注意:#は各行の先頭に置く必要があり、その行が説明として扱われます。

ただし、数字で命名すると、1 つの単語に複数のルールを同時に使用する方法に問題が生じます。(言の活用は同じではありませんよね?)

longを使用する場合、ルールを直接書くだけで済みます(長さは固定の 2 文字で、プログラムが認識できます):

高い/XAXB

数字を使用する場合は、英語の半角カンマで区切る必要があります:

高い/001,002

SFX#

aff ファイルの最初の部分の書き方を再度説明する理由は、dic ファイルが複数のルールを指定できることを強調したいからです。ここでの複数のルールは MAP や REP を指すのではなく、次に紹介するカスタム命名をサポートする SFX ルールを指します。

ここで特に強調したいのは「カスタム命名をサポートする」という点です。なぜなら、命名は aff ファイルだけでなく、dic ファイルにも影響を与えるからです。

最初に dic ファイル内で以下のような書き方があることを述べました:

高い/XA

ある意味で、SFX ルールは本当の意味での構詞法です。この機能を通じて接頭辞を構築し、形態素の還元を実現し、日本語の活用の推導と辞書形の還元を実現します。(以下の内容は主にマニュアルのAFFIX FILE OPTIONS FOR AFFIX CREATION章を参考にしています。)

まず、簡単な例を使って説明します:

SFX	XA	Y	1	
SFX	XA	い	く	い

1 行目:XAは私たちがカスタムした接頭辞の名前で、Y は固定のパラメータです(マニュアルに記載されているように、1 はこのXAという名前の接頭辞が含む接頭辞の数です);
2 行目の最初のは、このルールが dic ファイル内ので終わる単語にのみ適用されることを示しています(マニュアルの説明は「接頭辞ルールで単語の先頭から、接尾辞ルールで単語の末尾から文字を削除する」私の理解では、私たちはXAという名前の接頭辞を定義し、その接頭辞の実際の内容はです。この接頭辞はプログラムが処理する部分です)、はこのルールが入力された単語がで終わるときに機能することを示しています。末尾のは、構詞法が実際に機能する前に満たすべき条件を示しています:「構詞法推導の単語の末尾はでなければならない」、満たされない場合、推導結果は表示されません。

具体的な例を挙げると、高くと入力すると、プログラムはに置き換え(ここでのは 2 行目の最初の)、その後 dic ファイル内でで終わる単語に高いがあるかどうかを確認します(ここでので終わるのは 2 行目の 2 番目ののためです)。もしあれば、GoldenDict は直接該当する画面にジャンプします。

簡単だと言えるのは、原プロジェクトのこのルールは実際には以下のようになっています:

#形容詞文く
SFX	XA	Y	2	
SFX	XA	し	く/BaTe	し
SFX	XA	い	く/BaTe	い

これは、日本語の高くがさらに活用できるため、ユーザーが選択する部分が高くば高くてである可能性があることを考慮して、原プロジェクトの作者がこのルールを使用して連続変形を処理するために/を使用しています(少し見覚えがあるかもしれません。dic ファイル内でこの記号は単語がどのルールに使用できるかを示すために使用され、品詞として理解できます)。

注意すべき点は、BaTeは 2 つの独立したルールであり、原作者がカスタムしたもので、原プロジェクトの aff ファイルを参照すれば見つけることができます:

SFX	Ba	Y	1	
SFX	Ba	0	ば	.

高くばのような文法が本当に存在するかどうかはあまり確信が持てませんが、このルールを分離してテストしたところ、確かにこのルールは高くばを入力した際に高いの説明を表示させることがわかりました)

SFX	Te	Y	3	
SFX	Te	0	て	[っいしく]
SFX	Te	0	で	ん
SFX	Te	0	て	.

(重要なのはSFX Te 0 て .この行で、他は日本語の文法の観点からSFX XA し く/BaTe しSFX XA い く/BaTe いとは無関係です。原プロジェクトの作者は個人的な習慣からそれらを一つのカテゴリにまとめたのかもしれません)

ここで.という非常に特殊な文字が登場します。以前述べたように、それらの位置は置き換え後の結果に単語の末尾に含まれるべき文字を示すものであり、その位置のパラメータには「ゼロ条件はドットで示される」というルールがあります。したがって、SFX Te 0 て .の意味は、単語の末尾にあるを直接削除することを示しています。

このルールの作用を理解するのは難しいかもしれませんが、SFX XA い く/BaTe いというルールをSFX Te 0 て .と一緒に考えると理解しやすくなります。原プロジェクトの作者は高くてという入力を処理するためにこのルールを設計しました。(/BaTeを取り除くと、日本語非辞書形辞典と同じになります:選択する要求が高くなるため、原プロジェクトは本当に素晴らしい設計です)

上記の例は二重入れ子に関わるため、理解が難しいかもしれません。疑問がある場合は、マニュアルのTwofold suffix stripping章とAFFIX FILE OPTIONS FOR AFFIX CREATION部分を参照してください。実際、私もあまり理解していません

さらに別の例を挙げます:

SFX	To	Y	1	
SFX	To	0	とも	.

Toはルール名で、0はこのルールが定義された接頭辞ともを削除することを示します。ともは実際に入力された単語の接頭辞を示し、.は置き換え後の結果に対する要求がないことを示します。したがって、このToという名前のルールの作用は、入力ボックスに入力された末尾のともを削除することです。(このルールはともという日本語ルールを学ぶ思考に非常に合致しているため、理解しやすいかもしれません)

また、SFX Te 0 て [っいしく]では[っいしく]が登場します。マニュアルによれば、これは置き換え前の入力文字にのいずれかが含まれていることを示します。

以下には、比較的難しいカスタムルールがいくつかありますが、簡単に紹介します:

[^行]くは正規表現と同じ意味で、ルールは行くを含まないが、いで終わる単語にのみ適用されます。

SFX	5T	く	い/TeTaTrTm	[^行]く
SFX	5T	く	っ/TeTaTrTm	行く

このルールは少し長いですが、特に特殊なものではありません。

SFX	KN	く	け/RUTeTaTrTmf1f2f3f4f5f6m0m1m2m3m4m5m6m7TiTItiSuNgQq1Eba1M1myo	く

このルールは実際には 2 つに分けることができますが、原作者は[]の構文を柔軟に使用しています。

SFX	xU	い	かる/bs	[しじ]い

脇道#

私が構詞法に興味を持ったのは、完全に《日本語非辞書形辞典》プロジェクトで厄介な問題に直面し、他の解決策を探していたからです。そのため、約 1 週間をかけて難解なマニュアルを読みました。大まかにしか理解できませんでしたが、GoldenDict の構詞法 Hunspell 機能の強力さを実感しました言語学は永遠の神です!、人に魚を与えるよりも釣り方を教える方が良いという考えで、自分のまとめを共有し、この機能について皆さんが少しでも理解できることを期待しています。また、皆さんと一緒に GoldenDict の構詞法 Hunspell 機能を改善できることを楽しみにしています。さあ、hunspell_ja_JPに issue や PR を提出しましょう

しかし、もう一つ重要な理由があります。FreeMdict に参加した @epistularumが《日本語非辞書形辞典》の考え方を用いて GoldenDict の構詞法のデモを作成しました(GitHubにあります)。彼とコミュニケーションを取るために、数ヶ月間先延ばしにしていたことを正式に進める決心をしました(英語が苦手で本当に大変です……)

さらに、GoldenDict が以前に言及した日本語の複合動詞の漢字書き問題を簡単に解決できることを予告しておきます:
|500

また、奇妙なことに、GoldenDict の hunspell 機能は複数の結果を返すことができますが、欧路辞典も似たような hunspell 機能を持っていますが、1 つの結果しか返さないようです。マニュアルによれば、特定の機能がモバイルではサポートされない可能性があるBUG: UTF-8 flag type doesn't work on ARM platform.とされていますが、欧路はこの理由でこの技術を採用しないわけではないでしょう……

しかし、いずれにせよ、複数のスペル結果をサポートするべきです。例えば:

雨が降ります。
バスから降ります。

欧路辞典の類似機能#

FreeMdict Forumのフォーラムメンバーと欧路辞典の類似機能について議論しました:

大きな最適化は見つかりませんでしたが、小さな最適化は存在します:

  1. 一部の文型が欠落しています。例えば、言わざるを得ない言わざる(ただし、言わを選択すると結果が出ます)
  2. 口語表現のん、と、ちゃなど

Hunspell 技術は二重入れ子しか解決できないようなので、食べたければのような複雑な文型は解決できないと推測しています(つまり、選択する前に考えておく必要があり、本当にどこでも選択できるわけではありません)

また、私の表現が不十分だったかもしれませんが、欧路には「活用の還元」機能がありますが、その技術は Hunspell とはあまり似ていません:
|500
(多重入れ子、原プロジェクトはおそらく実現できない)

|500
(単独で末尾を選択することができ、原プロジェクトは可能)

日本語の書き方の習慣を無視しています
|500
形容詞の最も単純な変形すらサポートしていません
|500
結果から見ると、欧路は特別にオープンソースではない活用推導ツールを作成した可能性がありますが、ユーザーがカスタマイズすることは許可されていないため、試しに欧路公式にフィードバックを送って、改善を促してみましょう。

参考#

チュートリアル#

オープンソースプロジェクト#

関連#

注:この記事は以下のプラットフォームにバックアップされています:

以 hunspell_ja_JP プロジェクトファイルを例に浅析 goldendict 構詞法ルール - NoHeartPen の文章 - 知乎

以 hunspell_ja_JP プロジェクトファイルを例に浅析 goldendict 構詞法ルール - ソフトウェア経験交流展望 - FreeMdict Forum

読み込み中...
文章は、創作者によって署名され、ブロックチェーンに安全に保存されています。