ここでは,構文解析の際に曖昧性解消をする確率モデルの一つ feature forest モデルの 推定について説明します.
feature forest モデルは,文に対してその derivation の確率を与えるモデルです. 文をs,その derivation をd とすると, p(d|s) を求めます. Enju の確率モデルは最大エントロピーモデルになっているので, モデルの推定では素性の最適な重みを計算することになります (詳しくは確率モデルを参照して下さい). そのために最大エントロピーモデル推定器 Amis と mayz の Amis 用ツール forestmaker, amisfilter を利用しています.
具体的には次のような手順で推定が行われます.
確率イベントとは,以下のように // で区切られたフィールドを持つ文字列です.
最後のフィールドはこのイベントのカテゴリ を表しています.
その他のフィールドはイベントの特徴を表す記号です.
forestmaker は 文と対応する derivation の特徴を表す確率イベントを
feature forest 形式でファイルに出力します.
S_fin//plays//VBZ//[npVPnp]_lxm_10-singular3rd_verb_rule//play//VB//[npVPnp]_lxm_10//2//1//m//root
amisfilter では,上のような確率イベントに対して
そのカテゴリにしたがってマスクをかけます.
マスクではどのフィールドを組み合わせて素性を作るかが指定されています.
例えば上の文字列に,(0, 0, 1, 1, 0, 0, 0, 0, 0, 0)というマスクをかけると,
次のような素性が得られます.
amisfilter はこのようにイベントから素性を取り出し,
Amis 形式のデータファイルを生成します.
最後に,Amis によって素性の最適な重みが計算されます.
_//_//VBZ//[npVPnp]_lxm_10-singular3rd_verb_rule//_//_//_//_//_//_//root
以下各ステップについて説明します.
ここでは 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 を作るため, 入力の文法を用いて構文解析をします. そして結果のチャート上の構文木の各ノードに対して確率イベントを出力します.
構文木の各ノードからカテゴリ名と特徴を表す記号を取り出すインターフェースは, "grammar/forestevent.lil" で実装されています.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.
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 は "Ms. Haag plays Elianti." という文に対する確率イベントの
出力です.
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
......
ここでは 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 形式のイベントファイルが得られます.
出力される 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
......
_//_//_//[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
......