Kazuki Ohta
mover****@hct*****
2004年 6月 24日 (木) 03:36:09 JST
どうも、kzkです。 岡本さん、非常に参考になる情報を有難う御座いました。 変換エンジンなんて敷居が高いと思って今までちょっとソースコードを 読むのを躊躇していたのですが... 変更を行われた場合には頑張ってコメントを付けるようにしたいと思います。 そして少し質問が有るのですが、アルゴリズムの向上(Splitterの改良)というのが 変換精度向上の糸口として上げられていますが、具体的にどういう改良を施される つもりなのでしょうか?そして、その成果はどうやって確かめられるんでしょうか? この辺りがまだ俺の中では暗黒っぽいのですが。 よければ御返事下さいm(_ _)m > 岡本(henkma)です. > はじめまして > はじめましての方々 > お久しぶりです > お久しぶりの方々 > > anthyの変換精度を上げたいと考え, 少しソースコードを読んでみて, > どうすれば良いかについて考えとメモをまとめてみました. > 開発に必要なドキュメントはdoc/* にかなり質の良いものが揃っていて > 以下のことはこれのsubset的なものになっているかもしれませんが, > Subjectの視点に特化したものとしてコンパクトに, またその方向にある程度詳しく > したつもりです. 突込み等いただければ幸いです. > 長文なので, 興味のない方は申し訳ありませんが無視して下さい. > > > 1. 変換精度向上のために > > 変換精度向上のために, 2つのアプローチが考えられます. 一つは > アルゴリズムの向上, もう一つは辞書の充実です. それぞれに対し, > 現状最も効果的なのは前者に関してsplitterの改良, 後者に関しては > 付属語グラフの充実だと私は考えています. > > この文書はこれらの点, 特に前者に注目して書いたものです. > > > 2. 用語 > > anthyのコメントやコード中に使われている用語の意味についてまとめます. > > ・candidate 候補 > ・commit (変換の)確定 > ・context 入力コンテキスト 変換する文字列一つに対応する. > ・metaword 文節を複数まとめたもの > ・extent 文(context)中の範囲 > ・nr_* 何かの数を表す変数名の接頭辞. > 主に"nr_配列名"で配列の長さを表す. > ・anty_*(...) 外部に公開する関数. > > > 3. 型 > > anthyで用いられている型(主にstruct)について意味や構造をまとめます. > > ・xchar > include/xstr.h > 文字一個分を表す型. 正体はint. EUCもしくはASCIIのコードが入っている. > > ・xstr > include/xstr.h > 正体はstruct xstr_. > struct xstr_ のメンバは以下の通り. > - xchar* str; > xcharの配列 > - int len; > 上記配列の長さ > > ・struct anthy_context > src-main/main.h > contextを表すstruct. > メンバは以下の通り > - xstr str; > contextの持つ文字列 > - struct segment_list seg_list; > 文節のリスト > - dic_session_t dic_session; > コンテキストと一対一対応? > 辞書キャッシュのエントリがどのコンテキストに使われているかを > 把握するのに使う. > - struct splitter_context split_info; > splitterのcontext > > ・struct segment_list > include/segment.h > 文節リストを表す. > メンバは以下の通り > - int nr_segments; > 文節リストの要素数 > - struct seg_ent list_head; > 文節リストの先頭 > > ・struct seg_ent > include/segment.h > context内に存在する文節の列 > メンバは以下の通り > - xstr str; > 文字列(実体はcontextの中, らしい. > つまりallocateするなということか) - int committed; > 確定された候補の番号. 負のときは未確定. > - int nr_cands; > 候補の数. ↓の配列の長さ. > - struct cand_ent **cands; > 候補のポインタの配列. > - int from, len; > - int core_from, core_len; > - int nr_seginfo; > ↓の配列の長さ. > - struct seg_info **si; > 文節の構成に関する情報へのポインタの配列 > - struct seg_ent *prev,*next; > リストの前要素, 後要素へのポインタ. > > ・struct seg_info > include/splitter.h > 文節に関する細かい情報. > メンバは以下の通り > - enum {SI_NORMAL, SI_CAND} type; > seg_infoの持つ情報. > SI_NORMAL=品詞情報を持っている, SI_CAND=候補が与えられている. > - int info_len; > word_infoでカバーされている部分の長さ. > - int nr_word_info; > ↓で表される配列の長さ. > - struct word_info *word_info; > word_infoの配列. > - int core_word_info_index; > 自立語部のインデックス > - int struct_ratio; > 文節の形式のスコア. 0以上でなければならない. > この数字が高いほど確率の高い構造をしている. - struct seg_class > seg_class; > 文節クラス > - xstr cand; > type == SI_CANDの時に候補が入っている. > - int score; > seginfoのスコア(seg_infoのスコア?) > > ・struct word_info > seg_info用の構造体 > > ・struct splitter_context > include/splitter.h > splitterのcontext > メンバは以下の通り > - struct word_split_info_cache* > word_split_info; context中の自立語などの情報. > - int char_count; > 上記structのメンバcnodeで表される配列の長さ. > - struct char_ent *ce; > 配列として使う. char_entは文字, 文節境界, > 文節の長さ等を持っている模様. # なんでこんな構造になっているのだろう? > > ・struct word_split_info_cache; > context中の自立語などの情報. > > > 4. 関数 > > splitterに関する動作に関連した関数の仕様(メモ)です. > > splitterのエントリポイントはanthy_do_context_set_str()のよう >なので, この関数と, これに関する関数について述べています. > anthyの文節区切りアルゴリズムは, 基本的に全ての部分文字列を出し, > その可能な組み合わせに関して最もスコアの高いものを選択する, という > 感じになっているようです. > > ・int anthy_do_context_set_str(struct > anthy_context*, xstr*) src-main/context.c > 文節区切のエントリポイント. > > ・void anthy_do_reset_context(struct > anthy_context *) src-main/context.c > struct anthy_contextの初期化 > > ・void anthy_init_split_context(xstr*, struct > splitter_context *sc) src-splitter/splitter.c > splitterの初期化. 左右両端を文節境界に設定する. > ここでmake_word_cache()が呼ばれている. > make_word_cache()が文節区切のキモ. > > ・static void make_word_cache(struct > splitter_context *) src-splitter/splitter.c > 全ての部分文字列をチェックし, 文節候補を列挙する. > > ・void anthy_make_word_list_all(struct > splitter_context *) src-splitter/wordlist.c > 文節の形式を満たす部分文字列を列挙する. > 部分文字列は30文字まで(ここソースに即値ベタ書き) > > ・static void make_word_list(struct > splitter_context *, seq_ent_t, int, int) > 独立語に対し, 接頭辞, 接尾辞, 付属語を付けたものを文節の候補word_listとして > cacheに追加する. > > ・static void compose_segment_list(struct > anthy_context* , int, int) src-main/context.c > splitterによって配列中に付けられた文節境界のマークから文節リストを > 構成する. > > ・void anthy_sort_seginfo(struct > segment_list*) src-ordering/infosort.c > 各文節のseginfoをsortする. > > ・void anthy_mark_border(struct > splitter_context *, int, int, int) > src-splitter/splitter.c > 文節を区切る(境界をマークする) > > > 5. 付属語グラフ > > 付属語グラフに関する関数は以下の通りです. > > ・void anthy_scan_node(struct > splitter_context*, struct word_list*, xstr* > int) src-splitter/depgraph.c > 付属語の付いていない状態から検索を開始する. > > ・int anthy_get_node_id_by_name(const char*) > src-splitter/depgraph.c > 付属語グラフのノード名からそのidを探す. 見付からなかった場合は > 作ってそのidを返す. > > ・int anthy_init_depword_tab(void) > src-splitter/depgraph.c > 付属語グラフを初期化する. 成功すれば0, 失敗すれば-1を返す. > > ・void anthy_release_depword_tab(void) > src-splitter/depgraph.c > 付属語グラフを解放する. > > また, 附属グラフの情報はdepgraph/の下にまとめられているようです. > > > 6. テスト > > test/の下で, ./anthyとやるとテストができます. > 詳しくは./anthy --helpで. テストで出るメッセージの構造は > > 例文のインデクス:(例文) > "|"で文節に区切られた例文 > 1番目の文節の変換候補とスコア情報, > … > n番目の文節の変換候補とスコア情報, > > と, なっています. > なお, 文節の変換候補とスコア情報に関しては, > > 候補(何か謎のもの, 構造のスコア, 何か謎のもの)候補のスコア > > の羅列です. > となっています. 「何か謎のもの」についてはわかりません. > 「候補のスコア」は三桁毎に","が入っています. > > > ----------------------------------------------- >--------- 岡本 暁広 > henkm****@trans***** ((株)トランス・ニュー・テクノロジー) > henkm****@kmc***** (京大マイコンクラブ) > > _______________________________________________ > Anthy-dev mailing list > Anthy****@lists***** > http://lists.sourceforge.jp/mailman/listinfo/an >thy-dev -- Move the worlD! Kazuki Ohta : mover****@hct*****