……バッドノウハウのカタマリかもしれん。
以下の内容は、仮定と推測に基づいた憶測が混じっており、 事実と異なる、あるいは事実に反する記述である可能性があります。 また、事実誤認や誤解が無い事を保証するものではありません。
本ページの著作権は、私 fenix.ne.jp の G-HAL に属します。 Copyright(C)2007-2011 G-HAL.
Anthy の複数の version/variant を試す場合、
各々の version/variant にて configure する時に、
--prefix オプションでインストール先を別に指定して
make install まで行い、
実行時に
env LD_LIBRARY_PATH=(インストール先)/lib (テストプログラム)
とかしないと、
違う version/variant のライブラリとか辞書とかを使ってしまいます。
# LD_LIBRARY_PATH に指定するパスの記述では、
ホームディレクトリの指定に ~ が使えない場合があるので注意。
また、Anthy の Makefile はアレなので?、
ファイルを書き換えて make しても更新されない場合が有ります。
make clean してから make install すれば、ほぼ確実に更新される筈です。
個人用学習データが1万件くらい貯まってくると、 個人用学習データだけでそこそこ良い変換をする様になってくるので、 システム埋め込みのコーパスの必要性が薄れてきます。 なので、思い切ってシステム埋め込みのコーパスを全て削除するパッチ。
悪い方の副作用として、 個人用学習データがまだ十分に貯まっていない時にこれを使うと、 変換結果が若干悪くなるかもしれません。 また、まだ学習されていない様な内容の変換を行った時に、 変換結果が悪くなる場合があります。
良い方の副作用として、 変換の候補がコーパスの文体や癖の影響を受けなくなります。
このパッチを使うと、学習量の上限が、 取り敢えず1年〜2年くらい学習を続けても 上限超過で削除されたりしない程度の量になります。
副作用として、 辞書(last-record1_default)が肥大化し、 初動の変換に必要な時間が増えます (メモリ上に展開されたキャッシュにヒットすれば速いのですが)。 半年間学習し続けると、 とても「あの軽快だった Anthy」とは思えない程、遅くなります。
patch無印と alt-cannadic の誤字修正パッチをマージした物です。
誤学習をしない様にする為と、個人用学習データの肥大化を防ぐ為、 あとついでに無駄なディスク書き込みを減らす為、 変換途中のまだ間違っている変換内容を学習しない様にしました。
また、コマンドラインツール anthy-agent に、 辞書のフラッシュ (last-record2_default から last-record1_default への移行) 機能を追加しました。
% anthy-agent --update-base-record --do-nothing
とする事で、フラッシュします。
原作版では変換途中に OCHAIRE, CAND_HISTORY, INDEPPAIR の学習を更新していますが、 学習データーベースを変換バッファに使っているだけで、 実際の学習は、されていない模様。
個人用学習データの肥大化を防ぐ為と、不要な学習を行わない様にする為、 特定の記号を含む項目を OCHAIRE 学習しない様にしました。
具体的には、句読点や括弧類や記号の文節区切りを学習しません。 日本語の文書ならば句読点や括弧類や記号は必ず文節区切りになるので、 学習する必要無いし。
その類の文節区切りも学習させたい場合は、 src-ordering/exception_word_list.c の exception_word_list_cstr[] から、 学習させたい物を消して下さい。
また、学習データをとことん集積する為に、 OCHAIREの学習削除の学習を行わない様にしました。 但しこれには副作用があって、 文節を切る様に学習させた内容に対して、 文節を切らずに1文節で変換する様に学習させる事ができなくなります (この問題は、patch12 で解消…… と言うよりも、patch12 になるまで問題に気付かなかった)。
オリジナル版の Anthy に、 不正なメモリアクセスを行うバグを3件見つけたので修正しました。
OSDN のプロジェクト/トラッカー: Anthy/バグの、 ID:12379「src-util/dic-tool.c の英文タイプミス」 (IWAI Masaharu 氏、2008-04-21 07:16) パッチをマージ。
学習結果を最後に利用した日付と利用した回数でスコアリングし、 学習結果の削除を行う際にスコアリングの低い物から削除する様に変更しました。 これにより、 最近の変換だけでなく、 利用頻度の高い変換の学習も保持される様になります。 スコアリングは last-record1_* のファイルサイズが大きくなった場合のみ 行う様にしてあるので、普段の負荷は変わらない筈です。
CAND_HISTORY の学習と削除は、 過去8種類の同読みの変換からスコアリングで順位を決める様に変更しました。 これにより、 利用頻度が2番目以降の変換も候補の2〜8番目に残る様になりました。
補足: 基本的な方針として、 変換結果は時間不変である(同じ条件ならば、いつも同じ結果になる) べき、だと考えています。 しかしながら、スコアリングに相対時刻を用いると、 時間不変では無くなってしまいます (処理を行った時刻によって結果が変わってしまう)が、 本パッチでスコアリングに相対時刻を用いるトリガは、 CAND_HISTORY の場合は第1候補を変更した時のみ、 学習全般の枝刈りの場合は変換確定(学習データ更新)した時に 古い物に対してのみ、 であり、 (CAND_HISTORY の場合は) 利用者にも変化が起こる事が明示的かつ合理的に認識・判断できる (付け加えて、第1候補だけはスコアリングを行わずに、 利用者が指定した物を第1候補としている)、 (学習全般の枝刈りの場合は) どのみち状態の変化を行わなければならないし 枝刈りで残す量がある程度大きければスコアリングの影響は小さい、 ので、 不変性を維持しなくても問題にはならない、と考えたからです。
# 原作の anthy では、 学習結果の削除はデータベースの後方にある物から削除するので、 利用頻度が高くても、 暫く使っていなかった変換結果の学習は消される事があります。 また、 CAND_HISTORY と EXPANDPAIR の同読みの学習は、 過去8回の変換で使った物のみ、となっているので、 学習が1種類しか残らずに 利用頻度が2番目やそれ以降の物が候補に出てこない事があります。
なお、EXPANDPAIR の学習結果のスコアリングは、 初回学習時以降、全くと言っていいほど変わりません。 これは OCHAIRE 学習結果が EXPANDPAIR の学習結果よりも優先して使われ、 その結果 EXPANDPAIR の学習結果が全く利用されていない為です。
注意:
patch4では、学習結果のデータ形式が変更になっています。 原作の anthy 及び patch〜patch3 までで学習した内容は patch4 でもそのまま利用できますが、 patch4 以降で学習した内容は原作及び patch〜patch3 では利用できません。
オリジナル版の Anthy に、
メモリを明示的に初期化せずに使っている部分を
また見つけたので修正しました。
C99 では、 .bss な静的変数の初期値は 0(+0.0) と定義されているらしい、
ので、仕様上は問題無い、
……実際の実装の話になると問題になるケースも有る。
学習データの読み込みバッファを多めに確保する事で メモリ割当サイズ変更の回数を減らし、高速化しました。
副作用として、 無駄なメモリが増える、 valgrind等の不正なメモリアクセスの検出ツールでの検査が甘くなる、 があります。
プロファイラで追跡したり実際に計測した所では2割程度速くなりましたが、 実感としては、あまり変わっていない様に思えます。
注意:個人用学習データの形式が(以下略)
オリジナルの Anthy だと、文節の切り直しを行なって再変換した場合、 文全体の再評価を行う為、注目文節より左側の変換結果が変わる事があります。 このパッチでは、 注目文節より左側は再変換を行っても再評価しない様に、変更します。
注意:個人用学習データの形式が(以下略)
個人用学習データのファイルのパーミッションを、 group と other が読めない物に変更しました。
個人用学習データをバイナリ形式に変換して、 読み込みを約7割高速化しました ……本当か?測定結果間違ってないか?。
バイナリ形式の学習データのファイル名は、 「(学習データの基本ファイル名).bin」 です。
バイナリ形式の学習データのデータ形式は、 アーキテクチャや OS に非依存の形式にしてあります。 i386系と amd64系での共用は動作確認済。 設計上は、 sparc だろうが alpha だろうが MIPS だろうが PowerPC だろうが ARM だろうが m68k だろうが SH だろうが M32 だろうが、 何でも共用できる筈です(実機が無い為、未確認)。
学習データの保存を行う際には、 従来通りのテキスト形式と、新規に追加したバイナリ形式の、 両方で保存します (テキスト形式でも保存しておかないと、 テキストエディタを使った誤学習の修正作業ができないし、 学習の追加/変更/削除の比較ができないから。 加えて、何らかの再利用をする場合は、テキスト形式の方が有利だから)。
従来通り、 テキスト形式の学習データが変更された場合のみ、 学習データの再読み込みを行います。 バイナリ形式の学習データのみが変更された場合、 再読み込みは行いません。
学習データの再読み込みを行う際は、 バイナリ形式のデータがあればそれを読み込みます。 無い場合は従来通りテキスト形式から読み込みます。
学習データを手作業で修正する場合、 テキスト形式の学習データを編集すると共に、 バイナリ形式の学習データを削除して下さい。
注意1:個人用学習データの形式が(以下略)
注意2:本パッチ中の src-diclib/strlcpy.c と src-diclib/strlcat.c は BSDライセンスになります。
オリジナル版の Anthy のデータベース処理にバグ?を見つけたので 修正してみました (do_select_row() から trie_insert() を呼び出した時に PROTECT フラグを破壊した後に PROTECTフラグを見ているので、 意味が無かった)。 ただ、修正しても意味は無さそうです。
オリジナルの Anthy に、 複数のアプリケーションで同時にかな漢字変換を行った場合に 学習データが過去に戻るバグ?仕様?を見つけたので、 それを発症しにくくする修正をしました。 但しあくまで発症しにくくしただけで完全な治療はしていません。 ロックの仕様を変更して大幅改変しないと根治できないので治しません。
オリジナル版の Anthy に、 last-record2_* の構文チェックが甘い部分が有ったので修正してみました。
学習のセクションの識別子の処理方法を文字列から enum に変更し、 セクション毎のヒント情報を持てる様にした。
メモリ先行確保量のヒント情報を持つ事で、数%〜1割程度の高速化。
個人の学習データの保管や作業ファイルを置くディレクトリを、 環境変数 ANTHY_CONFDIR で変更可能にした。 但し、指定ディレクトリの正当性の検査は行っていませんので、 注意して下さい。 また、ANTHY_CONFDIR で指定するディレクトリは、 ${HOME} 下からの相対ディレクトリとなります。
ついでに、各種環境設定の一部を集約して変更可能にした。 但し、そうそう頻繁に変更する物でもなく、また面倒なので、 動的変更用の API を作る気はありません。 変更したい場合は src-worddic/settings.c を変更して、 anthy ライブラリの再構築を行なって下さい。 anthy ライブラリの再構築を行わずに動的に変更したい場合、 src-worddic/settings.c を変更して 単独で shared library形式でコンパイルし、 LD_PRELOAD してください (patch13 にて ${HOME}/.anthy/conf で指定できるように変更しました。 再構築の必要はありません)。
さらについでに勢いで、 オリジナルの Anthy でキャストのウォーニングが大量に出るのを、 全部叩き潰した。
Anthy の置き換えとなる かな漢字変換 の開発が 次世代アーキテクチャの計算機/OSの 一般化に間に合わなかった場合の保険として、 int型が 64bit なシステムだと メモリ破壊かスタック破壊を起こす可能性があるバグ?仕様?を修正。 (int型を数字に変換した時の最大文字数が 10文字固定になっていた) (2286年11月21日以降か、 変換候補数/文節数/候補の頻度値のどれかが 9999999999個を越えた場合か、 変換候補数/文節数/候補の頻度値のどれかが -999999999個より小さくなった場合に、 発症する)
注意1:個人用学習データの形式が(以下略)
注意2:本パッチ中の src-diclib/strlcpy.c と src-diclib/strlcat.c は BSDライセンスになります。
Anthy の置き換えとなる かな漢字変換 の開発が 2038年までに間に合わなかった場合の保険として、 2038年問題対応。 (time_t と int が相互変換可能である前提になっていた) 但し、2038年問題が発症しても、 候補の並び順の学習結果が破壊され、 並び順が出鱈目になる程度だと思われます。
2038年問題対応と言っても、 OS側が2038年問題非対応の場合は効果がありません。
メモリのアラインメントを間違える可能性の有るバグ?仕様?
正しいアラインメントよりも整数倍大きい値に間違えるだけなので、問題無し。
を、一応修正。
無駄そうな部分を調整してみたけれど、速度は変わらなかった。
注意1:
patch9では、再度、学習結果のデータ形式が変更になっています。 原作の anthy 及び patch〜patch8 までで学習した内容は patch9 でもそのまま利用できますが、 patch9 で学習した内容は原作及び patch〜patch8 では利用できません。
注意2:本パッチ中の src-diclib/strlcpy.c と src-diclib/strlcat.c は BSDライセンスになります。
変換候補の学習(CAND_HISTORY)と予測変換の学習(PREDICTION)を統合する事で、 個人用学習データの大きさを1割程度削減しました。 それにより読み込みが1割程度速くなった筈ですが、 体感では変わった気がしません。
オリジナルの Anthy もしくは patch9 までの Anthy から 本 patch10 に移行する場合、 予測変換の学習データを従来の形式から新しい形式に変換する必要があります。
% rm ~/.anthy/last-record1_*.bin % anthy-agent --do-nothing --update-base-record % rm ~/.anthy/last-record1_*.bin % anthy-agent --do-nothing --update-base-record
とする事で、変換が行われます (1回目の anthy-agent にて last-record2_* を last-record1_* へマージ。 2回目の anthy-agent にて テキスト形式から読み込む事で PREDICTION を CAND_HISTORY へ統合)。
注意1:
予測変換を利用している人の場合、 予測変換の変換の傾向が変わる可能性があります。 予測変換を利用していない人の場合、デメリットはありません。
注意2:
本 patch10 適用後に学習した予測変換の学習データは patch9 までの Anthy では利用できなくなり、 予測変換の学習データが全く無い状態と同じになります。
注意3:本パッチ中の src-diclib/strlcpy.c と src-diclib/strlcat.c は BSDライセンスになります。
オリジナルの Anthy に、 郵便番号辞書を使う変換をした時にメモリリークしているのを見つけたので 修正。
オリジナルの Anthy に、 libc 側で NULLポインタの検査をしている事を前提としている箇所 (qsort() の base に NULL 突っ込んでる)を1つ見つけたので修正。
数値や記号やひらがなやカタカナだけの文節は、
学習しているとキリが無さそうなので、
学習しない様に変更。
「2割」で1文節にして変換すると、学習します。
「2」+「割」と数値だけの文節にして変換すると、学習しません。
この方法は大量の文を入力する時に面倒なので、patch12 以降は廃止しました。
patch11 のみで有効な方法です。
似た様な内容を変換した時に、あるいは全く同じ内容を変換した時に、 頻度情報も同値で、 学習状況もほとんど同じで、 デバッガで追跡してみると候補の最終評価値まで全く同じなのに、 候補の並び順が変わっている事が有って気になっていた (急いで文書を打たないといけない時に、 さっき変換した時と違う物が出てきて、気を取られて困った)。
それから、数値を変換した時の候補の並び順が、 学習していないにも関わらず、 入力した数値によって違っている事が気になっていた。
例: 学習や単語登録がされていない場合、 「123」を変換すると
となるが、「1234」だと
になるし、「1」だと
になる。
調べてみたら、 候補の並び順のソートにクイックソートを使っているので 計算機のアーキテクチャやら OS やら接頭辞/接尾辞の有無やら 変換する数値やら運やらによって並び順が変わる、 数値だけの文節に対して ひらがなフラグとカタカナフラグの 両方が立っていて処理が変になっている、 「1」〜「50」はシステム辞書での評価がそう設定してあるだけだった、 だった。
上記の例の様に、数値や記号を変換する時や、 同じ評価値を持つ候補がある時に、 候補の並び順が安定する(毎回同じになる)様に修正した。
システム辞書もしくはユーザ辞書で単語登録されていない限り、 下記の順で固定します。 変更したい場合は、src-worddic/settings.c の .extra_flag の CEF_TUNESCORE_SIGN にて設定して下さい (patch12以降では ${HOME}/.anthy/conf にて指定)。
「1」〜「50」はシステム辞書での単語登録で優先順位が指定されている為、 プログラム側で順序を変えるのは不可能です ( alt-cannadic/gcannaf.ctd で、 ASCII数字(#NN*22) > JIS X 0208 数字(#NN*21) > 漢数字(#NN*20)、 で登録されている。 システム辞書の頻度値は ユーザ辞書の頻度値の10倍くらいの強さを持っているらしい) 。 ユーザ辞書に「0」〜「50」(読み、書き方、ともに、いわゆる全角)を 頻度 300 くらいで単語登録する事で、並び順を優先させる事ができます。 なお、 private_words_default は1行に1項目しか記述できないので注意。
……パッチが 11 まで来るとは思わなかった。 4 とかせいぜい 6 で終わると思っていたのに。
オリジナルの Anthy では、 学習の蓄積や、学習結果の変換への反映に関しては、 かなり軽視している(それともコーパス導入で不要になったと考えた?) 傾向がある様な気がします(根拠無し)。
本 patch12/patch13 シリーズでは、 その学習に関して改善あるいは強化してみようと試みるものです。
但し、 理論的裏付けをしないままに直感と思い付きでやった為、 何が起こるかは判りません。
追加機能や変更した機能のパラメータチューニングに関しては、 sample/conf を参照されたし。
オリジナルの Anthy では、 文節区切りには OCHAIRE学習のみ反映し、 優先順位は 「システム辞書から生成した文節区切りと OCHAIRE から生成した文節区切りでは OCHAIRE が優先、 OCHAIRE同士ならシステム辞書の設定値で判定、 非OCHAIRE同士もシステム辞書の設定値で判定」 となっています。 また、 文節の候補の並び順には CAND_HISTORY学習のみ反映し、 候補の優先順位は CAND_HISTORYで学習した通り、となっています。
この方法の場合、 文節の切り方に対して システム辞書(システム持ちのコーパスを含む)の内容を反映する という点では安定しますが、 単文節変換での区切り位置の学習(区切りが無いという学習)が 全くできなかったり(注意:patch3 にて、 頻繁に OCHAIRE学習データを消すのを避ける様にした結果、そうなった)、 CAND_HISTORY では学習しているものの OCHAIRE が未学習の場合に 学習結果が全く反映されなかったり、 します。 また、 同読みの変換を行った場合には必ず同じ字に変換される代わりに、 同読み異字の変換を行おうとした場合に、 前後の文節によって候補が異なる事を特定できる場合でも、 同じ字に変換されてしまいます。
この為、 例えば「です」とか「ます」とか「する」とか「この」とか「また」とか、 個人的によく使う単語は反映されませんし、 一度でも「はままつ」を「浜|待つ」と変換して OCHAIRE学習すると、 二度と「浜松」が第1候補にはならなくなります。 また、 「かなかんじへんかん」を「かな|漢字|変換」と学習した後に、 「かんじ」を「感じ」と学習すると、 「かなかんじへんかん」が「かな|感じ|変換」と変換されてしまいます。 注意1: ここでの「浜|待つ」と「浜松」の例は、 変換結果が望んだ物では無い事は問題ではなく (たった1文節入力しただけなのに、 計算機が人間が何を変換しようとしているかを想像するなんて、 できるわけが無いのですから)、 望んでいない変換から望んでいる変換に 学習しなおす事ができない点が問題です。 注意2: patch3 摘要前(オリジナルどおりの Anthy)ならば、 「はままつ」を「浜松」と変換確定した時点で 「は|ままつ」 「はま|まつ」 「は|ま|まつ」 「はまま|つ」 「は|まま|つ」 「はま|ま|つ」 「は|ま|ま|つ」 の(たぶん)全パターンの学習データを削除するので 「浜松」が第1候補になりますが、 代償?として「浜|待つ」の学習データが完全に消滅します {つまるところ、 patch3を摘要しない場合(オリジナルどおりの Anthy の場合)、 普段とちょっとでも文節の切り位置を違えて変換確定すると、 学習データが次々と削除され、 学習が蓄積されにくくなります(経験則)}。
本パッチは、上記の点の改善を図った物です。 但し、理論的裏付けをしないままに直感と思い付きでやった為、 何が起こるかは判りません。
●元の文 ・8文節の文章の例。 文節1 | 文節2 | 文節3 | 文節4 | 文節5 | 文節6 | 文節7 | 文節8 ●お茶入れの学習 ・オリジナルおよび patch11 まで:1文節〜4文節まで、全18通り学習する。 ・patch12パターン10:1文節〜3文節まで、全13通り学習する。 お茶入れ1文節1 | お茶入れ1文節2 | お茶入れ1文節3 | お茶入れ1文節4 お茶入れ2文節1 | お茶入れ2文節2 | お茶入れ2文節3 | お茶入れ2文節4 お茶入れ3文節1 | お茶入れ3文節2 | お茶入れ3文節3 | お茶入れ3文節4 お茶入れ4文節1 | お茶入れ4文節2 | お茶入れ4文節3 | お茶入れ4文節4 お茶入れ5文節1 | お茶入れ5文節2 | お茶入れ5文節3 | お茶入れ5文節4 お茶入れ1文節1 | お茶入れ1文節2 | お茶入れ1文節3 お茶入れ2文節1 | お茶入れ2文節2 | お茶入れ2文節3 お茶入れ3文節1 | お茶入れ3文節2 | お茶入れ3文節3 お茶入れ4文節1 | お茶入れ4文節2 | お茶入れ4文節3 お茶入れ5文節1 | お茶入れ5文節2 | お茶入れ5文節3 お茶入れ6文節1 | お茶入れ6文節2 | お茶入れ6文節3 お茶入れ1文節1 | お茶入れ1文節2 お茶入れ2文節1 | お茶入れ2文節2 お茶入れ3文節1 | お茶入れ3文節2 お茶入れ4文節1 | お茶入れ4文節2 お茶入れ5文節1 | お茶入れ5文節2 お茶入れ6文節1 | お茶入れ6文節2 お茶入れ7文節1 | お茶入れ7文節2 ●お茶入れの利用 ・オリジナルおよび patch11 まで:できるだけ長い物を、連結して使用する。 お茶入れ1文節1 | お茶入れ1文節2 | お茶入れ1文節3 | お茶入れ1文節4 | | お茶入れ5文節1 | お茶入れ5文節2 | お茶入れ5文節3 | お茶入れ5文節4 → 問題点:連結部分で間違える事が有る(原作者氏も気付いてはいたらしい)。 ・patch12パターン10:できるだけ長い物を、段々にして、たすき掛け?する。 お茶入れ1文節1 | お茶入れ1文節2 | お茶入れ1文節3 お茶入れ2文節1 | お茶入れ2文節2 | お茶入れ2文節3 お茶入れ3文節1 | お茶入れ3文節2 | お茶入れ3文節3 お茶入れ4文節1 | お茶入れ4文節2 | お茶入れ4文節3 お茶入れ5文節1 | お茶入れ5文節2 | お茶入れ5文節3 お茶入れ6文節1 | お茶入れ6文節2 | お茶入れ6文節3 → 処理量が増えるけれども、連結部分で間違える事が無い。 ●連結部分の間違えとは? 「頻度|情報|や|コーパス|の」 を学習すると 「頻度情報やらコーパスやら」 と変換したい時に 「頻度|情報|や|等|コーパス|やら」 などと変換してしまう。「頻度|情報|や」の学習を元に、「や」の後ろで切ってしまう。まあ、一度学習させれば間違えなくなるのだけれど。 patch12パターン10やpatch13では、「頻度|情報|や」の学習の「や」に関しては、「や」の左側での文節区切りは行うが、「や」の右側での文節区切りを行わない。OCHAIRE内において、 2文節が件数 57% 容量 48%、 3文節が件数 30% 容量 33%、 4文節が件数 13% 容量 19%。 4文節を削除する事で学習全体に対して容量 13%縮小(読み込みが高速化)。
パターン10に対して、 付属語の調整を加えた物。
オリジナルの Anthy の depgraph/Makefile.am の手抜き箇所を修正。 Sun,30 Nov,2008版にて、patch8 までバックポート。
オリジナルの Anthy では、 depgraph や辞書の頻度情報にミスやら何やらがあっても、 コーパスの量でカバーしていましたが、 オリジナルの Anthy付属のコーパスが自分の文体に合っていない事と 個人用の学習データがだいぶ貯まった事を受けて コーパスを消した為、 その手が使えなくなりました。 ……個人用の学習データって、出現確率や遷移確率の計算には使わないから、 コーパスの代わりにはならないのだよね……。 ……。 なので取り急ぎ、 vagus氏の depgraph修正パッチ2008年10月18日版、 nosuke氏の depgraph修正パッチ2007年11月24日版 (元のままだと完全に出なくなるので、弱くする程度に変更)、 をマージし、若干の調整を加えました (出る筈の単語が出なくなると嫌なので、 評価を下げるだけで削除はしていない)。
↑の depgraph 更新と関連して、 付属語つき文節の場合、 付属語が1つの場合は文節の評価を1%下げ、 付属語が2つの場合は文節の評価を12%下げ、 それ以降、 付属語が1つ増える毎に評価を1%ずつ追加して下げる様に変更してみた。 付属語の遷移回数ではありません。 また、付属語の文字数でもありません。 なお、この計算において、 スコアを率で下げる (1%基準なら、元が 500 なら 495 に、800 なら 792 に下がる)方が良いのか、 スコアの点数を下げる (5点基準なら、元が 500 なら 495 に、800 なら 795 に下がる)方が良いのか、 迷っている所です。
例: (地名)+(@名詞のあと)+「として」+「の」+「か」+「と」+(Sy@) の場合、付属語が4つで、評価を14%下げ。
備考: 付属語の遷移グラフの weak は、「.」と「:」の区別はありません。 また、遷移中の何処か1つにでも付いていると、文節評価が90%下がります。 weak が付いている数は関係無く、90%だけ下がります。 オリジナルの Anthy からずっと、そのまま変えていません (anthy-8?00 のコーパス導入で変えたらしい)。
例: (団体名)+(.@名詞のあと)+(.@さ(名詞化))+「さ」+(:Sr@) の場合、weak が3つ付いていますが、数に関係無く 90%だけ下がります。
備考:
% env ANTHY_ENABLE_DEBUG_PRINT=y ANTHY_SPLITTER_PRINT=wmlic anthy-agent --anonymous senndaitosennga(space) PRINT_CONTEXTすると、一応、どんな付属語が付いているのか見えます。 でも、
*meta word type=single(0-8):score=1000:seg_class=名詞+格助詞:suffix:num:can_use=1* .せん.だい-とせんが(POS=16,COS=2,SCOS=93,CC=0,CT=0,flags=4) 名詞+格助詞 千台とせんが:(,1000,Nk,2804,263,4)0 |せんだいとせんが せんだいとせんが(仙台とせんが:(,1000,Nk,5609,799,4)17,529 ,先代とせんが:(,1000,Nk,5609,799,4)16,652 ,川内とせんが:(,1000,Nk,5609,799,4)15,425 ,千代とせんが:(,1000,Nk,5609,799,4)10,868 ,籤題とせんが:(,1000,Nk,5609,799,4)4,383 ,千台とせんが:(,1000,Nk,2804,279,4)3,823 ,千大とせんが:(,1000,Nk,2804,279,4)3,779 ,千題とせんが:(,1000,Nk,2804,279,4)3,779 ,仟台とせんが:(,1000,Nk,2804,279,4)3,648 ,仟代とせんが:(,1000,Nk,2804,279,4)3,604 ,仟大とせんが:(,1000,Nk,2804,279,4)3,604 ,仟題とせんが:(,1000,Nk,2804,279,4)3,604 ,せんだいとせんが:(N,0,-)2 ,センダイトセンが:(g,0,-)2 ,センダイトセンガ:(N,0,-)1 ,):とかいう表示なので、depgraph の何を使ったのか、 さっぱり判らなかったりします。 括弧周辺の数値と文字は、
変換候補:(その文節の由来,基本スコア,種別と品詞,文節構造のスコア,同読み同種類の自立語の最高スコア,付属語の数)総合スコアです。 自立語の最高スコア、付属語の数、の表示は、私が追加した物なので、 オリジナルの Anthy にはありません。 スコアの計算は、
オリジナルの Anthy、patch12pattern11まで: (自立語のスコア) = (システム辞書の頻度値で順位を付けた時に最下位から数えて何番目かを 800で正規化した値) patch12pattern12〜patch13: (自立語のスコア) = (システム辞書の頻度値) オリジナルの Anthy: (文節構造のスコア) = 65536 × { 0.1 + (コーパスから得た確率情報)} × (付属語の weak があれば 0.1) × (SUFFIX があれば 0.5) patch12〜13:コーパスから情報を得られた場合: オリジナルと同じ patch12pattern11:コーパスから情報を得られなかった場合: (文節構造のスコア) = 65536 × { 0.1 − 0.001 × (付属語の数)− (付属語が2個以上あれば 0.01) } × (付属語の weak があれば 0.1) × (SUFFIX があれば 0.5) patch12pattern12〜patch13: オリジナルと同じ オリジナルの Anthy、patch12pattern11まで: (総合スコア) = (文節構造のスコア) × (自立語のスコア) patch12pattern12〜patch13: (総合スコア) = (文節構造のスコア) × (自立語のスコア) − 100 × (付属語の数)− (付属語が2個以上あれば 500)で、総合スコアの高い順に、変換候補が並びます。
src-worddic/settings.c の .depgraph
${HOME}/.anthy/conf に書く値で、
付属語による文節構造のスコアを変更できます。
ここの値を調整する事で、
付属語付きの単語が上位になるか下位になるか、調節できます。
オジリナルの Anthy からずっとあった、 テキスト形式の入力ファイルに空行があると、 そこでファイルからの読み込みを強制終了してしまうバグ修正。 Sun,30 Nov,2008版にて、patch8 までバックポート。
オリジナルの Anthy では、 変換候補が見つからなかった時にカタカナ語と推定して かなりの高得点(OCHAIREに次ぐ高得点)を付けていたが、 この機能を削除。
「(接頭語)+(自立語)+(接尾語)」の評価を変更。 オリジナルの Anthy では、 (自立語)の評価がそのまま文節の評価となり、1文節扱いだった。 (接頭語),(自立語),(接尾語)の各評価の合計を文節の評価とし、 2文節扱いする様にした。
パターン11に対して、 自立語のスコアをシステム辞書の頻度値そのままに変更してみた。
CAND_HISTORY の上限が8件だと溢れたので、12件に増やしてみた。
オリジナルの Anthy の mkworddic/Makefile.am の手抜き箇所を修正。 Sun,30 Nov,2008版にて、patch8 までバックポート。
オリジナルの Anthy の src-diclib/xchar.c にて、 文字コードを間違えているバグがあったので修正。 Sun,30 Nov,2008版にて、patch8 までバックポート。
vagus氏や内海氏の、 頻度値をカスタマイズした辞書を使うと、 変換候補の並び順や文節の区切り方の傾向に大きな違いが出ると思う。 良い傾向か悪い傾向かは判りませんが。
オリジナルの Anthy のバグ未満の問題3件 { 数字の変換結果の自動生成にこけた時 (例えば郵便番号辞書に3桁の郵便番号を登録して変換した時)に SIGSEGV する箇所が1件。 何らかのトラブル (例えば郵便番号辞書に3桁の郵便番号を登録して変換した時)で 変換前もしくは変換後の文字列を NULL もしくは文字列長 0 で処理してしまった時に SIGSEGV する箇所が1件。 0000??? の郵便番号を変換できない問題が1件、但し実在しない。 } と、 3桁の郵便番号を変換できないバグ?と、 変換後の文字列が存在しなかった時 (INDEPPAIR で強制入れ替え作業中に付属語遷移で拒否されて 変換候補作成しなかった時。 郵便番号辞書に3桁の郵便番号を登録して変換した時。) に SIGSEGV するバグが2件、 anthy-agent にて不正なメモリアクセスを行うバグが1件、 修正。
INDEPPAIR(最後に使用した自立語の学習)にて、 OCHAIRE 学習由来の変換を行った場合でも、 学習できる様に改造してみた (オリジナルの Anthy では実装されていなかった。 コメントに、なおした方がいい、みたいな事は書いてあった)。
「いちおく」の件の解析結果の解説:
Tue,02 Dec,2008の2 版にて、
手元で確認した限りでは、「いちおく」の変換で落ちるバグが治った模様。
あるいは、誰も気付いていなかった別のバグなのかも。
原因は、 INDEPPAIR 学習にて得た結果が付属語遷移の関係で存在しない場合に、 自動生成した変換候補(ひらがな語?やカタカナ語など)に対して (出自辞書項目番号に自動生成を意味するフラグ -1 を設定してあるのに、 それを無視して) 項目番号 -1 で辞書バッファ(実体は配列変数)を探しに行ってしまい、 dic_ents[-1] で落ちていました。
但し、 複合原因で他にも原因が有るならば、治りきっていないかもしれません。
例) 前提: INDEPPAIR 学習に、「無限大」→「∞」の学習がある 発症する例: 「むげんだいが」を変換すると、落ちる。 解析: (1) 「むげんだいが」に対して、以下の候補一覧を生成する。 (a)(システム辞書由来の単語)(システム辞書の項目番号i)「無限大 + が」 (b)(自動生成した単語)(システム辞書の項目番号 -1)「むげんだいが」 (c)(自動生成した単語)(システム辞書の項目番号 -1)「ムゲンダイが」 (d)(自動生成した単語)(システム辞書の項目番号 -1)「ムゲンダイガ」 ここで、 + は、自立語と付属語の境界を表す。 また、(システム辞書の項目番号)が -1 の物は、 単語の由来がシステム辞書ではない事を表すフラグ。 「∞ + が」と言う候補は、付属語遷移にて定義されていないので、存在しない。 (2) 第1候補の自立語の「無限大」に関して INDEPPAIR に該当が有るので、 「∞」のスコアを上げる為に、候補一覧の検索を行う。 (3) 候補一覧の (a) は第1候補なので、INDEPPAIR の検索はしない。 (4) 候補一覧の (b) の自立語部分が「∞」に一致するか検査する為に、 システム辞書の項目番号 -1 を検索する。 (5) システム辞書のバッファ(実体は配列変数)の -1 の項目、 dic_ents[-1] にアクセスする。 → 落ちる。 注意: メモリ配置によっては、dic_ents[-1] が前なり後ろなりの候補の辞書バッファなり なんなり、何かの変数と重なる場合があり、その場合は落ちない。 計算機のアーキテクチャや OS や コンパイラの種類やバージョンやコンパイルオプションや メモリ配置の環境設定などによって、 この辺のメモリ配置が変わる為、発症したりしなかったりする。 発症しない例: 「むげんだい」を変換すると、落ちない。 解析: (1) 「むげんだい」に対して、以下の候補一覧を生成する。 (a)(システム辞書由来の単語)(システム辞書の項目番号i)「無限大」 (b)(システム辞書由来の単語)(システム辞書の項目番号j)「∞」 (c)(自動生成した単語)(システム辞書の項目番号 -1)「むげんだい」 (d)(自動生成した単語)(システム辞書の項目番号 -1)「ムゲンダイ」 (2) 第1候補の自立語の「無限大」に関して INDEPPAIR に該当が有るので、 「∞」のスコアを上げる為に、候補一覧の検索を行う。 (3) 候補一覧の (a) は第1候補なので、INDEPPAIR の検索はしない。 (4) 候補一覧の (b) が、「∞」に一致するか検査する為に、 システム辞書の項目番号jを検索する。 (5) システム辞書の項目番号jは「∞」で、INDEPPAIR での指定と一致するので、 スコアを上げる。 (6) 該当する物が見つかったので、処理を終了する。
メモ: ビタビアルゴリズムだと 後方から順に文節区切りの決定が行われる傾向が強い。 なので、 前方から順に文節区切りの決定を行っているつもりで何かすると、 ひょんな所で出鱈目な結果が出てしまう。
自立語の学習を 「変換の第1候補 → 変換確定した候補」形式を1件だけ学習、から 「よみがな → 変換確定した候補」形式の複数履歴学習、に変更。 接尾辞の学習を1項目から複数履歴学習に変更。 接頭辞の複数履歴学習を追加。
これで、 頻繁に使う自立語があるけれども 使われる毎に付属語が違うので文節学習が生かされず 望んでいない物が候補の上位に来てしまう、 とか、 2番目によく使う自立語を覚えてくれない、 とか、 数詞の文節学習を無効に設定していると接頭辞を覚えてくれない、 とか、 数詞の文節学習を有効に設定しているけれども 数詞の値が変わると接頭辞が忘れ去られる、 とか、 2番目によく使う接尾辞を覚えてくれない、 とか、 言う問題が解消される。
副作用として、学習データの肥大化が進み、 その為に処理が遅くなる、問題がある。 2割増3割増当たり前、の勢いで肥大化が進む。 ジレンマ。 それから、単語変換方式を使っている人の場合、 何の役にも立たないただの無駄。 あと、実地試験を始めて日が浅いので、どんな副作用が出るか判らない。
具体例による詳細解説: 例:使用前) 「くらすは」を変換 → 「暮らすは」 くらすは(暮らすは:(,1000,Vf,3276,503,2)5,150 ,クラスは:(g,1000,Nk,3276,303,1)3,741 ,暮すは:(,1000,Vf,3276,503,2)1,977 ,くらすは:(N,1000,Vf,3276,503,2)1,964 ,クラスハ:(N,0,-)1 ,): → 「クラスは」に訂正して確定 次に、「くらすと」を変換 → 「暮らすと」 くらすと(暮らすと:(,1000,Vy,3276,503,2)5,150 ,クラスと:(g,1000,Nk,3276,303,1)3,741 ,暮すと:(,1000,Vy,3276,503,2)1,977 ,くらすと:(N,1000,Vy,3276,503,2)1,964 ,蔵すと:(,1000,Vy,327,303,2)11 ,倉すと:(,1000,Vy,327,303,2)11 ,鞍すと:(,1000,Vy,327,303,2)11 ,庫すと:(,1000,Vy,327,303,2)11 ,区らすと:(,1000,Vy,327,255,3)11 ,苦らすと:(,1000,Vy,327,255,3)11 ,句らすと:(,1000,Vy,327,255,3)11 ,九らすと:(,1000,Vy,327,255,3)11 ,9らすと:(,1000,Vy,327,23,3)11 ,9らすと:(,1000,Vy,327,23,3)11 ,クラスト:(N,0,-)1 ,): 説明: 付属語が異なるので文節学習は反映されず、 CEF_GUESS属性で INDEPPAIR学習は除外されているので、 以前の「クラスは」の訂正は生かされない。 例:使用後) 「くらすは」を変換 → 「暮らすは」 → 「クラスは」に訂正して確定 「くらすと」を変換 → 「クラスと」 くらすと(クラスと:(wg,1000,Nk,3276,303,1)126,136 ,暮らすと:(,1000,Vy,3276,503,2)5,150 ,暮すと:(,1000,Vy,3276,503,2)1,977 ,くらすと:(N,1000,Vy,3276,503,2)1,964 ,蔵すと:(,1000,Vy,327,303,2)11 ,倉すと:(,1000,Vy,327,303,2)11 ,鞍すと:(,1000,Vy,327,303,2)11 ,庫すと:(,1000,Vy,327,303,2)11 ,区らすと:(,1000,Vy,327,255,3)11 ,苦らすと:(,1000,Vy,327,255,3)11 ,句らすと:(,1000,Vy,327,255,3)11 ,九らすと:(,1000,Vy,327,255,3)11 ,9らすと:(,1000,Vy,327,23,3)11 ,9らすと:(,1000,Vy,327,23,3)11 ,クラスト:(N,0,-)1 ,): 説明: 自立語単体でも学習しているので、 付属語が異なっていても、よく使われる自立語が優先される。 問題点: 使用前の学習内容) ADD "CAND_HISTORY" S"くらすは" S"クラスは" ADD "CAND_HISTORY" S"くらすと" S"クラスと" 使用後の学習内容) ADD "CAND_HISTORY" S"くらすは" O1 N1 S"クラスは" T1 F1 ADD "INDEP_HISTORY" S"くらす" O1 N1 S"クラス" T1 F1 ADD "CAND_HISTORY" S"くらすと" O2 N1 S"クラスと" T2 F1 ADD "INDEP_HISTORY" S"くらす" O2 N1 S"クラス" T2 F2 学習量が 1.5倍くらいになる (上記の例では、2回目の INDEP_HISTORY で1回目の INDEP_HISTORY を上書きして消すので、2倍にはならない)。 しかも文節学習(CAND_HISTORYの学習)した後は自立語学習(INDEP_HISTORYの学習)は無駄になる。 備考: 前々から気づいてはいたが、学習データの利用効率の悪さからお蔵入りにしていた。 それとも、異なる文節学習でも同一の自立語学習になる事がある分、それほど肥大化はしないのだろうか?。 単語変換を行った場合、CAND_HISTORY での文節学習と、INDEP_HISTORY での自立語学習の、内容が全く同じになる。
またビタビモードでの学習結果の反映をミスった。 要約: ビタビだと1パスで文節を区切るので、 学習結果の反映にて記憶による評価の変化を行ってはいけない。 前方n文節最長一致では2パスで文節区切りを行い、 学習結果の反映で記憶を持たせて処理しているので、 ついうっかりそのままやってしまった。
前方n文節最長一致モードにて、 OCHAIRE学習の右端の文節を「その文節の途中では区切らない学習」とした。 ビタビモードは変えていない(そういう風に変えるのが困難)。
従来、OCHAIRE学習の右端の文節は、 「その文節の途中では区切らず、かつ、 その文節の右端で文節を区切る」 としていたところを、 「その文節の途中では区切らず、 その文節の右端で区切るかどうかは 他の学習データもしくは前方n文節最長一致アルゴリズムに任せる」 に変更した。
具体例による詳細解説: 前提) 「ぶんせつのくぎりかた」を「文節の|区切り|方」と学習。 それ以外の学習は無し。 例:使用前) 「ぶんせつのくぎりかたが(以下略)」を変換すると「文節の|区切り|方|が」となったり、 「ぶんせつのくぎりかたを(以下略)」を変換すると「文節の|区切り|方|乎」となったり、 してしまう。 例:使用後) 「ぶんせつのくぎりかたが(以下略)」を変換すると「文節の|区切り|方」までは確定事項とみなすが、 「方」の右側で区切るか否かは、他の学習データもしくは前方n文節最長一致アルゴリズムで判断する。 この場合は「方|が」と区切る様な学習データは無いので、 前方n文節最長一致アルゴリズムによりできるだけ長い文節を選択するので、 「文節の|区切り|方が」になる。 「ぶんせつのくぎりかたを(以下略)」も同様に「文節の|区切り|方」までは確定事項、 「方」の右側で区切るか否かも同様に処理して、「文節の|区切り|方を」になる。 備考: 前々からそうしたいとは考え、パターン10辺りから実装の試行錯誤をしていたが、そうやく安定動作する様に実装できたと思う。
文節区切りに於いてパターン14の区切り方をする事を前提に、 文節区切りの学習(OCHAIRE学習)に於いて、 1セットのOCHAIRE学習の、 最後の文節の付属語を削除した内容を学習する様にしてみた。
具体例による詳細解説: 前提) 「ぶんせつのくぎりかたが」を「文節の|区切り|方が」と確定した場合。 例:使用前) OCHAIREにおいては、以下の内容を学習。 「ぶんせつの|くぎり」:「文節の|区切り」 「くぎり|かたが」:「区切り|方が」 「ぶんせつの|くぎり|かたが」:「文節の|区切り|方が」 例:使用後) OCHAIREにおいては、以下の内容を学習。 付属語付き:「ぶんせつの|くぎり」:「文節の|区切り」 付属語付き:「くぎり|かたが」:「区切り|方が」 付属語付き:「ぶんせつの|くぎり|かたが」:「文節の|区切り|方が」 付属語無し:「ぶんせつの|くぎり」:「文節の|区切り」 (付属語付きと同じ) 付属語無し:「くぎり|かた」:「区切り|方」 付属語無し:「ぶんせつの|くぎり|かた」:「文節の|区切り|方」 効能) 「ぶんせつのくぎりかたを」を変換した時に、 付属語無し:「ぶんせつの|くぎり|かた」:「文節の|区切り|方」 の学習を使って「文節の|区切り|方+を」が生成される。 備考: 基本的な考え方としてはパターン13と同様。 さらに学習量が増える。
パターン14を実装する時に、面倒になって手抜き実装をしたら、 やっぱり、たまに変な候補が出てしまった。 仕方が無いので、真面目に実装しなおした版。
具体的には、 ptn14 にて付属語の自動延長の判定を行う際に手抜きをして、 文節長が長くなり且つ付属語の文字数が増えている事だけを確認し、 自立語の内容がちゃんと一致しているか見ていない。 そもそも、原作版の Anthy の設計仕様では、 文節区切りの判定を行う時点では変換候補の生成が行われていないので、 自立語がまだ不確定であり、一致するか検査しようが無い。 でも、実際に使っていると、たまに、 読みが同じだけれど字が全然違う自立語を適用してきたり、 そもそも自立語の長さが違う語を適用してきたり、 してくる事が有った。
仕方が無いので、 文節区切りの処理時点で付属語の自動延伸に該当する場合は、 一旦、変換候補の生成を行なって、 自立語が一致しているか否かをちゃんと判定した上で延長判定を行う様にした。
文節区切りの時点と、候補一覧生成の時点で、 2ヶ所に似た様な候補生成のコードが書かれていて、 しかも文節区切りの時点で生成した分は捨てていて、 実装としては、もう、かなりアレだが。
それでもまだ完全解決はできなくて。
原作版の Anthy では、 文節区切り位置候補の生成 → 文節区切りの位置の判定 → 変換候補の生成 → 変換候補の判定 → 文節区切り候補と変換候補をユーザへ提示、 と言う順で処理している為、 文節区切りの位置の判定を行っている時点では、 変換候補の一覧生成や自立語/付属語の部位切り分けが完了していない。 文節区切り位置が同じ同読み異字の変換候補がまとまった状態 (part[] の seq が縮退した状態のまま)で、 学習由来の候補はシステム辞書の自立語とのマッチングを 取っていない事がある(自立語/付属語の文字数がわからない)状態、 になっている。 なので、 文節区切りの処理時点で、 自立語の文字数が一致で付属語が伸びているかを判定したり、 学習結果と自立語が一致しているか否かを判定したり、 しようとしても、 そもそもそう言う情報を生成する前なので、判定できない。 仕方が無いので、文節区切りの判定で必要に迫られた時に、 文節区切り候補から変換候補の生成を行っているのだけれども。 選択された文節区切りの情報が持っている変換候補の情報に対して、 どの変換候補が使用可能でどれが使用禁止かの指定をできないので、 文節区切り時点で付属語延長して使用と判定した候補が使われずに、 同音異字が使われてしまう事があって防げない。
この辺をパターン14〜16に合わせようとすると、 Anthy の処理全体に関わる部分を大幅に変更しなければならないし。 パターン14〜16を諦めると、 付属語違いのパターンを全て学習するまでは、 付属語無しや付属語が短い状態で文節を切ってしまうし。 Anthy をベースにした改造の限界地点。
付属語の利用頻度の計測をできる様にしてみた。 ついでに、付属語の利用頻度を学習する様にしてみた。
文節を区切る際や変換候補を並べる際に、 文節/候補のスコアに対して、付属語の利用頻度に応じて log10(1+(付属語の利用回数)) * (DEPGRAPH_SCORE_INCREASE_BIASSCORE_BY_LEARN) を加点する。
ビタビの文節区切りに付属語の学習を反映させようとしていたら、 前方n文節最長一致にて cand_info コーパスの反映のさせ方が判ったので実装。 併せて、 ビタビモードでの文節区切りの際にも、 システム辞書の頻度値を利用するモードを追加。 ビタビの文節区切りでの付属語の学習を反映と、 前方n文節最長一致での cand_info コーパスの反映は、 LATTICE_WITH_CAND_SCORE, LATTICE_WITH_CANDSTRUCT_SCORE, LATTICE_WITH_CAND_CORPUS, LATTICE_WITH_DEP_HISTORY, あたり。
文節区切りに関しては、そんな付属語滅多に使わないよ、 となる文節区切り候補が出にくくなる傾向はあるが、 逆に、 普段使っている付属語を無理に付けようとするなよ、 と言う候補が出る様にもなる諸刃の剣。 LATTICE_WITH_CAND_SCORE, LATTICE_WITH_CANDSTRUCT_SCORE, LATTICE_WITH_CAND_CORPUS, LATTICE_WITH_DEP_HISTORY, DEPGRAPH_SCORE_INCREASE_BIASSCORE_BY_LEARN を調整して、 適当な頃合いを探した方が良いかも知れない。
変換候補を並べる際には、 変換候補に付属語が異なる物が並ぶ事は少ないみたいなので、 効果はほとんど無いかも知れない。
付属語無しOCHAIREとか INDEP_HISTORY とか DEP_HISTORY とか増やしたせいで、 せっかく patch10までの作業で学習処理を高速化した分を 丸ごと帳消しにするくらい学習量が増えてしまったので、 せこく ENABLE_PREDICTION false 機能を追加。 それから、 付属語有り3文節OCHAIRE(再利用率 5%前後)は、 付属語無し3文節OCHAIRE(再利用率 7%前後) にて 代替が効くので削除。 再利用率が微妙に低いのもあるが、 これはデータ総数が 400件前後なので、有意なのか誤差なのか微妙。
いいかげん、これでもう、 学習出来そうな物は全部学習する様になったと思うけれど。 あとはもう、 「(付属語)+(自立語)」とか、 「(自立語)+(付属語を削)+(自立語)」とか、 「(付属語)+(自立語を削)+(付属語)」あたりの、 言語学者とか統計学者とか純粋単語nグラム派とかでないと 意味が無いんでないの、 という辺りだけだと思う。
例) 「例えば|この|文の|例だと」(たとえば|この|ぶんの|れいだと) 「(付属語)+(自立語)」 の|例 「(自立語)+(付属語を削)+(自立語)」 例えば|この この|文 文|例 「(付属語)+(自立語を削)+(付属語)」 の|だと この辺を学習して、実用的な効果はあるかね? 「(付属語)+(自立語)」は、実用的な面と効率の面のバランスを考えると、 パターン17で追加した付属語の学習にて、代替が効く様な気がする。 注意) vagus氏(あるいはその先人)が、Canna や Anthy にて 少しでも変換結果を良くするにはどうしたら良いのか苦心なさった結果、 わりと単純でよく使われる文節は、丸ごと自立語としてシステム辞書に登録されています。 この例の場合、「例えば」や「この」がそうです。 従って、言語学?的には不適切な解析結果になります。 Canna や Anthy は、 日本語入力の実用的な(……実用的になる事を目指した?)道具であって、 言語学?的な解析の道具じゃ無いし。
「(付属語)+(自立語)」、 「(付属語)+(文節)+(自立語)」、 の学習を実装。 但し、標準状態では無効にしてある。 ENABLE_OCHAIRE* の辺り。 有効にすると、学習データ量が標準状態の1.3〜1.4倍になります。
新規に実装したばかりなので、 学習させる価値が有るのか無いのかは、全く不明です。 単語Nグラム派の主張を全面的に信じるならば、 価値が有るのかもしれませんが。
パターン16で書いた通り、Anthy の構造上、 この辺りの学習結果を反映しようとすると、 同音異字の誤変換や、 過剰な文節区切り(自立語と付属語の間で切ってしまう)が、 どうしても完全駆除できなくなってしまう。
Anthy の構造を変えれば直せるが、 ソースのおおよそ 1/3 〜 1/2 くらいを 書き換えないといけなくなりそうだから嫌。 ……まぁ、patch13 で既に、 ソースの 1/3 くらいは書き換えているのだけれど。
必要なデータ構造の構想のメモ書き。とは言っても、もうやる気無し (OCHAIRE mw A) --- (OCHAIRE mw A) -+- (OCHAIRE mw D) -+- (MW_SINGLE mw F) --- (OCHAIRE mw G) …… | | (OCHAIRE mw D + OCHAIRE mw G) | | | +- (MW_SINGLE mw E) | | | +- (OCHAIRE mw D) | +- (MW_SINGLE mw C) | +- (MW_SINGLE mw B) | +- (OCHAIRE mw A) OCHAIRE mw A の第1文節は自立語有りでもなしでもどちらでもいい OCHAIRE mw A の第3文節は付属語無し。LATTICE_AUTOEXPAND_DEPS 処理により、MW_SINGLE mw B, MW_SINGLE mw C, MW_SINGLE mw D の枝が増える。 OCHAIRE mw D の第1文節は自立語有り。OCHAIRE mw A の自立語と OCHAIRE mw D の自立語が一致するので、LATTICE_AUTOEXPAND_DEPS 処理により、OCHAIRE mw A の枝に接ぎ木される。 OCHAIRE mw D の第2文節は付属語無し。LATTICE_AUTOEXPAND_DEPS 処理により(略) OCHAIRE mw G の第1文節は自立語無し。MW_SINGLE mw F の自立語が OCHAIRE mw D と一致し、MW_SINGLE mw F の付属語が OCHAIRE mw G と一致するので、連結される。 取り敢えず MW_SINGLE と書いたけれども、MW_COMPOUND 系列でも構わない。 あ、接ぎ木の根元側も、複数になる場合があるや。 この場合だと、OCHAIRE mw G が MW_SINGLE mw E にも接ぎ木されるパターンもありうる。 ……やっかいだな。 こんな感じでつないでいけば、現状の「文節群の部分集合だけでも完全に一致しないと学習が生かせない」問題は解決。
「(自立語)+(付属語を削)+(自立語)」、 「(付属語)+(自立語を削)+(付属語)」、 「(自立語)+(付属語を削)+(自立語を削)+(付属語)」、 の利用頻度の計測機能を実装。 但し、標準状態では無効にしてある(ENABLE_DATASAMPLING)。 有効にすると、学習データ量が標準状態の3倍になります。
なお、 現状の Anthy のビタビモードでは、 これらの学習結果の反映ができない構造になっている為、 データの蓄積分析をした結果、学習させるだけの効果が有ると判ったとしても、 学習を反映させる実装は行いません(行えません)。 前方n文節最長一致モードではこれらの学習結果の反映ができる事に気付いた。 でももう面倒。
……、もういいかげん、 学習させてみるだけの価値のありそうな物は 無いだろうと思いたい所なのだけれど。
「ぁぃぅぇぉゃゅょっ」を付属語として連結するのを 完全禁止にしていると、 口語調の文を書く時につらい事に今更気付いたので、 スコアを下げるだけに変更 (DEPGRAPH_SCORE_DECREASE_BIASSCORE_XCT_PART)。 自立語学習も適用しない様にした。
vagus氏の alt-depgraph のパッチを見ると、カタカナ語を (カタカナ変換を使わずに)漢字変換で出す使い方をするみたいなので、 対応オプションを追加(CANDIDATE_SCORE_TRIM_KANA)。
入力された内容と前方完全一致する OCHAIRE 学習データが無かった場合、 これまでは、 入力内容の後方で一致する OCHAIRE や CAND_HISTORY に対して システム辞書由来の単語よりも高い得点 (学習したエポック秒の値をそのまま頻度値とみなす)を付けていたが、 これだと CAND_HISTORY の反映が強すぎて、 しばしば細切れ文節の連発を起こす事があった。 これを、 {(システム辞書の頻度値)+(追加得点)+(学習を利用した回数の対数)} に変更してみた (LATTICE_BIASSCORE_BY_OCHAIRE, LATTICE_WITH_LEARNEDFREQ_SCORE)。 学習の反映が穏やかになりつつも、そこそこは反映される様になったかな?。
コーパスのハッシュ切り替え閾値の HF_THRESH が、 拙作パッチに合っていないらしい (nosuke(のすけ)氏 - 日記みたいな何か - 2009年 2月21日 (土) - 配流) ので、 調整。 システム辞書上の単語得点が HF_THRESH より大きいか否かで、 単語?付属語?のコーパス検索のハッシュ値を変えているらしいが、 拙作パッチ patch12ptn12 にて得点の計算方法を変えた (原作:頻度値の序列、但し頻度値が同じ場合はランダム(qsort)に順位を決定。 拙作:頻度値をそのまま。)為、 合わなくなっていたらしい。
接尾辞付き数詞を自立語学習すると、 全般的に学習が少ない場合 (大量に貯まっていない、と言った方がいいのかもしれない)に 何か嫌な変換になるらしい (nosuke(のすけ)氏 - 日記みたいな何か - 2009年 2月21日 (土) - 配流) 。 接頭辞もしくは接尾辞が付いている数詞の自立語学習を無効にするオプション CANDIDATE_DISABLE_INDEPSCORE_WITH_PREFIX_OR_POSTFIX 追加。デフォルトで学習は無効。
原作の Anthy の depgraph/mkdepgraph.c にて、 ソースを展開したディレクトリとビルドするディレクトリを分離した場合の 対応が不十分だったので、対応を追加。 ……エラーを黙殺して壊れた辞書を作るのはやめてほしい……。 その影響で、vagus氏の alt-depgraph の修正パッチが必要になってしまった。
OCHAIRE の読みの文字数検査を追加。
ビタビモード時の、 「ほぼ千部」「週六単語」対策として、 VITERBI_MODE_DECREASE_PROBABILITY_PHRASE_WITH_PRE_POST, VITERBI_MODE_DECREASE_PROBABILITY_PHRASE_WITH_PRE_AND_POST, VITERBI_MODE_DECREASE_PROBABILITY_PHRASE_WITH_PRE, VITERBI_MODE_DECREASE_PROBABILITY_PHRASE_WITH_POST を追加。 前方n文節最長一致と異なり、 ビタビは確率処理を行う都合で挙動の予想が付かないので、 本オプションの使用する事により何が何処へ飛んでいくかは不明。
辞書と変換結果の不整合検出機能「ENABLE_ERROR_RECORD true」を追加。
変換確定した内容が システムの辞書(単語辞書 + 付属語グラフ)に存在しない場合に、 その旨を学習の ERROR レコードに記録します。
ADD "ERROR" S"ことになる" S"事になる" S"cand_hint_freq is less than 1." T1237212984 F1
こんな感じ。
なお、この様な状況は、
場合に発生します。 従いまして、 標準の辞書/付属語グラフを使用している場合、 もしくは過去の学習データを所持していない場合、 ほとんど何の効果もありません。
「丘の道を登り - 2008年12月02日 - 自作 depgraph の進捗状況」 にて構想が述べられている、 「文節区切りをユーザが指定する」を 変換エンジン側の改造で実装してみた物。 「Anthy 文節区切りパッチ」
文節区切り指定の入力方法は、 LATTICE_HINTING_BY_KATAKANA, LATTICE_HINTING_BY_CHARACTER, LATTICE_HINTING_CHARACTER にて、設定します。
MANUALLATTICE_MODE true 指定すると 「区切りを指定した所では必ず区切り、指定しなかった所は絶対区切らない」 になります。
MANUALLATTICE_MODE true 指定しないで、 VITERBI_MODE true か MAXLEN_MODE true 指定すると、 「区切りを指定した所では必ず区切り、指定しなかった所は自動判定」 になります。
なお、文節区切り位置の修正を行った場合、 文節区切りの強制指定よりも区切り位置の修正が優先されます。
注意: SKK方式とは異なり、送り仮名の開始位置は片仮名にはしません。 また、送り仮名の無い漢字の末端位置でのスペース入力はしません。
備考: 文節区切りに指定した文字の入力方法は、 フロントエンドのソフトウェアに聞いて下さい。 uim とか scim とか iiimf とか im とか色々。
フロントエンドに uim を使っており、 LATTICE_HINTING_BY_CHARACTER 指定と LATTICE_HINTING_CHARACTER 0x3B 指定で、 「;」(JIS X 0201 セミコロン)を区切りに設定した場合:
;; (require "japanese.scm") (define ja-rk-rule (append '( ;; for anthy patch13Bptn21 [ (((";" ";"). ())(";" ";" ";")) (((";"). ())(";" ";" ";")) (((";" "a"). ())((";" ";" ";") ("あ" "ア" "ア"))) (((";" "i"). ())((";" ";" ";") ("い" "イ" "イ"))) (((";" "u"). ())((";" ";" ";") ("う" "ウ" "ウ"))) (((";" "e"). ())((";" ";" ";") ("え" "エ" "エ"))) (((";" "o"). ())((";" ";" ";") ("お" "オ" "オ"))) (((";" "A"). ())((";" ";" ";") ("ア" "あ" "ア"))) (((";" "I"). ())((";" ";" ";") ("イ" "い" "イ"))) (((";" "U"). ())((";" ";" ";") ("ウ" "う" "ウ"))) (((";" "E"). ())((";" ";" ";") ("エ" "え" "エ"))) (((";" "O"). ())((";" ";" ";") ("オ" "お" "オ"))) ;;] ) ja-rk-rule)) ;;
を ${HOME}/.uim に追加して、 「bunnsetsu;kugiri;itiwo;syudou;nyuuryokusuru;mo-dowo;tuika」 とタイプすると、 「ぶんせつ;くぎり;いちを;しゅどう;にゅうりょくする;もーどを;ついか」 と表示され、変換を行うと 「|ぶんせつ|くぎり|いちを|しゅどう|にゅうりょくする|もーどを|ついか|」 と区切られます。
なお、「;」(JIS X 0208 セミコロン)を入力したい場合は、 「;;」とタイプします。
「;」(JIS X 0201 セミコロン)を入力したい場合は、 「;;」を入力してからカタカナ変換を行うか、 「;;」を入力してから読みが「;」で変換後が「;」の 単漢字を利用する(初期状態で登録してある)か、 「;」を入力してから変換せずに確定するか、 IM を off にして入力するか、 して下さい。
フロントエンドに uim を使っており、 「スペース」をタイプした時は区切り指定、 「CTRL + スペース」をタイプした時は変換開始、 設定したい場合(あるいはその逆の割当):
uim の設定で 「確定前入力文字がある状態でスペースを入力」 を行い、 次いで変換開始のキー割り当てを「CTRL + スペース」に変更し、 anthy で LATTICE_HINTING_CHARACTER 0x20 と設定する。
フロントエンドに uim を使っており、 LATTICE_HINTING_BY_KATAKANA 指定でカタカナを区切りに設定した場合:
拙作 「uim.kana.conf(96KiB) (Thu,23 Apr,2009) ${HOME}/.uim のサンプル」、 「uim-Anthy のキーカスタマイズで大文字と小文字を別のキーとみなすパッチ(Canna+kinput2風)」 辺りで、カタカナ入力できます。 上記サンプルでは「;」に続けてタイプした文字が、 上記パッチと上記サンプルの両方を使った場合は 1文字目を大文字でタイプした所も、 文節の区切りになります。 「bunnsetsu;kugiri;itiwo;syudou;nyuuryokusuru;mo-dowo;tuika」 もしくは 「BunnsetsuKugiriItiwoSyudouNyuuryokusuruMo-dowoTuika」 とタイプすると、 「ブんせつクぎりイちをシュどうニュうりょくするモーどをツいか」 と表示され、変換を行うと 「|ぶんせつ|くぎり|いちを|しゅどう|にゅうりょくする|もーどを|ついか|」 と区切られます。
uim 以外のフロントエンドを利用している場合は、 各自で設定して下さい。
LATTICE_HINTING_BY_KATAKANA 指定でカタカナを区切りに設定した場合、 例えば「じゃ」の様に拗音が付く文字を区切りにしたい場合は、 「ジゃ」の様に、1文字目をカタカナに、拗音は平仮名に、 して下さい。 また、「ヴ」を区切りにしない場合は、 「う゛」と表記して下さい。
「無変換」キーや「前候補」キーを区切りに用いたい場合:
xmodmap でキーバインドを設定する。 設定方法は OS(GNU/Linux の場合はディストリビューション)によって 流儀が違うので、ここで全て説明するのは無理です。
副作用として、 設定した各キーの、元のキーとしての機能は使えなくなります。
設定方法の概要としては、 LATTICE_HINTING_BY_CHARACTER 指定と LATTICE_HINTING_CHARACTER 0x3B 指定で、 「;」(JIS X 0201 セミコロン)を区切り文字に設定している場合は、 ${HOME}/.xinitrc か ${HOME}/.xsession の適切な方の、適切な位置に
「無変換/文節読み」キーの場合: xmodmap -e 'keycode 131 = semicolon' 「前候補/変換/全候補」キーの場合: xmodmap -e 'keycode 129 = semicolon' 「カタカナ/ひらがな/ローマ字」キーの場合: xmodmap -e 'keycode 120 = semicolon'
を、追加する。 あるいは xmodmap に読み込ませるファイルの適切な位置に keycode 指定を追加する。
uim-anthy のキーバインド変更で設定する方法は不明。
「スペースバー/スペースキー」を 1回タイプした時は区切り指定、2回タイプした時は変換開始、 と、共用したい場合:
フロントエンドのソフトウェアに、そう言う機能を追加して下さい。
おまけで ENABLE_AUTOLEARN オプション追加。
直前に入力もしくは変換された内容を 変換の際のスコアリングの参考情報として保持する機能と、 直前に変換確定して学習した内容を取り消す機能を、 追加。
本機能を有効/無効にしたい場合は、環境設定の
ENABLE_KEEPALIVE
ENABLE_KEEPALIVE_REFER_COMPOUND
ENABLE_KEEPALIVE_REFER_OCHAIRE
ENABLE_KEEPALIVE_REFER_CORPUS
ENABLE_KEEPALIVE_LEARN_OCHAIRE
辺りを設定されたし。
# 「直前に変換確定して学習した内容を取り消す機能」の
有効無効を切り変えるオプションはありません :-O ワスレテタ。
注意:
本機能を利用する場合は、
フロントエンド側を対応させる改造が必須となります。
学習データの形式が、また変更になっています。 オリジナルの Anthy もしくは patch1〜patch13Bptn21 までの Anthy から patch13Bptn22以降に移行する場合、 一旦、
% rm ~/.anthy/last-record1_*.bin % anthy-agent --update-base-record % rm ~/.anthy/last-record1_*.bin % anthy-agent --update-base-record
を実行(同じ事を2回繰り返していますが、間違いではありません)して、 学習データの形式変換をして下さい。
(ac,0,?) の API呼び出しは、原作版 Anthy と全く同じです。
(ac,<0,?) の API呼び出しは、原作版 Anthy では何もせずに戻るので、 関数呼び出しの処理の分だけ時間を消費する以外は、無害です。
本機能の具体例、その1: 前回変換した内容を用いて、コーパスを用いたスコアリングも変わっている筈。 コーパス処理は統計的な処理が行われており人力での追跡が困難な為、 具体例を挙げる事は困難です(わかりやすい具体例は未発見です)。 本機能の具体例、その2: 前提状況: 学習に下記6件の学習が有る。 OCHAIRE学習に「|学習|優先|」(|がくしゅう|ゆうせん|) OCHAIRE学習に「した|時|」(した|とき|) CAND_HISTORY学習と INDEP_HISTORY学習に「|有線|」(|ゆうせん|) CAND_HISTORY学習と INDEP_HISTORY学習に「|とき|」(|とき|) 本機能を使わない時: 「がくしゅう」で変換して「|学習|」で確定した後、 「ゆうせん」で変換すると「|有線|」になる (CAND_HISTORY学習やINDEP_HISTORY学習でそう学習したから)。 続けて「した」と入力して無変換で確定した後、 「とき」で変換すると「|とき|」になる (CAND_HISTORY学習やINDEP_HISTORY学習でそう学習したから)。 本機能を使った時: 「がくしゅう」で変換して「|学習|」で確定した後、 「ゆうせん」で変換すると「|優先|」になる (OCHAIRE学習でそう学習したから)。 続けて「した」と入力して無変換で確定した後、 「とき」で変換すると「|時|」になる (OCHAIRE学習でそう学習したから)。 本機能の具体例、その3: 前提状況: 複合語辞書に「|日本|郵船|」(|にほん|ゆうせん|)が有る。 学習は特に無し。 本機能を使わない時: 「にほん」で変換して「|日本|」で確定した後、 「ゆうせん」で変換すると「|優先|」になる (システム辞書でそう設定されているから)。 本機能を使った時: 「にほん」で変換して「|日本|」で確定した後、 「ゆうせん」で変換すると「|郵船|」になる (複合語辞書の結果を優先)。 本機能の具体例、その4: 本機能を使わない時: 「あくせす」とタイプしようとして間違って「あくせうs」とタイプしてしまい、 「|悪|背|鵜|S|」で変換確定してしまった直後に、 (BackSpace) もしくは Ctrl+h をタイプして間違って入力した内容を消してから 「あくせす」を変換すると、 「|悪|背|鵜|S|」で変換確定した内容を適用して、 「|悪|背|す|」になってしまう。 本機能を使った時: 「あくせす」とタイプしようとして間違って「あくせうs」とタイプしてしまい、 「|悪|背|鵜|S|」で変換確定してしまった直後に、 (BackSpace) もしくは Ctrl+h をタイプして間違って入力した内容を消してから 「あくせす」を変換すると、 「|悪|背|鵜|S|」で変換確定した内容を忘れ、 「|アクセス|」になる。 本機能の問題点: ENABLE_KEEPALIVE_LEARN_OCHAIRE を有効にした場合、 学習データの利用効率が悪い (最良でもせいぜい2割前後と思われる。残り8割の学習は無駄になる)。 学習データの活用率は半々ぐらい? (2〜5割前後と思われる。使っていて5回に1回は、気付かない内に良くなっているかもしれない)。
LATTICE_AUTOEXPAND_DEPS がうまく機能していないので、 実装のやりなおし。
具体例1: 前提状況: 以下の2つの学習が有る。 OCHAIRE学習に「|学習を|優先|」(|がくしゅうを|ゆうせん|) CAND_HISTORY学習に「|優先する|」(|ゆうせんする|) LATTICE_AUTOEXPAND_DEPS を使わない時: 「がくしゅうをゆうせんする」と入力して変換すると、 「|学習を|優先|する|」(|がくしゅうを|ゆうせん|する|)と変換される。 「する」が付属語にならない。 ptn23 での修正前: 「がくしゅうをゆうせんする」と入力して変換すると、 「|学習を|優先する|」(|がくしゅうを|ゆうせんする|)と変換される。 「する」が付属語になる。 但し、CAND_HISTORY学習に「|優先する|」が無い場合は、 「|学習を|優先|する|」(|がくしゅうを|ゆうせん|する|)と変換されてしまう。 ptn23 での修正後: 「がくしゅうをゆうせんする」と入力して変換すると、 「|学習を|優先する|」(|がくしゅうを|ゆうせんする|)と変換される。 「する」が付属語になる。 CAND_HISTORY学習に「|優先する|」が無くても、ちゃんと「する」が付属語になる。 具体例2: 前提状況: OCHAIRE学習に「|文節の|区切り方|」(|ぶんせつの|くぎりかた|)がある時に、 「ぶんせつのくぎりかたと」や、 「ぶんせつのくぎりかたとかのはなしはどうなるのだろう」を変換すると。 LATTICE_AUTOEXPAND_DEPS を使わない時: 「文節の|区切り方|と」や、 「文節の|区切り方|戸かの|話は|どうなるのだろう」になる。 LATTICE_AUTOEXPAND_DEPS を使った時(ビタビ): 「文節の|区切り方と」 「文節の|区切り方とかの|話しは|どうなるのだろう」 LATTICE_AUTOEXPAND_DEPS を使った時(前方n文節最長一致): 「文節の|区切り方と」 「文節の|区切り方とかのはな|市は|どうなるのだろう」 前方n文節最長一致のアルゴリズムは、 文章全体の文節数と各文節の長さの情報を用いて区切り位置を判定するので、 各文節の内容や組み合わせを用いて判断する事は出来ない(しない)。 そう言う事をする様にしたのがビタビなどの確率的あるいは統計的手法なのだし。
原作版の Anthy からずっと、
OCHAIRE学習にヒットした前後にて
コーパス処理を間違えているバグ?仕様?手抜き?を見つけた。
これを治さないと、
vagus氏の alt-depgraph の文末属性に対応できないので、
修正。
なお、この修正の為に、
OCHAIRE学習の展開処理を丸ごと実装しなおしており、
そこそこ規模が大きい(20KB、700行くらい?)為、
その部分だけ取り出して、
原作版に修正パッチとして commit する気力はありません……。
「vagus氏 - 丘の道を登り - 2009年04月30日 - depgraph: 「文末」属性」の、
付属語グラフに文末属性を追加するアイディアに対応。
付属語グラフの、「Sz@」、「Sz.@」、「Sz:@」にて、文末属性になります。
付属語グラフで文末属性を使わなければ、特に変化は無し。
手動指定時/学習で区切ると指定された場合を除き、
文末属性の文節の直後に平仮名/カタカナが来たら、
そこでの文節区切りは全面禁止
(文末属性が付いていない文節を探して使用する)、
変換候補の並び順ではスコア半減。
学習データにヒットした場合でも、一応、文末属性やコーパスが効く筈です。
一応と言うのは、Anthy の構造上、完治できないから。
「日記みたいな何か - 2009年 5月 9日 (土) - Anthy」、
『「すぱーぎあ」が何度確定しても「す + パーギア」に』。
まず、「スパーギア」が辞書に載っていない。
原作版の Anthy だと、
平仮名語/カタカナ語の自動学習は、
平仮名/カタカナだけの文節にした場合のみ行われるので、
「|数えようとして|スパーギアの|方を|」の様に
途中までカタカナで最後に平仮名、と言う文節で確定した場合は
自動学習が行われず、
いつまで経っても「スパーギア」を覚えてくれない。
なので、何度確定しても「スパーギア」が出ない。
途中までカタカナで最後1文字が平仮名、と言う文節で確定した場合でも、
カタカナ部分だけ抽出して自動学習する様にした。
パターン20で語尾に拗音を付けるのを許可したが、
スコアリング調整にバグが有ったので
(参考:「nosuke氏 - 日記みたいな何か - 2009年 5月18日 (月) - でんしゃ」)
、
再度調整。
「っ」「ー」「゛」の場合と、
「ぁ」「ぃ」「ぅ」「ぇ」「ぉ」で且つ直前の文字の韻を踏んでいる場合は、
変換候補のスコアは半減、自立語部分一致での学習の適用を許可。
「ゃ」「ゅ」「ょ」「ゎ」の場合と、
「ぁ」「ぃ」「ぅ」「ぇ」「ぉ」で且つ韻を踏んでいない場合は、
変換候補のスコアは最低点、自立語部分一致での学習の適用は禁止
(文節全体で完全一致した場合のみ、学習適用を許可)。
にした。
具体例:
「電子」(でんし)が学習してある場合。
「電子ぃ」(でんしぃ)や「電子っ」(でんしっ)は、
「電子」(でんし)の半分のスコアで、
且つ自立語部分が「電子」(でんし)の学習の結果を受け継ぐ。
「電子ゃ」(でんしゃ)や「電子ゎ」(でんしゎ)などは、
変換候補の順番では最後尾群で、
且つ自立語部分が「電子」(でんし)の学習の結果を受け継がない。
Anthy の meta_word の仕様で誤解している部分が有り、
語尾に XCT_PART を追加した単語にて、
学習(拙作パッチでの拡張部分)の適用間違いや
ENABLE_ERROR_RECORD での誤判定が起きるバグが有ったので
修正。
meta_word の比較ルーチンを丸ごと書き直し。
meta_word 構造体に格納されている単語の合計長は、
meta_word.len よりも短い場合が有るらしい。
その場合の不足している部分は、入力された内容と同じ、らしい。
Anthy の辞書の頻度値?の仕様を誤解していたバグを修正。
「vagus氏 - 丘の道を登り - 2009年05月27日 - 正変換の候補の中に逆変換の候補が混じることに気づいた」、
の件。
要因解説:
システム辞書の単語の評価値は、
原作版 Anthy では、
辞書のソースに書かれている値を参考に
Anthy が適当に勘案した値になっていた。
拙作パッチの patch12/13ptn12 (Sat,22 Nov,2008) から、
辞書のソースに書かれている頻度値を直接用いる様に変更したが、
その際、
辞書のソースに書かれている頻度値が小さい場合に
システム辞書の各単語の逆変換フラグが壊れていた。
どうやら、
頻度値の下限は
内部表記の 100(拙作パッチでの換算では、辞書のソース上での 8)で、
これを下回るとシステム辞書のファイルに記録される頻度値が 0 になり、
逆変換フラグ(頻度値の符号がそのまま逆変換フラグになっているらしい)が
喪失するらしい(整数型の 0 には符号が無い)。
対策:
辞書のソースに書かれている頻度値から
システム辞書のファイルに記録する頻度値への計算方法を変更して、
小さい頻度値の場合でも逆変換フラグを喪失しない様にした。
副作用:
辞書のソースにおける頻度値の上限が 4095 ぐらい
(int型のデータ長の下限保証値は定義されていないので、断言はできない)
になった。
なお、非保障(仕様外)だが、
int型が 32bit なシステムでは 268427264 まではトラブルは起きない。
もっとも、
原作版 anthy の時点で
int型が 32bit よりも小さいシステムには非対応なので、
まぁアレだ。
あと、あんまり大きな値を付けると、学習よりも強くなる。
学習データの利用効率の統計を取り、 効果が低い部分は学習対象から削除した。 「Anthy 改造パッチの詳細解説と覚え書きと落書きとグチ - 継続使用の試験結果とかベンチマーク結果とか - Fri,12 Jun,2009」
連用形のスコアを調整。
「日記みたいな何か - 2009年 6月23日 (火) - 最近のAnthy」、
「いがいと」で「い甲斐と」が出る話。
「名詞/形容詞」と「動詞連用形」の相乗平均にした。
オプション
CANDIDATE_RENYOU_SCORE_FIRSTWORD,
CANDIDATE_RENYOU_SCORE_LASTWORD,
CANDIDATE_RENYOU_SCORE_GEOMETRICMEAN
のあたり。
また、原作版からずっとあった、
「|つけ|っぱなし|」と2文節に分割する事を学習した状態や、
付属語を切る位置を変更したりすると、
「点けっ放し」(つけっぱなし)や「付けっ放し」(つけっぱなし)が
候補として生成されないバグだか何だかを修正。
文節区切り位置の指定をして1文節で変換させようとすると、
連用形の元になる候補(動詞と D2KY,yasui,D2T16,D2T35)の段階で
metaword が使用不可判定(理由:指定された文節長より短い)されてしまい、
連結した metaword も使用不可判定
(理由:構成している metaword が使用不可判定されている)
されてしまうらしい。
コーパスや用例辞書に由来する候補のスコアを、
学習に由来する候補より小さくなる様に変更した。
症状:
「|(動詞)する|様に|した|。」と学習させてあるのに、
動詞の内容を変えて変換すると、
「|(動詞)する|様に|下|。」になってしまう。
候補を「|(動詞)する|様に|した|。」に選び直して学習させても、
また「|(動詞)する|様に|下|。」になってしまう。
${HOME}/.anthy/last-record2_default を確認しても、
ちゃんと学習されているし、
anthy-agent で見ても、学習のスコアは反映されている。
でも、「|様に|下|」の候補に、
学習を上回る謎のスコアが加算される。
問題を引き起こす箇所は3点。
src-ordering/relation.c:reorder_by_corpus()
と
src-ordering/relation.c:reorder_candidate()
と
src-ordering/relation.c:compare_context()
。
reorder_by_corpus() では、
変換内容がコーパスに一致したと判定された場合、
スコアをいきなり2倍にしている。
その為に、学習の内容よりもコーパスの内容の方が優先されている。
reorder_candidate() では、
用例辞書 mkworddic/udict に一致した場合、
スコアをいきなり10倍にしている。
その為に、学習の内容よりも用例辞書の内容の方が優先されている。
compare_context() では、
変換候補とコーパスとの一致判定において、
文を構成する各文節の出現順序問わず、
使われている「変換候補/結果の自立語の漢字表記」が
2つ以上かつコーパスの文に於ける文節数の半分以上が一致するならば、
変換候補とコーパスに記録されている文章が一致したと判定され、
reorder_by_corpus() のスコア2倍が適用されていた。
先の「するようにした」の場合:
まず、コーパスには
「|したの|せってい|ふぁいるを|みよ| |下の|設定|ファイルを|見よ|」
がある。
「せっていするようにした」を変換すると、
変換候補の1つとして「|設定する|様に|下|」と言う物も作られるが、
「設定」と「下」の自立語の漢字表記の2つがコーパスと一致するので、
一致判定の条件「2つ以上かつコーパスの文節数のうち半分以上」を
満たしているので、スコア2倍が適用され、
学習由来の候補や他のあらゆる候補を差し置いて優先されている。
対策:
コーパスのデータベースにおいては、
文中での単語の出現順序は記録されていない(たぶん)。
従って、
語順がコーパスと一致しているか否かを判定する事はできない(たぶん)。
一致とみなす文節数を増やすと、
多分、ほとんど一致しなくなってコーパスが効かなくなりすぎる。
なので、
スコアの計算の際に、
辞書上に記録されている評価値を2倍/10倍にする様に変えてみた。
これで、学習されていない内容以上、学習された内容未満、になる筈。
複合語のスコア加算を調整。
「|てつや|」で変換すると「|徹夜|」が第1候補になり、
「|たけだ|てつや|」で変換すると「|武田|鉄矢|」が第1候補になり、
「|こむろ|てつや|」で変換すると「|小室|哲哉|」が第1候補になる。
この機能自体は原作版 anthy から有った機能だけれども、
骨格部分のデータ仕様と、この機能の部分のデータ仕様がずれていて、
原作版 anthy では正しく動作しない状態だった、たぶん。
あるいは、さらに別の部分で仕様が一致していないバグが絡んで、
逆に機能している状態だったかも。
さらに、
左の文節の第1候補もしくは確定結果が不一致でも高得点付けている、
問題があった
(「|竹|だ|鉄矢|」とか「|わ|たり|哲也|」とか、
「|竹だ|鉄矢|」とか「|渡り|哲也|」とか、
左側が複合語辞書と一致していない候補も、優先されてしまう)。
これを、
左側が、複合語辞書もしくは OCHAIRE学習と一致した場合のみ、
優先される様に変更・調整した。
…… patch13 って……まだ続いたの?……。
オリジナルの Anthy は
文節区切りにビタビアルゴリズム(隠れマルコフモデルの派生らしい)を
使用しています。
このビタビアルゴリズムは、
理論上はトップクラスの変換正答率を誇るものの、
その高確率を出す条件として、
大量の高品質なコーパス(あるいは単語なり文節なりの頻度情報)が
必須となっています。
ざっと調べた感じだと、
どうも新聞数年〜十年分くらいの均質で大量のコーパスが必要だそうです。
Tue,23 Dec,2008 追記:
必要なコーパスの分量の確認をしました。
新聞1ページが 10文字 40行 10段 で
見出しや図や写真や広告などを除外した有意な文章の率が 65%と仮定して、
1ページで 2600文字、1日分で 50000文字、と想定すると。
実装した理論や手法により数倍の開きは有るかもしれませんが。
新聞1週間程度(10^5文字)では既存の伝統的手法よりも悪く、
1ヶ月〜数ヶ月ぶん程度(10^6文字)で条件付きで既存の手法と五分五分、
1年ぶん程度(10^7文字)で条件付きで既存の手法よりも良くなり、
10年ぶん程度(10^8文字)用いれば条件付きで既存の手法よりだいぶ良くなる。
条件付きと言うのは、
使用したコーパスに含まれていない分野の内容の文を変換したり、
使用したコーパスと違う文体で変換した場合、
確実に既存の伝統的手法よりも悪くなる。
らしいです。
また、
「新聞数ヶ月分程度のコーパスを用いるだけで既存の手法よりずっと良くなる」
と主張する論文もありますが、それらの場合、
「変換する内容は、使用したコーパスと全く同じ分野で、文体も全く同じ」
と言う条件が付いていますので、
例えば
新聞の社説担当者が社説を書く為だけに使う場合は重宝するかも知れませんが、
色々な分野の様々な文体で利用される事を前提として考えた場合……。
現実問題として、 Anthy あるいは Anthy に限らず「フリーな」かな漢字変換全般に於いて、 その様な大量の高品質なコーパスを利用する事は困難です (既存のコーパスを利用する場合は購入代金や利用料が払えない、 コーパスを新規作成する場合は 作成や頻度情報の品質向上を行う人員を確保できないもしくは品質が足りない、 など)。
ついでに、オリジナルの Anthy だと、 システム辞書の頻度情報や、蓄積した個人用の学習結果やらは、 ビタビアルゴリズムの確率計算には使用しておらず無駄になっていますし、 システム埋め込みのコーパスだけでは 利用者個人に合わせたチューニングができません。
そういった事などを受けて、 敢えて理論的な優秀さを捨て、 過去の、理論的には優秀では無いけれども そこそこ無難だった(と思う)アルゴリズムに戻すと どうなるかを試してみたのが、 patch13 の 前方n文節最長一致モード です。
有り体に言うと。
モダン手法である隠れマルコフモデルが良いと主張するグループと、
古典手法である前方n文節最長一致が良いと主張するグループと、
両方あるけれども。
検証せずに心証や宣伝や扇動を鵜呑みにするなんて、
なにが漢だ/女がすたる
/エンジニアの矜持は何処にやった/ハッカーじゃねぇ/ワナビーでも
(何でもいいので好きなの選んで下さい)、
と言うだけの話です。
変換結果を良くする事を目的として
アルゴリズムを変更したわけではありません。
取り敢えず、
前方n文節最長一致(nは任意、デフォルトでは3)を実装してみました。
本アルゴリズムのおおよそのイメージとしては、
学習能力を強化した、
VJE / 2005年頃までの ATOK / Canna? / Wnn?、
ぐらいになると思われます。
設計および実装上は、 前方2文節最長一致だろうが 前方4文節最長一致だろうが 前方8文節最長一致だろうが、 どうとでも選べる様にしてありますが、 面倒なので前方3文節最長一致のみしか動作確認していません。 ${HOME}/.anthy/conf に環境設定ファイルを書けば変更できます。
ついでに。
同環境設定ファイル ${HOME}/.anthy/conf にて、
文節構造のスコアリングを調整できます。
ここの値を変更する事で、
必殺パラメータを編み出す事が出来るかもしれません。
1点だけ、本来の 前方n文節最長一致とは実装を変えてあります。
文節数と全体長は一致するが
個別の文節の長さが違う物が何パターンか有る場合、
本来の 前方n文節最長一致では先頭文節が短い物を選択します(らしい)。
本 patch13 の実装では、
学習結果から得た文節を最優先とし、
学習結果から得た文節が無い場合は、
前述(patch12 パターン11)の
総合スコア(自立語のスコア × 文節構造のスコア)
の加重平均(先頭文節は高加重、後方文節は低加重)が高い物を選択します
(加重平均を使うのは、その方がプログラムの実装が楽だから)。
該当する学習結果が無く、スコアも同じ場合は、
本来のアルゴリズム通り先頭文節が短い物を選択します。
変更の根拠はありません、単なる思い付きです。
なお、前方n文節最長一致で複数の候補ができた時に
コーパスを使った解決を行わないのは、
現状の Anthy のコーパス情報は
個人の文体とは必ずしも一致しない問題があるのと、
コーパス情報を検索する方法が判らない為です
(文節区切りではコーパスを使用しませんが、
変換候補の並び替えでコーパスを使用しているか否かは不明です。
ソースコード読んで探すの面倒)。
patch13ptn17 より、
前方n文節最長一致で複数の候補ができた時に、
文節のコーパスを用いた解決を実装しました
(コーパス情報から利用頻度が高い単語を優先する)。
また、変換候補の並び替えの際には、
原作版通りコーパスを用いています。
疑問点:
付属語の遷移のスコアリングに於いて、
オリジナルおよび現状では weak 指定を含むか否かの2通りしか無いが、
システム辞書の頻度値の様な、多段階の指定ができた方が良いのだろうか。
それを始めると、
遷移グラフのメンテナンスをする方の負担が、
ただでさえ大変なのに、さらに爆発する問題が有るので、
積極的に乗り気にはなれないが。
付属語1つ毎に1%低下ルールを試した感じでは、
案外悪くない印象(あくまで印象なので、確証や物証は無い)
ではあったものの。
↑ anthy のレポジトリを見たら疑問は解決。
anthy-7??? までの Anthy では、
「:」が1回につき 1/2、「.」が1回につき 1/8、遷移確率を下げ、
複数回あるとそれだけ大きく下げていたが、
anthy-8?00 でコーパスを導入した際に、付属語グラフの仕様を変えて、
遷移確率はコーパスだけを使って算出し、
「.」と「:」は種別も回数も関係無く文節構造のスコアを 1/10 に下げるだけ、
に変更したらしい。
対比:
オリジナルの Anthy(ビタビアルゴリズム)だと、
例えて言うならば「後方∞文節 平均スコア最高」(……そのまんまかも)
あるいは「後方∞文節最長一致」
の様な挙動をしている様に感じる事がある。
日本語を左から右に書く感覚で見ていると、
何故そんな変換になったのか判らない誤変換がちょくちょくあるが、
右から左に見ながら計算機の処理を頭の中でシミュレートしてみると、
案外納得がいく誤変換だったりする事がある。
前方3文節最長一致だと文字通り左から右に処理していくので、
日本語を左から右に書く感覚で見ると、
文節区切るの早過ぎ、とか、遅過ぎ、とか、
感覚的にわかりやすい
(計算機の処理を頭の中でシミュレートした場合の話)。
ただ、かな漢字変換をする時に、
どんな変換がされるかなど一々考えないで変換する普通の人には、
どちらにせよ関係無い話。
結論:
プログラムの設定値や depgraph やシステム辞書の頻度情報などの、
手作業でのパラメータ調整で変換結果を最高にしようなんて無理、無謀。
オリジナルの Anthy にて、
「手作業で設定するヒューリスティックのパラメータ調整」
と言う方向性を捨てて、
「コーパスからパラメータを自動生成する」
と言う方向性を選んだのは、
至極真っ当。
ただ、不適切だったのは、
公募したコーパスが十分な品質と量になる事を前提とした点と、
個人の文体に合わせた調整機構(学習機能)が無いと言う運用上の点。
↑ コーパスの公募に関する点は、 初期の頃に vagus氏が危惧していた通り (http://vagus.seesaa.net/article/62333234.html) になってしまった様ですが (注:その当時の事は知らないので、 当時の開発関係者のブログや記事を読みかえした結果で書いています)。
Sun,21 Dec,2008 追記:
中古で出回っている辺りの Celeron 500MHz〜1.5GHz クラスや、
ネットブック Atom 1.0〜1.6GHz クラスや、
サブノート Core系 1.0〜1.6GHz クラスを前提にした場合。
新聞数年〜十年分くらいのコーパスを、まともに扱えるんですかね?。
コーパスだけで 100MB〜1GB くらいの容量になっちゃいますよ?。
変換精度が十分に高まる程コーパスを持つと負荷が高すぎて非実用的になり、
許容できる負荷程度にコーパスを減らすと変換精度が今の Anthy 程度になる、
かもしれない。
コーパスを使った変換を行う方面の理論では、この問題が解決できていません。
「コーパスからパラメータを自動生成する」と言う技術は、
10年早い技術なのかもしれない。
この手の「理論通り実装するには計算機の性能が足らない」と言う事を、
いわゆる学者と呼ばれる方々に言うと、相当の高確率で、
「ムーアの法則で性能は3年で2倍になるのだから、
数年も経てば問題は解決する」
と、判で押した様な回答だか文句だかが来ますので、
あらかじめ言っておきますと
……ほんと、あきれるくらいみんなそろってこう言いますけれど……、
一般人が1〜3年毎にパソコンを最新ハイエンド型に買い換えるなんて無理。
「計算機の性能に対するムーアの法則」それ自身に関しても、
現実世界では、
最近3〜5年くらい(おおむね2000〜2005年頃以降くらい)の計算機では
単純性能の向上が頭打ちになっています。
広告/広報/宣伝や論評などで
「ムーアの法則はまだ続いている」旨の主張がありますが、
HyperThreading で性能2倍、
デュアルコアならさらに性能2倍で
トリプルコアなら性能3倍で
クアッドコアなら性能4倍、
加えてマルチプロセサにすれば更に2倍/3倍/4倍でドン、
と言う計算をして、
「3年で2倍」を達成している裏事情が、勘定に入っていません
(それらの主張は、経営的/政治的/経済的な理由により、
故意に裏事情を無視している)。
備考:
本パッチの前方n文節最長一致の実装は、
信じられないほど豪快な手抜き実装をしている為、
本来の前方n文節最長一致とは次元が違うほど、処理が遅いです。
たぶん1〜3桁くらい遅い。
さすがに自分でも頭に来るほど遅かったので、
patch13B にて再実装しました。
注意:
オリジナルの Anthy が駄目とか悪いとかとは言っていません。
現実の運用に必ずしもそぐわない点がある、とは言っていますが。
注意の注意:
現実の運用にそぐわない点が多いとかそぐわない点だらけとは言っていません。
注意の注意の注意:
そぐわない点が有るのが良いとか悪いとかとは言っていません。
そんなのは単なる設計思想の違いです。
注意の注意の注意の注意:
その様な点/違いが存在している、とだけ言っています。
注意の注意の注意の注意の注意:
きりないな。
……、……、……。
しかし、原作のソースコードが、 よくこれだけの大量のパッチ当てに耐えたな。
patch13 の前方n文節最長一致の実装は、 信じられないほど豪快な手抜き実装をしている為、 本来の前方n文節最長一致とは次元が違うほど、処理が遅かった (後述のSun,15 Feb,2009:の項目を参照)。 たぶん本来の速度より1〜3桁くらい遅い筈。
ちょっと長めの文章を入力すると、 すぐに処理が遅くなるのに業を煮やして、 本 patch13B では、 前方n文節最長一致だけ最初から作り直してみた。
結果、patch13 よりも 1.3倍〜1桁くらい、速くなった (後述のSun,08 Mar,2009:の項目を参照。 使用した計算機は、日によって?測定結果が数割ずれる為、 ビタビの変換速度は変わっていないと言う前提で、 速くなった割合を算出した)。 前方4文節最長一致に設定してもビタビより2〜4割速い。 前方5文節最長一致に設定してもビタビより1〜3割速い。 それでも予想より数倍〜1桁遅かった。 読みが同長かつ同読みな異字で、 データを縮退させていない物は、 案外少ないのかもしれない。 あと、再帰処理をそのまま再帰呼び出しで実装したのが遅いのだろうか?。 メモリ消費量も patch13 の前方n文節最長一致より5割〜2桁減った、 前方3文節最長一致ならばビタビと同程度、 でも4とか5文節だとビタビより2倍〜1桁多い。
Anthy のデータ処理の構造はビタビに合わせて作られており、 データ構造を前方n文節最長一致に変換する処理が入る為、 前方n文節最長一致 専用の変換エンジンよりは、 どうしても遅いです。 前方n文節最長一致 専用の変換エンジンの場合、 文章の前方から順に文節区切り処理を行うのと同時に、 処理している部分に該当する内容のみ、 システム辞書や学習データを検索するらしい。 Anthy の場合、 一旦、文章全体から、全ての組み合わせの内容に対して、 システム辞書や学習データを検索してデータを構築してから、 文節区切り処理や変換候補生成を行っている。
文字コードのマッピングは、
原作の Anthy や iconv対応前の版では eucJP-MS ですが、
iconv対応版では EUC-JP(JIS X 0208/0212) に変更になります。
eucJP-MS に戻したい場合、
環境設定にて ANTHY_ENCODING_EUCJP_AS_EUCJPMS を指定して下さい。
なお、
各自の環境に於ける iconv が eucJP-MS 非対応の場合、戻せません
(例えば、OpenBSD の ports版 libiconv は非対応)。
「libiconv パッチ集(msyk氏)」
にある eucJP-MS 対応版を使用して下さい。
あるいは CP51932 にしたい場合は、
ANTHY_ENCODING_USERDEFINE 指定をした上で
「ANTHY_ENCODING_USERDEFINE_NAME CP51932」指定して下さい。
この場合も、各自の環境に於ける iconv が CP51932 対応である必要があります。
はたまた JIS X 0201 純正?変換にして YEN SIGN を U+00A5 にしたい方は、
eucJP0201? 対応の iconv(例えば HP-UX版)を使用し、
ANTHY_ENCODING_USERDEFINE 指定をした上で
「ANTHY_ENCODING_USERDEFINE_NAME eucJP0201」指定して下さい。
iconv対応前の場合、
波ダッシュを入力したつもりなのに実際にはチルダが入力されてしまう、
双柱を入力した(略)平行記号が(略)、
マイナス記号(略)横棒(略)、
エムダッシュ(略)水平線(略)、
と言う事があります。
これはマッピングが eucJP-MS になっているせいです。
また、
システム辞書や個人用単語辞書をテキストエディタで編集したり、
EUC-JP なロケールと UTF-8 なロケールを混在して
かな漢字変換を行ったりすると、
一部の記号が文字化けする事があります。
これは OSやアプリケーション等が、
EUC-JP のロケールに対して
JIS X 0208/0212 EUC-JP である事を前提に処理しているのに対して、
Anthy が eucJP-MS で応答しており、
同じ EUC-JP でも系列が食い違っている為です。
EUC-JP のマッピングを EUC-JP(JIS X 0208/0212) に変更する事により、
これらの問題を解消しています。
オリジナルの Anthy もしくは iconv対応前の版から、
iconv対応後の版に移行する場合、
個人用の単語辞書、個人用の学習データ、
インストール後のシステムの辞書、
全てに於いて、一部の文字の文字コードが変更になります。
全てのデータの文字コードを適切に変換するか、
iconv対応版をインストールする前に
個人用の単語辞書/個人用の学習データ/システムの辞書
全てを削除するか、
して下さい。
文字コードの変換方法は個別の環境によって異なる為、
一般的な変換方法をここで述べる事はできません。
ロケールとか
使っているフロントエンドソフトとか
辞書/学習の形式などによって、
どの変換を行うべきなのか/行わないべきなのかが異なるので、
iconv, nkf, qkc などでサクっと変換、と言う訳にはいきません。
問題になる文字は、
EUC-JP のマッピングを変更した事の副作用として、 ロケールを UTF-8 にして、 MSゴシック/MS明朝/みかちゃんフォント などの、 CP51932用フォントあるいは eucJP-MS用フォントを使用した場合、 一部の記号が文字化けします。 これは、 フォントのマッピングが違う、 もしくは Unicode の例示字体が間違っていた件を引きずっている為です。 メイリオフォント等の Unicode ver.3.1以降(ver.4.0以降?)対応/JIS X 0213対応の フォントに更新すれば、治ります、たぶん。
EUC-JP のマッピングが EUC-JP(JIS X 0208/0212) になった事に伴い、 EUC-JP にて JIS X 0212 補助漢字が使える様になります。 一般的な EUC-JP 対応の OS/X/アプリケーションなどでは、 環境設定等を変更する事無く使える筈です。 scim-anthy はソースを改造しないと駄目です (原作版 Anthy に忠実に合わせて?、EUC-JP-MS になっている為)。
EUC-JP にて JIS X 0213 第3・4水準漢字を使う事もできますが、
OS や X や ToolKit やアプリケーションなどが非対応である場合が多い為、
推奨できません。
手元で確認した範囲では、
GTK は JIS X 0213 EUC-JP 第3・4水準漢字に非対応でした。
また、
2007年よりも前の Solaris、
古めの GNU/Linux、
HP-UX や AIX などでは、
標準添付の iconv が JIS X 0213 EUC-JP 第3・4水準漢字に非対応の為、
JIS X 0213 EUC-JP 第3・4水準漢字 対応の
GNU libiconv 等を追加でインストールする必要があります。
EUC-JP にて第3・4水準漢字を使いたければ、
ANTHY_ENCODING_EUCJP0213 指定を行なって下さい。
各フロントエンドソフトに於いても変更が必要です。
uim-xim では anthy.scm の変更が必須です、
これ anthy.scm.0213(64KiB) を、
anthy.scm にリネームして適切な所に入れて下さい。
uim の GTK_IM_MODULE や QT_IM_MODULE では、
UTF-8 決め打ちなので、何もする事は有りません(何も出来ません)。
標準の scim では EUC-JP-MS を決め打ちしている為、
EUC-JISX0213 に非対応で、たぶんソース改造が必須です。
iiimf,im,ibus は未確認。
学習データを EUC-JP で保存している場合、
ANTHY_ENCODING_EUCJP_AS_* にて、
JIS X 0208/0212, JIS X 0213, eucJP-MS の
どの系列を使用するか選択できます。
但し、システム辞書と同じ系列にする必要があります。
なお、iconv が対応していない系列は使用できません。
iconv対応に伴い、
システム辞書の元データの文字コードの選択幅が広がりました。
set_input_encoding の後に iconv のエンコーディング名を書けば、
そのエンコーディングであると見なして読み込みます。
もっとも、対応している辞書の元データがありませんが。
EUC-KR とか EUC-CN とか EUC-TW とかの元データを
読み込んで辞書を作るとか言う無茶も出来ます。
よみがなをどうするのだと言う問題がありますが。
この機能を使用する場合、
iconvの流派やバージョンによって
エンコーディング名が異なる場合が有る事に注意されたし。
mkworddic/mkdic.c の set_input_encoding() に書いてある
エンコーディング名の省略名を使えば、
エンコーディング名の違いを可能な限りで吸収します。
なお、
システム辞書の文字コードは UTF-8 と EUC-JP系しか選択できません。
Anthy のシステム辞書の文字コードのフラグが、
UTF-8 と EUC-JP の2択しか無いので。
EUC-JP系の場合、
ANTHY_ENCODING_EUCJP_AS_* にて、
JIS X 0208/0212, JIS X 0213, eucJP-MS の
どの系列を使用するか選択できます。
iconv対応に伴い、 かな漢字変換フロントエンドとの 入出力文字コードの選択幅が広がりました。 ANTHY_ENCODING_* を参照。 もっとも、対応しているソフトウェアがありませんが。
原作版 Anthy にあった用例辞書 udict の機能が、 有効に機能していなかったり誤適用したりしているので、 原作版 udict の機能を丸ごと破棄して、 同様の機能を実装し直してみるテスト。
新仕様:
「学習の為に、入力した内容が丸々残るのは嫌」と言う場合、 FILE2_LIMIT を小さくすれば、 学習結果を「入力内容そのまま」から「文節単位の細切れ」に 分解するのが早くなります。 でも、細切れでも解析できますけれどね。 そういう事への本質的な回答は、 「暗号化ファイルシステム使えば?」 だとは思いますが、それは Anthy のやるべき仕事ではない。
# でもやっぱり、 FEP は MS-DOS用 WX2 が、 速度、軽さ、変換内容、バランス良く優秀だったと思う今日この頃……、 バグで時々フリーズしたけれどね。 次いで 松茸 かな。 VJE は操作や変換の癖が私には合わなかった。 ATOK は操作や変換の癖が私には合わなかった上に、 推論変換?予測変換?だか何だかと言った高機能化路線に行った挙句に 巨大化して重く遅くなったので嫌い。
原作版 Anthy の文節区切りアルゴリズムは
概して「ビタビアルゴリズム」と呼ばれているが、
本来?の名前は「MBR(Memory Based Reasoning)」らしい。
# MBR が文節区切りの確率情報群を生成する一連のアルゴリズムの名前。
# ビタビは文節区切りの確率情報群から最適解を探索するアルゴリズムの名前。
原作版 Anthy の統計的手法のアルゴリズムは、
過去に2回変更していて、今の中の人は3人目らしい。
HMM → MEMM → MBR。
学習のリミットを大きくして、学習情報の収集開始。
4ヶ月くらい学習させると、 学習辞書が 1MB くらい、 初動の変換所要時間が CoreDuo 1GHz(注:定格は1.6GHzだが発熱が酷いのでクロックを下げた) だと 1秒〜 2秒くらいで Athlon64 2GHz だと一瞬。 学習量の当初予想量とのずれが大きくなって来たので、 学習の上限量を調整。
半年くらい学習させると、 学習辞書が 2MB くらい、 初動の変換所要時間が CoreDuo 1GHz相当だと 2秒〜 4秒くらいで Athlon64 2GHz だと 0.5〜2秒くらい。
Anthy 累計学習量の変化(18KiB) グラフの左端が開始時、右端が約半年経過後、です。 横軸の数値は当方での管理番号で、日数ではありません。
10ヶ月経過。 変換結果がまた馬鹿になったと思ったら、 OCHAIRE 学習量が修正後の予想量をまた越えて消去されていた。 学習の上限量を再調整。 SUFFIX_HISTORY/CAND_HISTORY は当初予想量の 1/3 へ減量、 INDEPPAIR は当初予想量の 1/6 へ減量、 OCHAIRE は2度目の倍増、 PREDICTION は当初予想量の 1/2 へ減量、 UNKNOWN_WORD, EXPANDPAIR は当初予想のまま続行。
……、初動の変換が滅茶苦茶重い……。 CoreSolo 1.4GHz相当(注:コアを1つ止めてクロックをちょっと上げた) だと 2秒〜 5秒くらいで Athlon64 2GHz だと 1〜3秒くらい待たされる。 変換初動でいきなり待たされるので、 感覚的にはこの2〜3倍くらいの時間、待たされている気分になる。 ……。 メモリ上に展開されたキャッシュにヒットすれば速いのだが、 キャッシュに当たるのか、外れて読み込むのか不確かなので (一応、起動後初めて変換した時と、学習データを手作業で編集した場合のみ、 読み込みを行なって、それ以外はキャッシュにヒットする筈なのだが)、 結構フラストレーションが溜まる。
CAND_HISTORY は、 「直近8件」ではなく、 「スコアリング付き上位8件」にした方が良い様な気がする。 文節変換は句読点や記号で強制的に切り、 OCHAIRE への記録は 句読点や記号を入れない方が良いと思う。 通常の日本語の文章は、 句読点で区切れ、 文中に記号を含む場合は記号の部分で一単語になっている、 と思うし。 最近のネットやらケータイやらの特殊な文体だとアレだけれども。
個人学習データの OCHAIRE が無圧縮で 4MB 4万件とかある状態だと、 システム埋め込みのコーパス 800KB 1万件は、 個人の入力傾向と必ずしも一致していないであろうから、 むしろ邪魔になるのではないかと思った。 今度、コーパスを消したシステム辞書を作って試してみよう。 ……。 もしかして、大量の学習をさせた結果、変換結果が良くなったのって、 大量の OCHAIRE が支えていたりする?。 コーパス5万件目標、とか言う話もあったし。
システム埋め込みのコーパスを削除したシステム辞書に交換してから、 約1ヶ月。 変換状況に全く変化無し。 つまりは、大量の個人学習データがあれば、 システム埋め込みのコーパスは全く不要だと言う事か。
個人学習データから、 句読点と括弧と記号と数値を含む項目と、平仮名と片仮名だけからなる項目を、 全て削除してみた。 個人学習データのサイズが 2/3 くらいに縮まった。 変換結果は若干悪くなったが、 それよりもむしろ、 高々この程度の悪化で初動の変換所要時間が 2/3 に縮まった事の方が、 凄い嬉しい。
と言う事で、 前回追記時の 「システムのコーパスは不要」、 「句読点と記号は学習に不要」、の、 裏付けが取れた。
OCHAIRE 学習が、全くサチらない。サチる気配すら無い。 もしかして完全に同一の文章を入力しない限り、 ずっと増えつづけるの?。
変換結果と学習データのサイズと初動変換の遅延からすると、 学習保持量は、2/3 に縮めた後の現時点ぐらいが妥協点だと思われる。 保持量の上限をつけておかないと、 OCHAIRE なんぞは永遠に増えつづけそうな勢いだし。 あとは、学習の保持量を越えた分をどう消すかだが。 素の Anthy の様に、 バッファから超過分を適当 (ここでの「適当に」には、「適切に」の意味合いは含まれない) に消す、だと、 経験則から、消した直後の変換結果が凄く悪くなる。 代替案としては、 最後に利用したタイムスタンプ情報と、 利用した回数の頻度情報を持たせて、 それでスコアリングして点数の高い方を保持、 と言う辺りかなぁ。 スコアリング方法としては、 [{(現時刻)−(最後に利用した時刻)}÷(頻度)] が小さいほど高得点、辺りが手っ取り早いか?。 どうせ、 このスコアリングのチューニングを行うよりも、 学習量を増やした方が、 変換結果が格段に良くなるのだし。
学習させ始めてから1年経過。
Anthy 累計学習量の変化(21KiB) グラフの左端が開始時、右端が約1年経過後、です。 横軸の数値は当方での管理番号で、日数ではありません。 半年経過頃に UNKNOWN_WORD が大きく減っているのは、 手作業で誤学習を削除したから。 1年経過するちょっと前に OCHAIRE, CAND_HISTORY, PREDICTION が大きく減っているのは、 前述の学習結果の整理(手作業)をしたから。 1年経過するちょっと前に last-record1 が大きく減った直後に大きく増えているのは、 スコアリング用データを追加したため。
GTK_IM_MODULE=uim だと約5MBの学習データ読み込みに 約 7秒(Core 1.5GHz) や約 3秒(Athlon64 2.2GHz) かかるが、 GTK_IM_MODULE=xim だと 約 3秒(Core 1.5GHz) や約 1.5秒(Athlon64 2.2GHz) だった。 理由は不明。 コンパイル時に -pthreadオプションの有無で比べてみたが、 影響無し。
あと、 GTK_IM_MODULE=uim よりも GTK_IM_MODULE=xim の方が、 消費メモリが仮想サイズで 44MiB 実メモリで 37MiB 少ない。 GTK_IM_MODULE 駄目伝説は未だ健在か。
Athlon64 2.2GHz にて、 patch4の9月版だと GTK_IM_MODULE=uim で約 4秒、xim で約 2秒。 patch5の最新版だと GTK_IM_MODULE=uim で約 3秒、xim で約 1.5秒。 一応、速くなったらしい。 ただ、このくらいだと実感では変わっていない。
MALLOC_OPTIONS をどちらに設定しても、実感の速度は変わらない気がする。 ……。
% time env MALLOC_OPTIONS=avzj ./test/bin/anthy-agent.static --do-nothing % time env MALLOC_OPTIONS=avzJ ./test/bin/anthy-agent.static --do-nothing % time env MALLOC_OPTIONS=avjZ ./test/bin/anthy-agent.static --do-nothingで比較した所、jz だと1割速くなった。
↑ 学習データのファイルを、eucJP の場合と UTF-8 の場合で、 読み込み速度を比べてみたが、変わらなかった。
ビルドして動作確認したら、候補のスコアリングの計算を間違えていた場合の例。
学習の活用状況を調べてみた結果。
注意: 2008/08/22以前は、使用回数の記録が無く、最低1回使用した事しか判らないので除外した。 1回しか使用しなかった項目は前述以降の3ヶ月間だけの記録であり、 2回以上使用した項目はそれ以前を含む15ヶ月間の記録である。 その為、統計的な分析はできない事に注意。 また、途中で学習アルゴリズムを何度も変更し、また学習データの選別削除も行っている。 その点でも、統計的な分析はできない事に注意。 あくまで、方向性を読み取る事しかできない(真面目に考えると、それも危ういかも)。 EXPANDPAIR は、その学習アルゴリズム上、使用回数は出鱈目になるので、データ分析をしなかった。 INDEPPAIR は、その学習アルゴリズム上、減る事がある。また、使用回数の記録もあまり正確ではない。 2008/08/29-2008/11/17 増加件数 2回以上使用した件数 1回 2回 3回 4回 5回 6回 7回 8回 9回 10〜19回 20〜29回 それ以上 OCHAIRE2文節 5998 976 16% 5022 681 175 49 32 10 7 6 5 8 2 1 OCHAIRE3文節 3068 135 4% 2933 109 13 7 3 0 0 0 1 1 1 無し OCHAIRE4文節 1417 26 2% 1391 25 1 これ以上の回数、使用された項目は無し OCHAIRE学習の4文節は、費用対効果で見ると、削除対象と見なして良さそう。 2008/08/29〜2008/12/09 セクション 増加件数 2回以上使用した件数 1回 2 3 4 5 6 7 8 9 10〜19 20〜29 30〜 40〜 50〜∞ CAND_HISTORY 9233 4962 54% 4271 2292 917 493 301 185 142 91 80 291 87 32 14 37 INDEPPAIR 474 177 37% OCHAIRE 13159 1632 12% 11527 1132 279 84 55 24 14 11 5 19 6 2 0 1 うち OCHAIRE 2文節 8515 1385 16% 7130 942 246 73 49 24 12 11 4 17 4 2 0 1 うち OCHAIRE 3文節 4644 247 5% 4397 190 33 11 6 0 2 0 1 2 2 0 0 0 SUFFIX_HISTORY 66 51 77% UNKNOWN_WORD 163 93 57% 総数 23567 7077 30% 総量約1.4MiB OCHAIRE以外の学習は、案外役に立っているらしい。 OCHAIRE学習は、思った程役には立っていないらしい。 OCHAIRE3文節は諦めて、OCHAIRE2文節の有効活用を考えた方が良いのかも知れない。 # 3文節の場合、中間文節は、両端の区切りが確定した文節として、決定しやすい(誤変換しにくい)。 # 2文節の場合、中間の区切りは確定できるが、文節の両端の区切りの確定は行いにくい(誤変換しやすくなる)。 # 現状の Anthy の実装は、「両端の区切りが確定した文節の列挙」と言う形態になっているので、OCHAIRE2文節は扱いにくいのよ。
ここには掲載していない分析結果によると、
OCHAIRE学習に関して、
直近に学習した 3000〜3200件は2回以上使用される率が高く、
直近に学習した 3200件より古い学習データになると
2回以上使用される率が下がった。
ちょうど、3000〜3200件の点で折れるグラフになった。
但し、丁度その頃に、学習アルゴリズムの変更、
もしくは学習データの手動選別を行ったのかも知れない可能性が大いにある。
あるいは丁度その頃に、書く文章の種類が大きく変わったとか。
……3000〜3200件と言うと……、2008年10月中旬。
丁度 patch7/patch8 の初版が完成した頃……、
でもOCHAIREアルゴリズムは変更していない。
……ああ、丁度その頃に、書く文章の種類が、
仕様書の類から連絡/手配の類に変わったわ……、駄目じゃん。
Anthy 累計学習量の変化(16KiB) グラフの左端が開始時、右端が約1年半経過後、です。 横軸の数値は当方での管理番号で、日数ではありません。 時々学習量が大きく減っているのは、 手作業で誤学習の削除と学習内容の整理をしたから。 INDEPPAIR と PREDICTION が途中で消えているのは、 他の項目に変更したり、他の項目と統合したりした為。 2回、last-record1 が大きく増えているのは、 スコアリング用データを追加したため。
UNKNOWN_WORD と SUFFIX_HISTORY は、ついにほぼ飽和したっぽい。 PREFIX_HISTORY は、そもそも無いらしい。
CAND_HISTORY は微増(と言っても桁が大きいが)が続き、 OCHAIRE は飽和する気配全く無し。
INDEP_HISTORY と DEP_HISTORY と OCHAIRE.withDEP と OCHAIRE.withoutDEP は、 最近追加した学習項目の為、動向はまだ不明。
この記録を採った後に、 付属語無しOCHAIRE にまだ対応していなかった頃に採録した 付属語付きと思われる(語尾が平仮名になっている)OCHAIRE 3文節の 学習データの内、 利用頻度が1回の物(約14,000件、全OCHAIRE の約 28%)を削除、 利用頻度が1回以上の物(約500件、全OCHAIRE の約 1%)を 付属語無しOCHAIREに変換して再登録、 した。 付属語無しと思われる(語尾が漢字)OCHAIRE 3文節 (約3,500件、全OCHAIRE の約 7%)は、そのまま継続。 約32,000件、約64%は、OCHAIRE 2文節だった。
併せて、 先頭文節に自立語が付いていない可能性がある(ひらがなで始まっている) OCHAIRE 約2,300件 を削除。
これで、 6MBくらいまで肥大化していた学習データが、 4MB弱まで減った。
ふとした思い付きで、変換速度のベンチマークを採ってみた。
使用するのは anthy-9100h.patch13ptn19.2009212。 辞書・付属語グラフ・コーパスは 9100h標準品。 変換処理は anthy-agent --anonymous < data > /dev/null 変換結果が望んだ物であるか否かの判定はしない。 学習は、記録・反映ともに全て無効。但し、変換確定結果から記録すべきデータの抽出だけは行っている。 3回測って全消費時間が中央値だったデータを採用。 全 ユーザランド カーネル内 SHM data stack ページ コンテキスト 消費時間 消費時間 消費時間 使用量 使用量 使用量 割当回数 スイッチ回数 時間単位は秒 変換させる内容は、1文当たり2文節を 500件(単純に、普段の学習データから取り出した物) Athlon64 2.2GHz (FreeBSD/amd64 6.4-RELEASE-p3 GENERIC) CnQ無効 MALLOC_OPTIONS=AvzJ 無変換(-g3 -O0): 0.05 0.04 0.00 24kiB 433kiB 146kiB 395 15 ビタビ(-g3 -O0): 5.14 3.86 0.18 23kiB 818kiB 126kiB 1140 881 2文節最長一致(-g3 -O0): 3.52 2.86 0.17 23kiB 836kiB 127kiB 1105 660 3文節最長一致(-g3 -O0): 3.93 3.04 0.17 23kiB 846kiB 125kiB 2548 691 4文節最長一致(-g3 -O0): 4.02 3.25 0.18 23kiB 872kiB 127kiB 6992 744 変換させる内容は、1文当たり2文節を 500件(単純に、普段の学習データから取り出した物) Athlon64 2.2GHz (FreeBSD/amd64 6.4-RELEASE-p3 GENERIC) CnQ無効 MALLOC_OPTIONS=AvzJ 無変換(-g0 -O2): 0.04 0.04 0.00 22kiB 397kiB 153kiB 404 10 ビタビ(-g0 -O2): 2.25 1.76 0.21 19kiB 760kiB 126kiB 1115 474 2文節最長一致(-g0 -O2): 1.73 1.42 0.21 20kiB 787kiB 129kiB 1129 418 3文節最長一致(-g0 -O2): 1.77 1.46 0.29 19kiB 789kiB 126kiB 2759 419 4文節最長一致(-g0 -O2): 2.09 1.69 0.20 20kiB 828kiB 129kiB 7546 449 変換させる内容は、1文当たり10文節を 100件(同じ内容を100回) Athlon64 2.2GHz (FreeBSD/amd64 6.4-RELEASE-p3 GENERIC) CnQ無効 MALLOC_OPTIONS=AvzJ 無変換(-g0 -O2): 0.02 0.02 0.00 30kiB 432kiB 192kiB 387 4 ビタビ(-g0 -O2): 7.88 4.41 1.44 20kiB 1109kiB 129kiB 706 1243 2文節最長一致(-g0 -O2): 6.88 3.65 1.54 19kiB 1090kiB 126kiB 706 1190 3文節最長一致(-g0 -O2): 8.11 4.57 1.61 20kiB 1184kiB 129kiB 40786 1413 4文節最長一致(-g0 -O2): 36.12 20.82 5.05 20kiB 3671kiB 129kiB 737304 5822 変換させる内容は、1文当たり10文節を 100件(同じ内容を100回) Athlon64 2.2GHz (FreeBSD/amd64 6.4-RELEASE-p3 GENERIC) CnQ無効 MALLOC_OPTIONS=avjz 無変換(-g0 -O2): 0.01 0.01 0.00 30kiB 434kiB 192kiB 387 5 ビタビ(-g0 -O2): 7.88 4.36 1.34 20kiB 1110kiB 129kiB 706 1245 2文節最長一致(-g0 -O2): 6.72 3.67 1.35 19kiB 1090kiB 126kiB 706 1053 3文節最長一致(-g0 -O2): 7.64 4.28 1.58 20kiB 1174kiB 128kiB 40786 1339 4文節最長一致(-g0 -O2): 31.40 17.15 5.11 19kiB 3517kiB 127kiB 737304 4625 変換させる内容は、1文当たり2文節を 500件(単純に、普段の学習データから取り出した物) Core 1667MHz (FreeBSD/i386 6.4-RELEASE-p3 GENERIC) SpeedStep無効 MALLOC_OPTIONS=AvzJ 無変換(-g0 -O2): 0.07 0.06 0.00 17kiB 264kiB 142kiB 292 28 ビタビ(-g0 -O2): 6.62 5.09 1.46 15kiB 796kiB 126kiB 1012 2163 2文節最長一致(-g0 -O2): 5.34 3.80 1.48 15kiB 821kiB 126kiB 939 1791 3文節最長一致(-g0 -O2): 6.08 4.40 1.61 15kiB 851kiB 126kiB 1718 2153 4文節最長一致(-g0 -O2): 6.29 4.47 1.74 15kiB 1167kiB 126kiB 3349 2236 変換させる内容は、1文当たり10文節を 100件(同じ内容を100回) Core 1667MHz (FreeBSD/i386 6.4-RELEASE-p3 GENERIC) SpeedStep無効 MALLOC_OPTIONS=AvzJ 無変換(-g0 -O2): 0.05 0.04 0.00 19kiB 221kiB 153kiB 292 14 ビタビ(-g0 -O2): 17.25 13.65 3.42 15kiB 838kiB 126kiB 579 5560 2文節最長一致(-g0 -O2): 13.69 10.17 3.33 15kiB 832kiB 126kiB 578 4676 3文節最長一致(-g0 -O2): 18.18 14.42 3.52 15kiB 919kiB 126kiB 48743 6136 4文節最長一致(-g0 -O2): 104.28 98.07 4.74 15kiB 6718kiB 126kiB 232977 32470 結果: 短い文ならば、ビタビより前方n文節最長一致の方が、1〜2割、速いらしい。 長い文だと、前方n文節最長一致のn値が大きくなるにつれ、どんどん遅くなるらしい。長い文でも前方2文節最長一致ならばビタビより速いらしい。 前方3文節最長一致よりビタビの方が、1割?、メモリ消費量が少ないらしい。 -O2 でも、2文節の変換を1件、3〜5[ms] かかる。10文節だと 150〜200[ms] もかかってしまうらしい。 感想(根拠無しの思い付き): 短い文の時にビタビが遅いのは、使用していた時の感触通りだった。 前方n文節最長一致の処理時間が文の長さにもろに影響されるのも、使用していた時の感触通りだった。 前方n文節最長一致において、文の長さが長くなればなる程、ここまで遅くなるのは予想外だった。実装で手抜きしすぎたか。気合入れてちゃんと実装すれば、1〜3桁は速くなるとは思うのだけれど。 前方3文節最長一致のメモリ消費量が、明らかにビタビより多いのは予想外。やっぱり実装で手抜きしすぎたか。 全般に、思っていたよりも1桁〜2桁遅いので、計算量としては結構大きいらしい。前方n文節最長一致に関しては、なんというか実装で手抜きしすぎ。 備考: 本パッチの前方n文節最長一致の実装は、 「可能な単語の全組み合わせをn段連ねて全探索」 しかも 「文節区切り位置を1段決定する毎に、これまでの探索結果を全部捨てて再度全探索」 とかいう、凄い馬鹿げた実装になっている為、 本来の前方n文節最長一致とは次元が違うほど遅くなっています。たぶん1〜3桁くらい遅い。 # 本来の前方n文節最長一致の実装ならば、 # 読みが同じ長さの文節の探索は1回、 # 文節区切り位置を1段決定する毎に深さ方向に1段分延長、 # で良いが、 # 本パッチは全探索なので同読み異字の文節が多ければ多いほど……、 # しかも1段毎に全探索なので入力した文章が長ければ長いほど……。
patch13B にて、再度ベンチマーク。
使用するのは anthy-9100h.patch13Bptn20.2009308。 辞書・付属語グラフ・コーパスは 9100h標準品。 変換処理は anthy-agent --anonymous < data > /dev/null 変換結果が望んだ物であるか否かの判定はしない。 学習は、記録・反映ともに全て無効。但し、変換確定結果から記録すべきデータの抽出だけは行っている。 3回測って全消費時間が中央値だったデータを採用。 全 ユーザランド カーネル内 SHM data stack ページ コンテキスト 消費時間 消費時間 消費時間 使用量 使用量 使用量 割当回数 スイッチ回数 時間単位は秒 変換させる内容は、1文当たり2文節を 500件(単純に、普段の学習データから取り出した物) Core 1667MHz (FreeBSD/i386 6.4-RELEASE-p3 GENERIC) SpeedStep無効 MALLOC_OPTIONS=AvzJ 無変換(-g1 -O2): 0.08 0.07 0.00 16kiB 255kiB 128kiB 278 23 ビタビ(-g1 -O2): 8.06 6.04 1.94 15kiB 882kiB 126kiB 1038 2303 2文節最長一致(-g1 -O2): 5.43 3.84 1.53 15kiB 801kiB 126kiB 1016 1879 3文節最長一致(-g1 -O2): 5.87 4.16 1.64 15kiB 949kiB 126kiB 946 2030 4文節最長一致(-g1 -O2): 5.97 4.11 1.78 15kiB 829kiB 126kiB 1477 2162 変換させる内容は、1文当たり10文節を 100件(同じ内容を100回) Core 1667MHz (FreeBSD/i386 6.4-RELEASE-p3 GENERIC) SpeedStep無効 MALLOC_OPTIONS=AvzJ 無変換(-g1 -O2): 0.04 0.04 0.00 16kiB 244kiB 128kiB 278 14 ビタビ(-g1 -O2): 20.36 16.23 3.88 15kiB 848kiB 126kiB 595 6721 2文節最長一致(-g1 -O2): 14.19 10.45 3.59 15kiB 836kiB 126kiB 575 4552 3文節最長一致(-g1 -O2): 14.32 10.71 3.45 15kiB 859kiB 126kiB 581 4727 4文節最長一致(-g1 -O2): 14.56 10.83 3.57 15kiB 893kiB 126kiB 1221 4695 5文節最長一致(-g1 -O2): 15.45 11.69 3.57 15kiB 980kiB 126kiB 6791 5153
Anthy 累計学習量の変化(22KiB) グラフの左端が開始時、右端が約1年8ヶ月経過後、です。 横軸の数値は当方での管理番号で、日数ではありません。 管理番号152にて、小計算出期間を変えている。 時々学習量が大きく減っているのは、 手作業で誤学習の削除と学習内容の整理をしたから。 INDEPPAIR と PREDICTION が途中で消えているのは、 他の項目に変更したり、他の項目と統合したりした為。 時々 last-record1 が大きく増えているのは、 スコアリング用データを追加したため。
学習の利用効率と活用率。
注意: セクション毎に集計期間がバラバラなので、セクション同士の合算は、してはいけません。 2008/08/22以前は使用回数の記録が無く、最低1回使用した事しか記録していない。2008/08/22以降は、2回以上使用した場合に、その旨記録されている。 1回しか使用しなかったデータと、2回以上使用したデータは、集計期間が異なるので、統計的な分析はできない事に注意。 また、途中で学習アルゴリズムを何度も変更し、また学習データの選別削除も行っている。その点でも、統計的な分析はできない事に注意。 あくまで、方向性を読み取る事しかできない(真面目に考えると、それも危ういかも)。 直前に変換した内容を保持しておけば、活用出来るかもしれない学習: セクション 内容 種類で数えた場合 延べ利用回数で数えた場合 利用回数を 学習した 2回以上使用した 学習した 2回以上使用した 学習した 総数 総数 率 のべ回数 のべ回数 率 期間 DATA_SAMPLING 2I 前の文節の自立語 + この文節の自立語 2975 372 13% 3630 1027 28% 約2ヶ月半 DATA_SAMPLING 3I 前々文節の自立語 + 前文節の自立語 + この文節の自立語 1833 73 4% 1918 158 8% 約2ヶ月半 DATA_SAMPLING 2D 前の文節の付属語 + この文節の付属語 1977 494 25% 5648 4165 74% 約2ヶ月半 DATA_SAMPLING 3D 前々文節の付属語 + 前文節の付属語 + この文節の付属語 1566 181 12% 2199 814 37% 約2ヶ月半 DATA_SAMPLING 2ID 前の文節の自立語 + この文節の付属語 4070 666 16% 5638 2234 40% 約2ヶ月半 OCHAIRE 2.wIwD 前の文節 + この文節 4134 547 13% 5340 1753 33% 約3ヶ月 OCHAIRE 2.wIwoD 前の文節 + この文節の自立語 5338 966 18% 8140 3768 46% 約3ヶ月 OCHAIRE 2.woIwD 前の文節の付属語 + この文節 2261 272 12% 2817 828 29% 約2ヶ月半 OCHAIRE 2.woIwoD 前の文節の付属語 + この文節の自立語 2075 472 23% 3350 1747 52% 約2ヶ月半 OCHAIRE 2 OCHAIRE 2.* 系統の総計 42470 3641 9% 50299 11470 23% 約8ヶ月 OCHAIRE 3.wIwoD 前々文節 + 前の文節 + この文節の自立語 2714 149 5% 3145 580 18% 約3ヶ月 OCHAIRE 3.woIwoD 前々文節の付属語 + 前の文節 + この文節の自立語 1389 68 5% 1473 152 10% 約2ヶ月半 OCHAIRE 3 OCHAIRE 3.* 系統の総計 7762 459 6% 8655 1352 16% 約8ヶ月 変換を行う各文節内で閉じた学習: CAND_HISTORY 文節丸ごと 29042 8168 28% 73207 52333 71% 約8ヶ月 DEP_HISTORY 付属語のみ 1291 504 39% 9443 8656 92% 約2ヶ月半 EXPANDPAIR 文節区切り位置を伸ばした 958 277 29% 1704 1023 60% 約8ヶ月 INDEP_HISTORY 自立語のみ 3908 2086 53% 21577 19755 92% 約3ヶ月 PREFIX_HISTORY 接頭辞のみ 5 2 40% 22 19 86% 約1ヶ月半 SUFFIX_HISTORY 接尾辞のみ 176 90 51% 1058 972 92% 約8ヶ月 UNKNOWN_WORD 単語の自動登録(ひらがな語、カタカナ語) 623 96 15% 904 377 42% 約8ヶ月 「種類で数えた場合」の「2回以上使用した率」は、学習データの利用効率。 「延べ利用回数で数えた場合」の「2回以上使用した率」は、利用者の役に立った割合。 備考: DATA_SAMPLING セクションは、オプション ENABLE_DATASAMPLING を有効にした時のみ、記録される。
学習の利用効率と活用率。
セクション 内容 種類で数えた場合 延べ利用回数で数えた場合 利用回数を 学習した 2回以上使用した 学習した 2回以上使用した 学習した 総数 総数 率 のべ回数 のべ回数 率 期間 DATA_SAMPLING 2I 前の文節の自立語 + この文節の自立語 5440 833 15% 7127 2520 35% 約4ヶ月 DATA_SAMPLING 3I 前々文節の自立語 + 前文節の自立語 + この文節の自立語 3774 202 5% 4043 471 12% 約4ヶ月 DATA_SAMPLING 2D 前の文節の付属語 + この文節の付属語 3244 847 26% 10750 8353 78% 約4ヶ月 DATA_SAMPLING 3D 前々文節の付属語 + 前文節の付属語 + この文節の付属語 2953 440 15% 4524 2011 44% 約4ヶ月 DATA_SAMPLING 2ID 前の文節の自立語 + この文節の付属語 7026 1308 19% 10775 5057 47% 約4ヶ月 OCHAIRE 2.wIwD 前の文節 + この文節 7202 954 13% 9338 3090 33% 約4ヶ月半間 OCHAIRE 2.wIwoD 前の文節 + この文節の自立語 8785 1691 19% 13813 6719 49% 約4ヶ月半間 OCHAIRE 2.woIwD 前の文節の付属語 + この文節 5126 689 13% 6701 2264 34% 約4ヶ月間 OCHAIRE 2.woIwoD 前の文節の付属語 + この文節の自立語 4730 1120 24% 8601 4991 58% 約4ヶ月間 OCHAIRE 2 最後に利用したのが 29 Aug,2008 以前 18786 19 0% 18806 39 0% 不明 OCHAIRE 2 最後に利用したのが 30 Aug,2008 〜 26 Oct,2008 3447 444 13% 4054 1051 26% 約2ヶ月間 OCHAIRE 2 最後に利用したのが 27 Oct,2008 〜 23 Dec,2008 4496 581 13% 5334 1419 27% 約2ヶ月間 OCHAIRE 2 最後に利用したのが 27 Oct,2008 〜 23 Dec,2008 4496 581 13% 5334 1419 27% 約2ヶ月間 OCHAIRE 2 最後に利用したのが 24 Dec,2008 〜 19 Feb,2009 3543 460 13% 4257 1174 28% 約2ヶ月間 OCHAIRE 2 最後に利用したのが 19 Feb,2009 〜 17 Apr,2009 9386 1120 12% 11203 2937 26% 約2ヶ月間 OCHAIRE 2 最後に利用したのが 18 Apr,2009 〜 12 Jun,2009 14266 3098 22% 24672 13504 55% 約2ヶ月間 OCHAIRE 2 最後に利用したのが 19 Feb,2009 〜 14 Mar,2009 3105 318 10% 3608 821 23% 約1ヶ月間 OCHAIRE 2 最後に利用したのが 14 Mar,2009 〜 06 Apr,2009 4043 475 12% 4787 1219 25% 約1ヶ月間 OCHAIRE 2 最後に利用したのが 06 Apr,2009 〜 29 Apr,2009 5566 940 17% 7322 2696 37% 約1ヶ月間 OCHAIRE 2 最後に利用したのが 30 Apr,2009 〜 22 May,2009 6139 1205 20% 9113 4179 46% 約1ヶ月間 OCHAIRE 2 最後に利用したのが 22 May,2009 〜 12 Jun,2009 4799 1280 27% 11045 7526 68% 約1ヶ月間 OCHAIRE 2 OCHAIRE 2.* 系統の総計 53924 5722 11% 68326 20124 29% 約9ヶ月半 OCHAIRE 3.wIwoD 前々文節 + 前の文節 + この文節の自立語 4817 278 6% 5445 906 17% 約4ヶ月半 OCHAIRE 3.woIwoD 前々文節の付属語 + 前の文節 + この文節の自立語 2740 181 7% 2997 438 15% 約4ヶ月 OCHAIRE 3 OCHAIRE 3.* 系統の総計 11196 694 6% 12522 2020 16% 約9ヶ月半 CAND_HISTORY 文節丸ごと 31214 9278 30% 85939 64003 74% 約9ヶ月半 DEP_HISTORY 付属語のみ 1830 730 40% 16678 15578 93% 約4ヶ月 EXPANDPAIR 文節区切り位置を伸ばした 1087 347 32% 2043 1303 64% 約9ヶ月半 INDEP_HISTORY 自立語のみ 4855 2676 55% 34240 32061 94% 約4ヶ月半 PREFIX_HISTORY 接頭辞のみ 5 3 60% 44 42 95% 約3ヶ月 SUFFIX_HISTORY 接尾辞のみ 185 102 55% 1259 1176 93% 約9ヶ月半 UNKNOWN_WORD 単語の自動登録(ひらがな語、カタカナ語) 632 96 15% 913 377 41% 約9ヶ月半
延べ利用回数での利用効率から言うと、
PREFIX_HISTORY, SUFFIX_HISTORY,
INDEP_HISTORY, DEP_HISTORY
の4種類は9割を越える圧倒的な利用効率で、
CAND_HISTORY はちょっと落ちて7割だが、
実際の変換では CAND_HISTORY で救われる事が結構有り、
その事は利用効率の数字には出てこない。
そんなこんなで、この辺りは削除しない。
UNKNOWN_WORD の利用効率は4割だが、
先の nosuke氏のスパーギアの件みたいな事の対策としては外せない。
未知の単語は必ず全て単語登録するならば、
UNKNOWN_WORD は完全に不要になり、消しても構わないのだが。
一般利用者の事を考えると、それは無理だろう。
EXPANDPAIR は……、現状の学習の仕様だと、
無くてもいいとは思うのだけれども、
ビタビ絡みでどうなっているのかよく判っていないので、
迷う所。
UNKNOWN_WORD や OCHAIRE で同等の機能が効いている筈なのだが、
EXPANDPAIR を消しても 60KiB くらいの節約にしかならないし……。
消すか。
OCHAIRE 3文節は、部分を見ても全般を見ても、
利用効率が低い。
さらに、
OCHAIRE 2文節での代替も効いている筈。
時々、
OCHAIRE3文節であれば誤適用しないが
OCHAIRE2文節だったので誤適用した、
と言う事も起きるけれども、効率悪すぎ。
削除する事にした。
これで1〜2割は削減できた。
思ったより減らないな。
OCHAIRE 2文節は、迷う所。
「末尾文節は自立語のみ取り出して付属語は削除して学習」
(wIwoD と woIwoD)にすると、
効率がグッと上がり5〜6割となるが、
付属語違いに対する誤適用がちょくちょく有り、
特に woIwoD はあからさまに誤適用が出てくるので、
一般利用者には勧めにくい。
そうなってくると、種別で削除するのはやめて、
時期で削除を考えてみる。
とすると、どうも、
最後に利用したのが直近3ヶ月以内である学習データの場合は
利用効率が平均を越えて3〜7割あり、
最後に利用したのがもっと古くなると2〜3割に落ちている。
何故かは不明だが、
取り敢えずこの辺りで切るのが良さそう。
DATA_SAMPLING は、現在は学習に利用しておらず、
実装する気も無い(実装が面倒)。
でも、見た感じ、
「前の文節の付属語 + この文節の付属語」は
利用効率が圧倒的に高く7〜8割も有り
OCHAIRE を確実に上回っている、
「前々文節の付属語 + 前文節の付属語 + この文節の付属語」と
「前の文節の自立語 + この文節の付属語」は
4〜5割と OCHAIRE 2文節と同等の効率で、
「前の文節の自立語 + この文節の自立語」でも
3〜4割と OCHAIRE 2文節に匹敵している。
学習として実装すると、
OCHAIRE よりも学習が適用できる率が高いもしくは匹敵するので、
案外いけるのかもしれない。
ただ、
OCHAIRE は文節の内容を丸ごと確保しているが、
こちらは文節の内容の特定部分だけなので、
誤適用とか不確実さとかは大きいかもしれない。
結局、
DATA_SAMPLING 全部と、OCHAIRE 3文節全部と、EXPANDPAIR 全部と、
OCHAIRE 2文節の古い物を削除で、
6割削減して 3.6MiB くらいにまで縮まり、
だいぶ楽になった。
変換結果は、特段変化した感じはしない。
でも、やっぱりまだちょっと遅い。
速度面からは、
一般的には 1MiB くらいが妥当な所で、2MiB が上限、3MiB が限界かなぁ。
学習の効果を考えると、2〜5MiB は欲しいのだが。
変換所要時間(変換速度)の比較。
1文の変換内容(10文節):
「tatoebakonnnakanzinobunsyouga10bunnsetutonarunaiyouwohenkansurutokekkahadounarunodarou.(space)」
変換内容を平仮名表記:
「たとえばこんなかんじのぶんしょうが10ぶんせつとなるないようをへんかんするとけっかはどうなるのだろう。」
期待する変換結果:
「(3 ((UL RV) "例えば" 0 3) ((UL) "こんな感じの" 0 4) ((UL) "文章が" 0 6) ((UL) "10文節となる" 0 3) ((UL) "内容を" 0 5) ((UL) "変換すると" 0 5) ((UL) "結果は" 0 7) ((UL) "どうなるのだろう" 0 2) ((UL) "。" 0 3))」
プログラム内で同じ変換を1000回(Canna,FreeWnn,sj3)もしくは 100回(Anthy)行い、
その処理に要する時間を計測し、1回当たりの変換時間を算出した。
変換結果が望んだ通りになっているか否かの判定は行わない。
約2.6秒 月面との通信での遅延時間(往復)。 約1.3秒 月面との通信での遅延時間(片道)。 930msec のび太が立った状態から昼寝を開始するのに必要な時間(初期の連載を除く)。 239msec 静止衛星との通信での遅延時間(往復)。 200msec チーラの一日 139msec Anthy拙作パッチ版(追加辞書有効)で、1文の内容を変換するのに要する時間。変換内容を読点で無理矢理分割した場合。MBRビタビ(-g3 -O0)、PentiumD 3.2GHz OpenBSD44R。 129msec Anthy拙作パッチ版(追加辞書有効)で、1文の内容を変換するのに要する時間。変換内容を読点で無理矢理分割した場合。前方4文節最長一致(-g3 -O0)、PentiumD 3.2GHz OpenBSD44R。 129msec Anthy拙作パッチ版(追加辞書有効)で、1文の内容を変換するのに要する時間。変換内容を読点で無理矢理分割した場合。前方3文節最長一致(-g3 -O0)、PentiumD 3.2GHz OpenBSD44R。 128msec Anthy拙作パッチ版(追加辞書有効)で、1文の内容を変換するのに要する時間。変換内容を読点で無理矢理分割した場合。前方2文節最長一致(-g3 -O0)、PentiumD 3.2GHz OpenBSD44R。 119msec 静止衛星との通信での遅延時間(片道)。 111msec Anthy拙作パッチ版(追加辞書有効)で、1文の内容を変換するのに要する時間。MBRビタビ(-g3 -O0)、PentiumD 3.2GHz OpenBSD44R。 107msec Anthy拙作パッチ版(追加辞書有効)で、1文の内容を変換するのに要する時間。変換内容を読点で無理矢理分割した場合。MBRビタビ(-g3 -O2)、PentiumD 3.2GHz OpenBSD44R。 102msec Anthy拙作パッチ版(追加辞書有効)で、1文の内容を変換するのに要する時間。変換内容を読点で無理矢理分割した場合。前方4文節最長一致(-g3 -O2)、PentiumD 3.2GHz OpenBSD44R。 101msec Anthy拙作パッチ版(追加辞書有効)で、1文の内容を変換するのに要する時間。変換内容を読点で無理矢理分割した場合。前方3文節最長一致(-g3 -O2)、PentiumD 3.2GHz OpenBSD44R。 101msec Anthy拙作パッチ版(追加辞書有効)で、1文の内容を変換するのに要する時間。変換内容を読点で無理矢理分割した場合。前方2文節最長一致(-g3 -O2)、PentiumD 3.2GHz OpenBSD44R。 96msec Anthy拙作パッチ版(追加辞書有効)で、1文の内容を変換するのに要する時間。前方4文節最長一致(-g3 -O0)、PentiumD 3.2GHz OpenBSD44R。 93msec Anthy拙作パッチ版(追加辞書有効)で、1文の内容を変換するのに要する時間。前方3文節最長一致(-g3 -O0)、PentiumD 3.2GHz OpenBSD44R。 93msec Anthy拙作パッチ版(追加辞書有効)で、1文の内容を変換するのに要する時間。前方2文節最長一致(-g3 -O0)、PentiumD 3.2GHz OpenBSD44R。 83msec Anthy拙作パッチ版(追加辞書有効)で、1文の内容を変換するのに要する時間。MBRビタビ(-g3 -O2)、PentiumD 3.2GHz OpenBSD44R。 74msec Anthy拙作パッチ版(追加辞書有効)で、1文の内容を変換するのに要する時間。前方4文節最長一致(-g3 -O2)、PentiumD 3.2GHz OpenBSD44R。 72msec Anthy拙作パッチ版(追加辞書有効)で、1文の内容を変換するのに要する時間。前方3文節最長一致(-g3 -O2)、PentiumD 3.2GHz OpenBSD44R。 72msec Anthy拙作パッチ版(追加辞書有効)で、1文の内容を変換するのに要する時間。前方2文節最長一致(-g3 -O2)、PentiumD 3.2GHz OpenBSD44R。 64msec Anthy-9100h原作版(通常辞書のみ) + alt-depgraph-090525 で、1文の内容を変換するのに要する時間。ビタビ(-g3 -O0)、PentiumD 3.2GHz OpenBSD44R。 64msec Anthy-9100h原作版(通常辞書のみ)で、1文の内容を変換するのに要する時間。MBRビタビ(-g3 -O0)、PentiumD 3.2GHz OpenBSD44R。 63msec Anthy-9100h原作版(通常辞書のみ)で、1文の内容を変換するのに要する時間。変換内容を読点で無理矢理分割した場合。MBRビタビ(-g3 -O0)、PentiumD 3.2GHz OpenBSD44R。 50msec 蒸着。 44msec Anthy-9100h原作版(通常辞書のみ) + alt-depgraph-090525 で、1文の内容を変換するのに要する時間。MBRビタビ(-g3 -O2)、PentiumD 3.2GHz OpenBSD44R。 43msec Anthy拙作パッチ版(Sat,08 Oct,2011)(追加辞書有効)で、1文の内容を変換するのに要する時間。MBRビタビ(-g3 -O3)、Phenom 2.0GHz OpenBSD48R/amd64。 43msec Anthy-9100h原作版(通常辞書のみ)で、1文の内容を変換するのに要する時間。MBRビタビ(-g3 -O2)、PentiumD 3.2GHz OpenBSD44R。 43msec Anthy-9100h原作版(通常辞書のみ)で、1文の内容を変換するのに要する時間。変換内容を読点で無理矢理分割した場合。MBRビタビ(-g3 -O2)、PentiumD 3.2GHz OpenBSD44R。 39msec Anthy拙作パッチ版(Sat,08 Oct,2011)(追加辞書有効)で、1文の内容を変換するのに要する時間。MBRダイクストラ2コアモード(-g3 -O3)、Phenom 2.0GHz OpenBSD48R/amd64。 33msec フレーム速度1/30での1フレーム。 18msec Anthy拙作パッチ版(Sat,08 Oct,2011)(追加辞書有効)で、1文の内容を変換するのに要する時間。MBRビタビ(-g3 -O3)、Core i5 2.4GHz FreeBSD90B3/amd64。 17msec フレーム速度1/60での1フレーム。 17msec Anthy拙作パッチ版(Sat,08 Oct,2011)(追加辞書有効)で、1文の内容を変換するのに要する時間。MBRダイクストラ2コアモード(-g3 -O3)、Core i5 2.4GHz FreeBSD90B3/amd64。 16.667msec チーラの一時間 13msec Anthy拙作パッチ版(Sat,08 Oct,2011)(追加辞書有効)で、1文の内容を変換するのに要する時間。文節数最小(-g3 -O3)、Phenom 2.0GHz OpenBSD48R/amd64。 12msec Anthy拙作パッチ版(Sat,08 Oct,2011)(追加辞書有効)で、1文の内容を変換するのに要する時間。前方3文節最長一致(-g3 -O3)、Phenom 2.0GHz OpenBSD48R/amd64。 8.69msec Canna-3.5b2 + alt-cannadicのgcanna(anthyの通常辞書とほぼ同量)で、1文の内容を変換するのに要する時間。変換内容を読点で無理矢理分割した場合。-g3 -O2、PentiumD 3.2GHz OpenBSD44R。 8.00msec Anthy拙作パッチ版(Sat,08 Oct,2011)(追加辞書有効)で、1文の内容を変換するのに要する時間。文節数最小(-g3 -O3)、Core i5 2.4GHz FreeBSD90B3/amd64。 7.40msec Anthy拙作パッチ版(Sat,08 Oct,2011)(追加辞書有効)で、1文の内容を変換するのに要する時間。前方3文節最長一致(-g3 -O3)、Core i5 2.4GHz FreeBSD90B3/amd64。 7.16msec Canna-3.5b2(Canna標準辞書)で、1文の内容を変換するのに要する時間。変換内容を読点で無理矢理分割した場合。-g0 -O2、PentiumD 3.2GHz OpenBSD44R。 6.63msec Canna-3.5b2 + alt-cannadicのgcanna(anthyの通常辞書とほぼ同量)で、1文の内容を変換するのに要する時間。-g3 -O2、PentiumD 3.2GHz OpenBSD44R。 5.47msec Canna-3.5b2(Canna標準辞書)で、1文の内容を変換するのに要する時間。-g0 -O2、PentiumD 3.2GHz OpenBSD44R。 3.69msec FreeWnn-1.1.1-a021(FreeWnn標準辞書)で、1文の内容を変換するのに要する時間。-g3 -O0、PentiumD 3.2GHz OpenBSD44R。 3.13msec FreeWnn-1.1.1-a021(FreeWnn標準辞書)で、1文の内容を変換するのに要する時間。-g3 -O2、PentiumD 3.2GHz OpenBSD44R。 1.389msec チーラの十分 0.94msec sj3-2.0.1.23(ネットワークソケット接続モード)(追加辞書でanthyの通常辞書の4割くらいの量)で、1文の内容を変換するのに要する時間。-g0 -O0、PentiumD 3.2GHz OpenBSD44R。 0.88msec sj3-2.0.1.23(ファイルソケット接続モード)(追加辞書でanthyの通常辞書の4割くらいの量)で、1文の内容を変換するのに要する時間。-g0 -O0、PentiumD 3.2GHz OpenBSD44R。 0.81msec sj3-2.0.1.23(ネットワークソケット接続モード)(sj3標準辞書)で、1文の内容を変換するのに要する時間。-g0 -O0、PentiumD 3.2GHz OpenBSD44R。 0.74msec sj3-2.0.1.23(ファイルソケット接続モード)(sj3標準辞書)で、1文の内容を変換するのに要する時間。-g0 -O0、PentiumD 3.2GHz OpenBSD44R。 0.63msec sj3-2.0.1.23(ネットワークソケット接続モード)(追加辞書でanthyの通常辞書の4割くらいの量)で、1文の内容を変換するのに要する時間。-g0 -O2、PentiumD 3.2GHz OpenBSD44R。 0.57msec sj3-2.0.1.23(ファイルソケット接続モード)(追加辞書でanthyの通常辞書の4割くらいの量)で、1文の内容を変換するのに要する時間。-g0 -O2、PentiumD 3.2GHz OpenBSD44R。 0.53msec sj3-2.0.1.23(ネットワークソケット接続モード)(sj3標準辞書)で、1文の内容を変換するのに要する時間。-g0 -O2、PentiumD 3.2GHz OpenBSD44R。 0.52msec sj3-2.0.1.23(ネットワークソケット接続モード)(追加辞書でanthyの通常辞書の4割くらいの量)で、1文の内容を変換するのに要する時間。変換内容を読点で無理矢理分割した場合。-g0 -O0、PentiumD 3.2GHz OpenBSD44R。 0.48msec sj3-2.0.1.23(ファイルソケット接続モード)(sj3標準辞書)で、1文の内容を変換するのに要する時間。-g0 -O2、PentiumD 3.2GHz OpenBSD44R。 0.46msec sj3-2.0.1.23(ファイルソケット接続モード)(追加辞書でanthyの通常辞書の4割くらいの量)で、1文の内容を変換するのに要する時間。変換内容を読点で無理矢理分割した場合。-g0 -O0、PentiumD 3.2GHz OpenBSD44R。 0.46msec sj3-2.0.1.23(ネットワークソケット接続モード)(sj3標準辞書)で、1文の内容を変換するのに要する時間。変換内容を読点で無理矢理分割した場合。-g0 -O0、PentiumD 3.2GHz OpenBSD44R。 0.41msec sj3-2.0.1.23(ファイルソケット接続モード)(sj3標準辞書)で、1文の内容を変換するのに要する時間。変換内容を読点で無理矢理分割した場合。-g0 -O0、PentiumD 3.2GHz OpenBSD44R。 0.36msec sj3-2.0.1.23(ネットワークソケット接続モード)(追加辞書でanthyの通常辞書の4割くらいの量)で、1文の内容を変換するのに要する時間。変換内容を読点で無理矢理分割した場合。-g0 -O2、PentiumD 3.2GHz OpenBSD44R。 0.32msec sj3-2.0.1.23(ネットワークソケット接続モード)(sj3標準辞書)で、1文の内容を変換するのに要する時間。変換内容を読点で無理矢理分割した場合。-g0 -O2、PentiumD 3.2GHz OpenBSD44R。 0.30msec sj3-2.0.1.23(ファイルソケット接続モード)(追加辞書でanthyの通常辞書の4割くらいの量)で、1文の内容を変換するのに要する時間。変換内容を読点で無理矢理分割した場合。-g0 -O2、PentiumD 3.2GHz OpenBSD44R。 0.27msec sj3-2.0.1.23(ファイルソケット接続モード)(sj3標準辞書)で、1文の内容を変換するのに要する時間。変換内容を読点で無理矢理分割した場合。-g0 -O2、PentiumD 3.2GHz OpenBSD44R。 0.116msec チーラの一分
ネットブックだと、この 2.5〜3倍くらいかかると思う。
Anthy だとたぶん 160〜300ms くらい。
Android携帯や iPhone携帯だと、この 12〜16倍以上はかかるのではないかと思われる。
Anthy だともしかしたら 750ms〜約2秒。
拙作パッチで5割増〜2倍も遅くなっているのは、
変換内容への学習の適用と、変換結果からの学習の抽出にて、
大幅に変更(もしかしたら木構造データベース処理部以外は全部書き変えたかも)し、
大量の文字列の取り出し/連結/分割を行う様になったのが効いているのではないかと思われる。
# anthy の設計仕様では、文字列の取出/連結/分割の操作1回に付き malloc() が2回と free() が2回付いてくるが、これの負荷が高い。
Thu,09 Jul,2009 追記:
Canna35b2 の変換所要時間を計測。なんとなく体感してはいたが、やっぱり速い。但し変換結果はまるで出鱈目だった。
「|タトエバコンナカンジノブンショウガ10ブンセツトナルナイヨウ|を|変換すると|結果|波動|奈留のだろう。|」
読点を突っ込んでようやくそれっぽくなったが。
「|例えば、|こんな|漢字の、|文章が、|10|文節となる、|内容を、|変換すると、|結果は、|どう|奈留のだろう。|」
Wed,09 Sep,2009 追記:
拙作パッチ版の測定対象を
anthy-9100h.patch13Bptn23.iconv.alt-depgraph-090712 に改訂。
「|例えば|こんな感じの|文章が|10文節と|なる|内容を|変換すると|結果は|どうなるのだろう|。|」
「|例えば|、|こんな感じの|、| 文章が|、|10文節と|なる|、|内容を|、|変換すると|、|結果は|、|どうなるのだろう|。|」
Thu,10 Sep,2009 追記:
sj3 の計測結果を追加。
追加辞書に使用した物は、
こちら
「ArtRecords - unixの日本語環境構築日記:) 賢いかな漢字変換システム Sj3」
の visual+.dic.gz。
追加辞書にて Canna や Anthy なみの大きな辞書を使用せず、
Canna や Anthy の半分以下の大きさの辞書でしか試していないのは、
sj3 は辞書の登録可能単語数の上限が小さいらしいので。
変換結果は、
「たとえばこんな漢字の文章が10分説となる内容を変換すると結果はどうなるのだろう.」
「たとえば,こんな漢字の,文章が,10分説となる,内容を,変換すると,結果は,どうなるのだろう.」
どこで文節を区切ったかの見方が判らん。
Thu,10 Sep,2009 追記:
FreeWnn の計測結果を追加。
変換結果は、
「|例えば|こんな|漢字の|文章が|10|文節となる|内容を|変換すると|結果|波動|なるのだろう。|」
Thu,10 Jul,2009 追記:
canfep の出力から tty 制御用のエスケープシーケンスの山を削除したら
3倍速くなったので、Canna35b2 の変換所要時間を測定し直し。
結論:
体感していた通り、Anthy の変換は遅い。
ただ、Canna や FreeWnn は速いと言っても、
連文節の区切りを覚えてくれないから……。
sj3 は何故こんなにも速いのか不思議なのと、
辞書の登録可能単語数の上限が小さいのがどう効いてくるか……。
それから、連文節の区切りの学習は有るらしい。
Anthy 累計学習量の変化(18KiB)
Anthy 累計学習量の変化(18KiB)
●変換してみた例1 ・学習データでの関連項目(OCHAIREは全く学習無し、CAND_HISTORYは断片的に学習済み) --- OCHAIRE --- CAND_HISTORY +たとえば O1 12 "例えば" T1 F5 +この O1 14 "この" T1 F14 +ような O1 32 "様な" T1 F25 +にほんご O1 17 "日本語" T1 F10 +へんかんの O1 16 "変換の" T1 F15 +れいに O1 3 "例に" T1 F2 +おいて O1 5 "於いて" O1 2 "置いて" O1 1 "おいて" T1 F7 +は O1 6 "は" O1 7 "派" O1 1 "波" O1 1 "端" T1 F8 --- ・変換する文字列 tatoebakonoyounanihongohenkannnoreinioiteha ・学習データが無い場合, 変換所要時間 valgrind上で約1.5〜2秒 例えば|子のような|日本語|変換の|れいにおいては ・patch11, 変換所要時間 valgrind上で約1.5〜2秒 例えば|子のような|日本語|変換の|れいにおいては ・patch12 pattern7, 変換所要時間 valgrind上で約1.5〜2秒 例えば|この|様な|日本語|変換の|例に|於いて|は ・patch12 pattern8 Fri,07 Nov,2008版, 変換所要時間 valgrind上で約2.5〜3秒 例えば|この|様な|日本語|変換の|例に|於いて|は ・patch12 pattern8 Sat,08 Nov,2008版, 変換所要時間 valgrind上で約1.5〜2秒 例えば|この|様な|日本語|変換の|例に|於いて|は ・patch13, 変換所要時間 valgrind上で約1秒 例えば|この様な|日本語|変換の|れいにおいては ・patch12 pattern8, OCHAIREは未学習のまま、「この様な」と「於いては」を CAND_HISTORY で学習後 例えば|この様な|日本語|変換の|例に|於いては ・結論 patch12 パターン9までの場合、OCHAIRE未学習の変換内容に対して、CAND_HISTORYの学習結果に由来した文節区切りが一応反映されている。 ただ、CAND_HISTORYの反映が強すぎて副作用が大きく、パターン10で CAND_HISTORYの反映を弱くしたので、ほとんど反映されなくなった筈。 ビタビから前方n文節最長一致にした事で、1.5〜2倍くらいに速くなったらしい?。 「れいにおいては」は、depgraph/noun.depword の「名詞」+「において」+「は」で自動生成された meta_word らしい。 ●変換してみた例2 ・学習データでの関連項目(OCHAIREは全く学習無し、CAND_HISTORYは断片的に学習済み) --- OCHAIRE ADD "OCHAIRE" S"ひんどじょうほう" N2 N3 S"頻度" N5 S"情報" T1 F5 ADD "OCHAIRE" S"じょうほうや" N2 N5 S"情報" N1 S"や" T1 F3 ADD "OCHAIRE" S"ひんどじょうほうや" N3 N3 S"頻度" N5 S"情報" N1 S"や" T1 F2 --- CAND_HISTORY ADD "CAND_HISTORY" S"ひんど" O1 N32 S"頻度" T1 F27 ADD "CAND_HISTORY" S"じょうほう" O1 N26 S"情報" T1 F19 ADD "CAND_HISTORY" S"や" O1 N7 S"や" T1 F5 ADD "CAND_HISTORY" S"やら" O1 N5 S"やら" T1 F5 ADD "CAND_HISTORY" S"ら" O1 N1 S"等" T1 F1 --- ・変換する文字列 nohindozyouhouyara ・patch12 pattern9 の|頻度|情報|や|等 ・patch12 pattern10 の|頻度|情報やら ・patch13 の|頻度|情報|やら ・結論 OCHAIRE末尾文節に対して CAND_HISTORY学習結果による対抗が想定通り機能している。 ビタビだと枝刈りと検索評価が前方から行われるとは限らない為、 OCHAIRE由来の「や|等」を CAND_HISTORY由来の「やら」で上書きした後に、 システム辞書由来の「情報やら」で上書きしているらしい。 前方n文節最長一致だと前方から検索するので、OCHAIRE由来の「や|等」を CAND_HISTORY由来の「やら」で上書きして、終わり。 ●備考 文の途中から望まない形で CAND_HISTORY が一致する場合を試さないと patch11 と patch12 の比較が不十分だし、 文の途中から望まない形で OCHAIRE が一致する場合を試さないと パターン7と8の違いが判らないのだが、 例文が思いつかない。 目的の文「ABCが123でdefした。」に対して、 OCHAIRE学習として 「BCが | 123で | defした」 「123で | defした」 を持っていた場合、オリジナルの Anthy 及びパターン7までの patch12 の場合、 「A | BCが | 123で | defした | 。」 としか区切らない(区切れない)筈だが、 パターン8なら最終の文節区切り判定の段階で 「A | BCが | 123で | defした | 。」 「ABC | が | 123で | defした | 。」 「ABCが | 123で | defした | 。」 が得られる筈なのだが。どれを選ぶのかまでは知らん。
コーパスの例文に
|いったら|いい| |行ったら|いい|
|きにいる|はずよ| |気に入る|筈よ|
|こっちゃ|ない| |こっちゃ|ない|
の3つを追加し、
かつ「|こっちゃ|ない|」が
『「#T35 こっちゃ」|「#KY な」「付属語:い」』として認識された場合、
「へんかんがようい」の変換結果が
「|変|閑雅よ|うい|」(|へん|かんがよ|うい|)になります。
例文に
|へんかんが|ようい| |変換が|容易|
を追加しても、
「へんかんがようい」の変換結果は
「|変|閑雅よ|うい|」(|へん|かんがよ|うい|)のまま変わりません。
なお、anthy のバージョンや辞書の構成や作業環境などにより、
「|こっちゃ|ない|」が
『「#R5 こ」「付属語:っちゃ」|「#T35 ない」』等と認識される事があり、
この場合は上記の現象は発現しません。
「|行ったら|いい|」から『|A Se 付属語「い」|』が、
「|気に入る|筈よ|」から『|Ve Se|Ne Se 付属語「よ」|』が、
抽出され、コーパスのデータベースに登録される。
「|こっちゃ|ない|」に関しては、
『|Ne Se|Ne Se 付属語なし|』と認識する場合と、
『|Ne Se|A Se 付属語「い」|』と認識する場合と、別れるが、
make update_params にて
「|行ったら|いい|」から『|A Se 付属語「い」|』を登録した後に
make update_params2 を行うと、
『|Ne Se|A Se 付属語「い」|』と認識する場合が少なくないと思われる
(必ずそうなる訳ではない)。
こうして、
『|Ve Se|Ne Se 付属語「よ」|』、
『|Ne Se|A Se 付属語「い」|』、
が、コーパス由来の確率データベースに登録された状態で、
「へんかんがようい」を変換すると。
「|経ん|閑雅よ|うい|」(|へん|かんがよ|うい|)という文節区切り候補に関して、
コーパスから覚えた
『|Ve Se|Ne Se 付属語「よ」|』が「|経ん|閑雅よ|」(|へん|かんがよ|)の部分に、
『|Ne Se|A Se 付属語「い」|』が「|閑雅よ|うい|」(|かんがよ|うい|)の部分に、
それぞれ一致するので、文節区切り位置として優先されるらしい。
文節区切り位置が決まった後に、
各文節に対して変換候補一覧の生成と並び順の決定が行われるが、
その時、第1文節の「|へん|」に関しては、
「|経ん|」よりも「|変|」の方が評価が高いらしく、
提示される変換候補が
「|変|閑雅よ|うい|」(|へん|かんがよ|うい|)
に変わったりする。
例文に
|へんかんが|ようい| |変換が|容易|
を追加しても駄目でした。例文に
|へん|かんがよ|うい| |~変|~閑雅よ|~うい|
を追加し、
『|Ve Se|Ne Se 付属語「よ」|』、
『|Ne Se|A Se 付属語「い」|』、
を強制的にコーパス由来の確率データベースから削除したところ、
ようやく「|変換が|容易|」(|へんかんが|ようい))が
第1候補として提示される様になりました。
がしかし、
『|Ve Se|Ne Se 付属語「よ」|』、
『|Ne Se|A Se 付属語「い」|』、
をデータベースから削除しているので、
「|(動詞)(付属語有無問わず)|(名詞)よ|」や
「|(名詞)(付属語有無問わず)|(形容詞)い|」といった
構文の事を忘れている筈です。
Anthy-8600 以降(これを書いている時点では 9100h まで同様)で 実装されている文節区切りアルゴリズムである 「品詞&付属語ベース 文節2グラム MBR ビタビ アルゴリズム」の、 Anthy(具体的にどのバージョンの範囲まで該当するかは未確認)で 行われている実装方法だと、 「なにがしかの構文を覚えると、別の構文が覚えられなくなる」 と言うパターンが存在します。
明確にコケる組み合わせを具体的な組み合わせとして見つけたのは、
上記の例で3パターン目ですが、
前2パターンは運悪く特殊な例外を引いてしまったと思って
記録も取らずに忘れ去っていました。
いちいちこんなコケるパターンを探しても何の得にもならないので
わざわざ探しはしませんが。
運悪く滅多に発生しない様な特殊なパターンを引き当ててしまったのか。
それとも
滅多に具体的な追究をしないから表面化しないだけで
潜在的にこの手のパターンが山ほど存在しているのか。
上記の内容は、 Anthy のコーパス例文や辞書メンテナンスをされる方が ドツボにはまって泥沼に落ち込まない様に注意喚起の為 (この手のパターンに遭遇した場合、 理論上?設計上?の限界を越えてしまっているので、 現場でどう頑張っても無駄です)、 あるいは新規にかな漢字変換エンジンの開発をされる方の参考情報として、 提起するものであり、 Anthy が良いとか悪いとか言う話ではありません。
これらの変更を行った事で、 一字一句誤りの無い学習データを貯めさえすれば、 文語でちょっと硬めの文書の入力には、 それなりに使えるかな漢字変換になったと思いますが。 今度の問題は 「一字一句誤りの無い学習データ」を「貯める」 事ですかね。
漢字コード入力、漢字コード表入力、 単漢字変換/部首変換/画数変換、 単語変換、単文節変換、連文節変換。 思えば遠くに来たもんだ。