# Feature forest モデル

English version

ここでは，構文解析の際に曖昧性解消をする確率モデルの一つ feature forest モデルの 推定について説明します．

feature forest モデルは，文に対してその derivation の確率を与えるモデルです． 文をs，その derivation をd とすると， p(d|s) を求めます． Enju の確率モデルは最大エントロピーモデルになっているので， モデルの推定では素性の最適な重みを計算することになります (詳しくは確率モデルを参照して下さい)． そのために最大エントロピーモデル推定器 Amis と mayz の Amis 用ツール forestmaker， amisfilter を利用しています．

具体的には次のような手順で推定が行われます．

1. forestmaker により確率イベントをファイルに出力する
2. amisfilter により確率イベントにマスクをかけて素性を取り出し， Amis 形式のデータファイルを作る
3. Amis により素性の最適な重みを計算する

確率イベントとは，以下のように // で区切られたフィールドを持つ文字列です．

>     S_fin//plays//VBZ//[npVPnp]_lxm_10-singular3rd_verb_rule//play//VB//[npVPnp]_lxm_10//2//1//m//root

最後のフィールドはこのイベントのカテゴリ を表しています． その他のフィールドはイベントの特徴を表す記号です． forestmaker は 文と対応する derivation の特徴を表す確率イベントを feature forest 形式でファイルに出力します．

amisfilter では，上のような確率イベントに対して そのカテゴリにしたがってマスクをかけます． マスクではどのフィールドを組み合わせて素性を作るかが指定されています． 例えば上の文字列に，(0, 0, 1, 1, 0, 0, 0, 0, 0, 0)というマスクをかけると， 次のような素性が得られます．

>     _//_//VBZ//[npVPnp]_lxm_10-singular3rd_verb_rule//_//_//_//_//_//_//root

amisfilter はこのようにイベントから素性を取り出し， Amis 形式のデータファイルを生成します． 最後に，Amis によって素性の最適な重みが計算されます．

以下各ステップについて説明します．

## 確率イベントをファイルに出力する

ここでは forestmaker を 使って，確率イベントをファイルに出力する過程を説明します．

forestmaker モデル名 文法モジュール derivbank イベントファイル
モデル名 | 確率モデルの名前(構文解析の時にも使います)
文法モジュール | 文法およびイベント抽出 predicate が実装されている lilfes module
derivbank | 文法獲得で得た derivbank (lildb 形式)
イベントファイル | 確率イベントを出力するファイル (テキスト形式または gz/bz による圧縮形式)

forestmaker が出力する確率イベントファイルには， 一文の derivation forest を表す確率イベントが feature forest 形式で記されています． derivation forest とは，構文解析後のチャートのように ある文に対して可能な derivation を重ね合わせたものです． 例えば次の図は "Mary runs" という文に対して， 全体として NP となる derivation と S となる derivation の2個がある場合の チャートを簡単に表しています．

"Mary" に対応する NNP ノードが二つの derivation に共有されています． このようなチャートを feature forest 形式で表すと次のようになります (実際には一行で出力されます)．

>     { node0
>       ( NProot NP//runs//NNS//root
>         { node1
>           ( NPbinary MOD//NNS//runs//NNS//NNP//mary//NNP//binary
>             { node2
>               ( NNPterm NNP//mary//NNP//term ) }
>             { node3
>               ( NNSterm NNS//runs//NNS//term ) } ) } )
>       ( Sroot S//runs//VBZ//root
>         { node4
>           ( Sbinary SUBJ//VBZ//runs//VBZ//NNP//mary//NNP//binary
>             $node2
>             { node5
>               ( VBZterm VBZ//runs//VBZ//term ) } ) } ) }

{ node0 ( NProot ... ) ( Sroot ...) } という構造が， チャートの最上部に 2 種類のノード (NP, S) があることを表します． つまり ( NProot ...) で NP ノードを root とする derivation を， ( Sroot ...) で Sノードを root とする derivation を表し， それらを { } で囲むことで，どちらかが正しい derivation であると示しています． また，共有されるノードは下から 2 行目のように参照を使って表します． つまり $node2 と書くことで { node2 ...} と同じノードであることを表しています．

forestmaker では， derivbank 中の各文の derivation forest を作るため， 入力の文法を用いて構文解析をします． そして結果のチャート上の構文木の各ノードに対して確率イベントを出力します．

1. 入力の derivbank の derivation から正解の構文木をつくる． 構文木の末端ノードになる語彙項目は，derivation の末端ノードから `fm_correct_lexical_entry/2` によって得たものを用いる．
2. derivation から `fm_derivation_to_word_lattice/2` によって，元の文に対する word lattice をつくる．
3. 上で作った word lattice を入力として構文解析を行いチャートを得る． 構文解析では up と同じ文法のインターフェースが使われる． ただし `lexical_entry/2` のみは， かわりに `fm_lexical_entry/2` が使われる．
4. 正解の構文木の確率イベントを観測事象として出力する． 具体的には構文木の各ノードに対し以下のインターフェースにより， カテゴリ名と特徴フィールドの記号を得る．
   - ルートノードならば `extract_root_event/4`
   - 末端ノードならば `extract_treminal_event/6`
   - unary ノードならば `extract_unary_event/6`
   - binary ノードならば `extract_binary_event/6`
   得られた記号とカテゴリ名をつなげて確率イベントを出力する．
5. チャート上の全ての構文木を feature forest 形式で出力する． 構文木の各ノードでは，4. と同様にしてカテゴリ名と特徴フィールドの記号を得て， 確率イベントを出力する．

構文木のノードから確率イベントを取り出すインターフェースには， 素性の値 (integer または float) を指定できる形式もあります． 詳しくは forestmaker のマニュアル を参照して下さい． Enju の場合，derivbank からチャートを作るインターフェースは "devel/forestmake.lil" で実装されています． 実装の特徴は次のようになっています．

- derivation から正解構文木の語彙項目を得るときには， derivation の末端ノードの単語情報 (TERM_WORD 素性)で辞書を引き， 返ってくる語彙項目の中から末端ノードの LEXENTRY_SIGN 素性と同じ素性構造を持つ語彙項目を対応させる．
- derivation から word lattice を作るときには， word 素性に derivation 中の対応する末端ノードの素性構造を格納する．
- 語彙項目をチャートに入力するときには， 上でつくられた word lattice に格納されている derivation の末端ノードを利用する． 具体的には末端ノードの TERM_WORD 素性で辞書を引き， 返ってきた全ての語彙項目の FOM を Unigram モデルで計算する． チャートに入力するのは，FOM の高い語彙項目と正解の語彙項目のみにする．

これらは例えば次のように実装されます．

>     fm_correct_lexical_entry(TERM_WORD\$Word & LEXENTRY_SIGN\$Sign, $LexName) :-
>         lookup_lexicon($Word, $TempNameList),
>         member($TempName, $TempNameList),
>         lookup_template($TempName, $LexEntry),
>         equivalent($LexEntry, $Sign),
>         !,
>         $LexName = LEX_WORD\$Word & LEX_TEMPLATE\$TempName.

>     fm_derivation_to_word_lattice(derivation_internal & DERIV_DTRS\$Dtrs, $WordLattice) :-
>         fm_derivation_to_word_lattice_dtrs($Dtrs, $WordLattice).
>     fm_derivation_to_word_lattice(derivation_terminal & $Term & TERM_WORD\$Word,
>     			      [left_position\$LPos & right_position\$RPos & word\$LexEntry]) :-
>         $LexEntry = $Term,
>         $Word = POSITION\$LPos,
>         $RPos is $LPos + 1.

>     fm_lexical_entry(TERM_WORD\$Word & LEXENTRY_SIGN\$Sign, $LexName) :-
>         lookup_lexicon($Word, $TempNameList1),
>         check_coverage($TempNameList1, $Sign, $TempName1),
>         findall($Lex,
>     	    (member($TN, $TempNameList1),
>     	     $Lex = LEX_WORD\$Word & LEX_TEMPLATE\$TN),
>     	    $LexList1),
>         restrict_templates($LexList1, $LexList2),
>         (memberchk(LEX_TEMPLATE\$TempName1, $LexList2) ->
>          $LexList3 = $LexList2 ;
>          $LexList3 = [LEX_WORD\$Word & LEX_TEMPLATE\$TempName1|$LexList2]),
>         member(LEX_TEMPLATE\$TempName, $LexList3),
>         $LexName = LEX_WORD\$Word & LEX_TEMPLATE\$TempName.

構文木の各ノードからカテゴリ名と特徴を表す記号を取り出すインターフェースは， "grammar/forestevent.lil" で実装されています．

- ルートノードからは "root" カテゴリのイベントを取り出す． このカテゴリはフィールドとして次を含む．
  - HEADとVAL 素性を表す記号
  - 文の head word の表層文字列と POS
  - その stemming 後の文字列と POS
  - 語彙項目の名前を表す記号
  - 語彙素項目の名前を表す記号
  - 文の長さ
  - 文の中に読点があるかどうかを示す記号
- 末端ノードから "term" カテゴリのイベントを取り出す． このカテゴリのフィールドは "root" カテゴリと同じものを持つ．
- unary ノードからは "sem" カテゴリと "unary" カテゴリのイベントを取り出す．"sem" カテゴリは述語項構造の素性で， 構文解析をしていった時にそのノードで初めて全ての項が確定した述語項構造に対して 取り出される．フィールドとしては次のものを持つ．
  - 述語となる語の表層文字列と POS
  - その語の語彙素テンプレートの名前
  - 項のラベル (ARG1, MOD 等)
  - 項となる語の表層文字列と POS
  - その語の語彙素テンプレートの名前
  - 述語の語と項の語の距離
  また "unary" カテゴリはフィールドとして， 娘ノードの特徴を表すフィールド ("root" カテゴリと同じフィールド) と， 今見ているノードが娘ノードから作られた時に適用されたスキーマ名を持つ．
- binary ノードからは "sem" カテゴリと "binary" カテゴリのイベントを取り出す．"sem" カテゴリは unary ノードと共通． "binary" カテゴリは次のようなフィールドを持つ．
  - 適用されたスキーマ名
  - 左右の娘の head word の距離
  - binary ノードが支配する句の長さと分の長さの差
  - 娘ノードの間に読点があるかを示す記号
  - binary ノードの端に読点があるかを示す記号
  - binary ノードの支配する句の位置 (両端の位置)
  - head になる娘とそうでない娘ノードの特徴をあらわすフィールド (それぞれについて "root" カテゴリを同じフィールド)

これらは例えば次のように指定されます．

>     extract_root_event("hpsg-forest", "root", $Sign, $Event) :-
>         encode_sign($Sign, $Event, []).

>     extract_terminal_event("hpsg-forest", "term", _, $Sign, _, $Event) :-
>         encode_sign($Sign, $Event, []).

>     extract_unary_event("hpsg-forest", "sem", _, _, _, $Inactives,
>                         [$Surface, $POS, $Temp,$ArgSurf,
>     		    $ArgPOS, $ArgTemp,
>     		    $Feature, $Dist]) :-
>         member($Ind & PRED\(LEX_WORD\(SURFACE\$Surface &
>     				  POS\$POS &
>     				  POSITION\$Position) &
>     			LEX_TEMPLATE\LEXEME_NAME\$Temp),
>     	   $Inactives),
>         extract_argument($Ind, $Feature,
>     		     LEX_WORD\(SURFACE\$ArgSurf & POS\$ArgPOS &
>     			       POSITION\$ArgPosition) &
>     		     LEX_TEMPLATE\LEXEME_NAME\$ArgTemp),
>         arg_distance($Position, $ArgPosition, $Dist).
>         extract_hpsg_sem_event($Inactives, $Event).

forestmaker が出力する確率イベントファイルは次のようになっています．

>     event_2
>     1        S_fin//plays//VBZ//[npVPnp]_lxm_10-singular3rd_verb_rule//
>     play//VB//[npVPnp]_lxm_10//2//1//m//root plays//VBZ//[npVPnp]_lxm_1
>     0//haag//NNP//[dtNP]_lxm_2//ARG1//1//sem plays//VBZ//[npVPnp]_lxm_1
>     0//elianti//NNP//[dtNP]_lxm_2//ARG2//1//sem SUBJ//1//1//m//m//NNP//
>     VBZ//VP//plays//VBZ//[npVPnp]_lxm_10-singular3rd_verb_rule//play//V
>     B//[npVPnp]_lxm_10//1//1//m//NP//haag//NNP//[dtNP]_lxm_2//haag//NNP
>     //[dtNP]_lxm_2//1//0//m//bin ms-period-//NNP//[dtNP]_lxm_2//haag//N
>     NP//[dtNP]_lxm_2//MODIFY//1//sem LMOD//1//2//m//m//NNP//NNP//N_adj/
>     /ms-period-//NNP//[dtNP]_lxm_2-noun_adjective_rule//ms-period-//NNP
>     //[dtNP]_lxm_2//0//0//m//NX//haag//NNP//[dtNP]_lxm_2//haag//NNP//[d
>     tNP]_lxm_2//0//0//m//bin N_adj//ms-period-//NNP//[dtNP]_lxm_2-noun_
>     adjective_rule//ms-period-//NNP//[dtNP]_lxm_2//0//0//m//term NX//ha
>     ag//NNP//[dtNP]_lxm_2//haag//NNP//[dtNP]_lxm_2//0//0//m//term COMP/
>     /1//2//m//m//VBZ//NNP//VX//plays//VBZ//[npVPnp]_lxm_10-singular3rd_
>     verb_rule//play//VB//[npVPnp]_lxm_10//0//1//m//NP//elianti//NNP//[d
>     tNP]_lxm_2//elianti//NNP//[dtNP]_lxm_2//0//0//m//bin VX//plays//VBZ
>     //[npVPnp]_lxm_10-singular3rd_verb_rule//play//VB//[npVPnp]_lxm_10/
>     /0//1//m//term NX//elianti//NNP//[dtNP]_lxm_2//elianti//NNP//[dtNP]
>     _lxm_2//0//0//m//term
>     { _ ( root31 S_fin//plays//VBZ//[npVPnp]_lxm_10-singular3rd_verb_ru
>     le//play//VB//[npVPnp]_lxm_10//2//1//m//root { node31 ( b31_0 plays
>     //VBZ//[npVPnp]_lxm_10//haag//NNP//[dtNP]_lxm_2//ARG1//1//sem plays
>     //VBZ//[npVPnp]_lxm_10//elianti//NNP//[NP]_23//ARG2//1//sem SUBJ//1
>     //1//m//m//NNP//VBZ//VP//plays//VBZ//[npVPnp]_lxm_10-singular3rd_ve
>     rb_rule//play//VB//[npVPnp]_lxm_10//1//1//m//NP//haag//NNP//[dtNP]_
>     lxm_2//haag//NNP//[dtNP]_lxm_2//1//0//m//bin { node18 ( u18_0 { nod
>     e17 ( b17_0 ms-period-//NNP//[dtNP]_lxm_2//haag//NNP//[dtNP]_lxm_2//
>     MODIFY//1//sem LMOD//1//2//m//m//NNP//NNP//N_adj//ms-period-//NNP//[
>     dtNP]_lxm_2-noun_adjective_rule//ms-period-//NNP//[dtNP]_lxm_2//0//0
>     //m//NX//haag//NNP//[dtNP]_lxm_2//haag//NNP//[dtNP]_lxm_2//0//0//m//
>     bin { node0 ( term0_0 N_adj//ms-period-//NNP//[dtNP]_lxm_2-noun_adje
>     ctive_rule//ms-period-//NNP//[dtNP]_lxm_2//0//0//m//term ) } { node3
>      (term3_0 NX//haag//NNP//[dtNP]_lxm_2//haag//NNP//[dtNP]_lxm_2//0//0
>     //m//term ) }) } ) } { node28 ( b28_0 COMP//1//2//m//m//VBZ//NNP//VX
>     //plays//VBZ//[npVPnp]_lxm_10-singular3rd_verb_rule//play//VB//[npVP
>     np]_lxm_10//0//1//m//NP//elianti//NNP//[NP]_23//elianti//NNP//[NP]_2
>     3//0//0//m//bin { node5 ( term5_0 VX//plays//VBZ//[npVPnp]_lxm_10-si
>     ngular3rd_verb_rule//play//VB//[npVPnp]_lxm_10//0//1//m//term ) } {
>     node14 ( term14_0 NP//elianti//NNP//[NP]_23//elianti//NNP//[NP]_23//
>     0//0//m//term ) } ) } ) ( b31_1 plays//VBZ//[npVPnp]_lxm_10//haag//N
>     NP//[dtNP]_lxm_2//ARG1//1//sem plays//VBZ//[npVPnp]_lxm_10//elianti/
>     /NNP//[dtNP]_lxm_2//ARG2//1//sem SUBJ//1//1//m//m//NNP//VBZ//VP//pla
>     ys//VBZ//[npVPnp]_lxm_10-singular3rd_verb_rule//play//VB//[npVPnp]_l
>     xm_10//1//1//m//NP//haag//NNP//[dtNP]_lxm_2//haag//NNP//[dtNP]_lxm_2
>     //1//0//m//bin $node18 { node29 ( b29_0 COMP//1//2//m//m//VBZ//NNP//
>     VX//plays//VBZ//[npVPnp]_lxm_10-singular3rd_verb_rule//play//VB//[np
>     VPnp]_lxm_10//0//1//m//NP//elianti//NNP//[dtNP]_lxm_2//elianti//NNP/
>     /[dtNP]_lxm_2//0//0//m//bin $node5 { node16 ( u16_0 { node9 ( term9_
>     0 NX//elianti//NNP//[dtNP]_lxm_2//elianti//NNP//[dtNP]_lxm_2//0//0//
>     m//term ) } ) ( u16_1 $node9 ) } ) } ) } ) (root32 NP//ms-period-//N
>     NP//[dtNP]_lxm_2//ms-period-//NNP//[dtNP]_lxm_2//2//1//m//root { nod
>     e32 ( b32_0 elianti//NNP//np[dtNP]_382//ms-period-//NNP//[dtNP]_lxm_
>     2//MODIFY//2//sem RMOD//2//1//m//m//VBZ//NNP//NP//elianti//NNP//np[d
>     tNP]_382//elianti//NNP//np[dtNP]_382//0//0//m//NP//ms-period-//NNP//
>     [dtNP]_lxm_2//ms-period-//NNP//[dtNP]_lxm_2//2//1//m//bin { node27 (
>      u27_0 { node22 ( b22_0 plays//VBZ//[npVPnp]_lxm_10//haag//NNP//[dtN
>     P]_lxm_2//ARG1//1//sem plays//VBZ//[npVPnp]_lxm_10//ms-period-//NNP/
>     /[dtNP]_lxm_2//ARG2//2//sem REL//2//2//m//m//NNP//NNP//S_fin//plays/
>     /VBZ//[npVPnp]_lxm_10-wh_move_rule-singular3rd_verb_rule//play//VB//
>     [npVPnp]_lxm_10//1//1//m//NX//ms-period-//NNP//[dtNP]_lxm_2//ms-peri
>     od-//NNP//[dtNP]_lxm_2//0//0//m//bin { node1 ( term1_0 NX//ms-period
>     -//NNP//[dtNP]_lxm_2//ms-period-//NNP//[dtNP]_lxm_2//0//0//m//term )
>      } { node21 ( u21_0 EMPTY_FILLER//S_fin//plays//VBZ//[npVPnp]_lxm_10
>     -wh_move_rule-singular3rd_verb_rule//play//VB//[npVPnp]_lxm_10//1//1
>     //m//unary { node20 ( b20_0 SUBJ//1//2//m//m//NNP//VBZ//VP//plays//V
>     BZ//[npVPnp]_lxm_10-wh_move_rule-singular3rd_verb_rule//play//VB//[n
>     pVPnp]_lxm_10//0//1//m//NP//haag//NNP//[dtNP]_lxm_2//haag//NNP//[dtN
>     P]_lxm_2//0//0//m//bin { node4 ( u4_0 $node3 ) ( u4_1 $node3 ) } { n
>     ode8 ( term8_0 VP//plays//VBZ//[npVPnp]_lxm_10-wh_move_rule-singular
>     3rd_verb_rule//play//VB//[npVPnp]_lxm_10//0//1//m//term ) } ) } ) }
>     ) } ) } { node15 ( u15_0 { node13 ( term13_0 NX//elianti//NNP//np[dt
>     NP]_382//elianti//NNP//np[dtNP]_382//0//0//m//term ) } ) ( u15_1 $no
>     de13 ) } ) } ) }

>     event_3
>     ......

event_2 は "Ms. Haag plays Elianti." という文に対する確率イベントの 出力です．

## マスクをかけて素性を取り出す

ここでは amisfilter を使って， 上のステップで出力された確率イベントにマスクをかけ， 素性を取り出し，Amis 形式のデータファイルを出力します． この部分は Unigram モデルの推定の場合と同様です． ただし，feature forest 形式を保ったまま素性を取り出すため， 出力されるイベントファイルは次のようになります．

>     event1
>     1 S//_//_//root _//_//VBZ//root SUBJ//VBZ//_//_//NNP//_//_//binary
>     SUBJ//_//_//VBZ//_//_//NNP//binary _//mary//NNP//term
>     _//runs//VBZ//term
>     { node0
>       ( NProot NP//_//_//root _//_//NNS//root
>         { node1
>           ( NPbinary MOD//NNS//_//_//NNP//_//_//binary
>                      MOD//_//_//NNS//_//_//NNP//binary
>             { node2
>               ( NNPterm _//mary//NNP//term ) }
>             { node3
>               ( NNSterm _//runs//NNS//term ) } ) } )
>       ( Sroot S//_//_//root _//_//VBZ//root
>         { node4
>           ( Sbinary SUBJ//VBZ//_//_//NNP//_//_//binary
>                     SUBJ//_//_//VBZ//_//_//NNP//binary
>             $node2
>             { node5 ( VBZterm _//runs//VBZ//term ) } ) } ) }

モデルファイルは Unigram モデルの場合と同様です．

Enju の場合，`feature_mask/3` は "grammar/synmask.lil"， "grammar/semmask.lil" で実装されています． "grammar/synmodel.lil"の場合， カテゴリ "root" に対するマスクには次のようなものが含まれます．

| Symbol | Surface | POS | TempName | Base | BasePOS | Lexeme | Span | NumClause | NumComma
mask 1 | × | × | × | ○ | × | × | × | × | × | ×
mask 2 | × | × | ○ | × | × | × | × | × | × | ×
mask 3 | × | × | ○ | ○ | × | × | × | × | × | ×
mask 4 | ○ | × | × | × | × | × | × | × | × | ×

これらは次のように実装されます．

>     feature_mask("hpsg-forest", "root", [0,  0, 0, 1,  0, 0, 0,  0, 0, 0]).
>     feature_mask("hpsg-forest", "root", [0,  0, 1, 0,  0, 0, 0,  0, 0, 0]).
>     feature_mask("hpsg-forest", "root", [0,  0, 1, 1,  0, 0, 0,  0, 0, 0]).
>     feature_mask("hpsg-forest", "root", [1,  0, 0, 0,  0, 0, 0,  0, 0, 0]).

上のようなマスクを上のステップで示した確率イベントファイルの例に適用すると， 次のような Amis 形式のイベントファイルが得られます．

>     event_2
>     1       _//_//_//[npVPnp]_lxm_10-singular3rd_verb_rule//_//_//_//_//
>     _//_//root _//_//VBZ//_//_//_//_//_//_//_//root _//_//VBZ//[npVPnp]_
>     lxm_10-singular3rd_verb_rule//_//_//_//_//_//_//root S_fin//_//_//_/
>     /_//_//_//_//_//_//root SUBJ//1//_//m//m//_//_//_//_//_//[npVPnp]_lx
>     m_10-singular3rd_verb_rule//_//_//_//_//_//m//_//_//_//[dtNP]_lxm_2/
>     /_//_//_//_//_//m//bin SUBJ//1//_//m//m//_//_//_//_//VBZ//_//_//_//_
>     ......
>     { _ ( root31 _//_//_//[npVPnp]_lxm_10-singular3rd_verb_rule//_//_//_
>     //_//_//_//root _//_//VBZ//_//_//_//_//_//_//_//root _//_//VBZ//[npV
>     Pnp]_lxm_10-singular3rd_verb_rule//_//_//_//_//_//_//root S_fin//_//
>     _//_//_//_//_//_//_//_//root { node31 ( b31_0 SUBJ//1//_//m//m//_//_
>     //_//_//_//[npVPnp]_lxm_10-singular3rd_verb_rule//_//_//_//_//_//m//
>     ......

>     event_3
>     ......

出力される Amis 形式のモデルファイルには，採用された素性と その重みの初期値が出力されています．

>     _//_//_//[npVPnp]_lxm_10-singular3rd_verb_rule//_//_//_//_//_//_//root 1.0
>     _//_//VBZ//_//_//_//_//_//_//_//root 1.0
>     _//_//VBZ//[npVPnp]_lxm_10-singular3rd_verb_rule//_//_//_//_//_//_//root 1.0
>     ......

## 素性の最適な重みを計算する

上のステップで得られた Amis 形式のモデルファイルとイベントファイルから Amis を使って 素性の最適な重みを計算します． 出力ファイルにはモデルファイルと同じ形式で，計算された素性の重みが示されています．

>     _//_//_//[npVPnp]_lxm_10-singular3rd_verb_rule//_//_//_//_//_//_//root 7.309690e-01
>     _//_//VBZ//_//_//_//_//_//_//_//root 1.639833e+00
>     _//_//VBZ//[npVPnp]_lxm_10-singular3rd_verb_rule//_//_//_//_//_//_//root 7.309690e-01
>     ......

Enju 開発者用マニュアル Enju ホームページ 辻井研究室