構文解析の例

English version

この節では "I saw a girl with a telescope." という文を例にして, Enju で構文解析がどのように行われているかを見ていきます.

前処理

前処理の節で示したように, 前処理はsentence_to_word_lattice/2で行われます.

入力文はまずexternal_tagger/2により品詞タガーにかけられます.

"I/PRP saw/VBD a/DT girl/NN with/IN a/DT telescope/NN ./."
この出力に,単語と品詞の切り出しや stemming 等の処理を行います. 次にtoken_to_word_lattice/2により 各単語に対して 'extent_word' 型の素性構造を作ります. 次の素性構造は,"saw" に対応する 'extent_word' 型です.
extent_word
left_pos1
right_pos2
word <
word
INPUT "saw"
SURFACE "saw"
BASE "see"
INPUT_POS 1 "VBD"
POS 1
BASE_POS "VB"
POSITION 1
>
このような素性構造を要素とするリストがsentence_to_word_lattice/2の 返り値となります.

語彙項目の作成

up に語彙項目の sign を渡すには,lexical_entry/2lexical_entry_sign/2が使われます.

lexical_entry/2は, 前処理の結果得られた 'extent_word' 型の word 素性の値に対して呼び出されます. その値は 'word' 型のリストになっているので、その各要素に対して lookup_lexicon/2により対応するテンプレートのリストを得ます. lookup_lexicon/2では,lexicon_lookup_keyunknown_word_lookup_key/2で得られるキーによって, 辞書のデータベースを引きます. 上の "saw" に対応する 'extent_word' 型の場合, word 素性は要素一つのリストです.その要素に対して lexicon_lookup_key/2が対応させるキーは, 単語の base form と 品詞を取り出したもので,次のようになります.

word
BASE "see"
POS "VBD"
このキーで辞書を引くと,'lex_template' 型のリストが返されます. 上のキーの場合,リストには次のような要素も含まれています.
lex_template
LEXEME_NAME "[npVPnp]xm_10"
LEXICAL_RULES <past_verb_rule>
上の 'lex_template' 型を使って,lexical_entry/2は 次のような素性構造を返します.
lex_entry
LEX_WORD
word
INPUT "saw"
SURFACE "saw"
BASE "see"
INPUT_POS 1 "VBD"
POS 1
BASE_POS "VB"
POSITION 1
LEX_TEMPLATE
lex_template
LEXEME_NAME "[npVPnp]xm_10"
LEXICAL_RULES <past_verb_rule>
前処理で得られた全ての 'extent_word' 型に対してlexical_entry/2が 呼ばれたあと,返ってきた 'lex_entry' 型について fom_lexical_entry/3 によって FOM が計算されます.fom_lexical_entry/3では, 'word' 型と 'lex_entry' 型を渡すと,対応する語彙項目の FOM が返されます. 低い FOM が返された語彙項目はこの時点で足切りされます.

次に,残った 'lex_entry' 型に対してlexical_entry_sign/2が 呼ばれます.lexical_entry_sign/2ではまず, lookup_template/2により 'lex_entry' 型の LEX_TEMPLATE 素性の 値をキーにして,テンプレートデータベースを引きます. 上の 'lex_entry' 型の場合, このようなテンプレートが得られます. そのテンプレートに単語依存情報を付加します. 具体的には,引数で渡された 'lex_entry' 型の LEX_WORD\INPUT 素性と, PHON 素性の値を単一化するなどの処理を行います. その結果のsignが, lexical_entry_sign/2の返り値となります.

得られた sign は reduce_sign/3 によって factoring という処理をされます. factoring では,sign のなかの一部の情報を切り捨てることで, 複数の等価な sign がひとつの sign に縮退され, 後の構文解析では縮退した sign が使われます. reduce_sign/3では,sign を与えると 縮退した sign と切捨てられた情報を返すようにすることで, factoring 処理を指定します. (詳しくはリンクの節を参照して下さい) その後fom_terminal/4に,'lex_entry' 型,対応する縮退した sign, 縮退した時に切り捨てられた情報をわたすと,FOM が計算されます. ここでも FOM が低かった sign は足切りされます.

チャートによる構文解析

UPではエッジ,チャート,リンクと呼ばれるデータ構造を使って構文解析を行います.

エッジ

エッジは,概念的には<左ポジション,右ポジション,sign,リンクのリスト,FOM> の5つの組で表現されます.ポジ ションは単語の境界位置をあらわします.つまり,エッジは 文中のある位置からある位置までに対応する sign をあらわしている,という ことになります.また,パーズツリーを構文解析後に復元するための情報がリ ンクリストに入っており,曖昧性解消のためのスコアがFOMにはいって います.

チャート

パーザには,チャートと呼ばれる構文解析状態を保存するデータがあります. チャートは,二次元テーブルになっていて,各要素をCKYセルと呼びます. 文 "I saw a girl with a telescope" が入力されたとき,チャートは次のようになります.

チャート
各CKYセルをS[i][j]とあらわしたとき,i,jは文中の位置,すなわちポジショ ンをあらわします.S[0][1]には"I"に対応するエッジのIDが格納され, S[1][2]には,"saw"に対応するエッジのIDが格納され,S[6][7]には "telescope"に対応するエッジのIDが格納されます.単語に対応するCKYセルに は以上のようにエッジのIDが格納されます. 句に対応するCKYセルにも構文解 析が行われることによってエッジのIDが格納されていきます.例えば, S[0][2]は"I saw" に,S[1][3]は"saw a"に対応し,さらに大きな句である S[0][3]は"I saw a"に対応します.つまり,文の長さをnとしたとき,文全体 に対応するエッジのIDはS[0][n] に格納されます.上記の例だとS[0][7]に文 全体に対応するエッジのIDが格納されます.

リンク

構文解析の際には子のエッジにid_schema_unary/4id_schema_binary/5によって定義された文法規則を適用して, 新たに親ができます. 例えば,S[1][2]に格納されたエッジと S[2][4]に格納されたエッジに文法適用した 結果はS[1][4]に格納されます.この際に,同じCKYセル中の複数の等価な sign は, reduce_sign/3で指定された方法でfactoring と呼ばれる処理をされ, ひとつの sign に縮退されます. factoring の処理においては,構文解析後に復元できる情報は切り捨てられるの で,構文解析後に復元できるようリンクと呼ばれるデータ構造にそれらの情報 を格納しています.例えば,子供のサインは切り捨てられる代表的な情報です. 他にも意味構造なども切り捨てて,全てリンクに格納します. 縮退されると複数のエッジが一つのエッジになるため, 一つのエッジに複数のリンクが対応します. 構文解析後,エッジとリンクを相互にたどることによって 全パーズツリーを参照することができます.

文"I saw a girl with a telescope."の場合, S[1][2]に格納されたエッジにはこのような signを 持つものがあります.またS[2][4]に格納されたエッジには このような signを持つものがあります. これらの sign には,id_schema_binary/5で定められた 'head_comp_schema' が適用できます. id_schema_binary/5では,スキーマの名前, 左右の娘の素性構造,親の素性構造,スキーマ適用後に実行する lilfes プログラムが 指定されています(id_schema_unary/4では娘の素性構造がひとつになります). 'head_comp_schema' の場合,左右の娘の素性構造は大体次のように指定されています.

F
SYNSEM|LOCAL|CAT|VAL SUBJ: A
COMPS: < B | C >
SPR: D
SPEC: E
CONJ: < >
, G
SYNSEM: B
上の sign に娘のエッジの sign を単一化します. 親の sign は次のように指定されているので,それと親のエッジの sign を 単一化します(Valence Principle もハードコードされています).
SYNSEM|LOCAL|CAT|VAL SUBJ: A
COMPS: C
SPR: D
SPEC: E
CONJ: < >
DTR
HEAD_DTR: F
NONHEAD_DTR: G
その後,スキーマ適用後に実行する lilfes プログラムによって, 親子エッジの sign を他のプリンシプルを満たすための素性構造と単一化するなどします. 得られた親の signreduce_sign/3によって factoring されます. reduce_sign/3では,スキーマ適用直後の親の sign を与えると 縮退した sign とリンクに格納する素性構造を返すようにすることで, factoring 処理を指定します.リンクに格納する素性構造と エッジの sign を単一化することで,元の sign が復元されます. facotring によって,先ほどの親の sign から 縮退したsign が得られます. その後fom_binary/6に,スキーマの名前 (この場合,'head_comp_schema'),左右の娘のsign, factoring 後の親の sign,factoring時にリンクに格納された素性構造が わたされ,スキーマ適用の FOM が計算されます. (id_schema_unary/4で定義されたスキーマが適用された場合は, fom_unary/5が使われます.) このようにして親のエッジが計算され,チャートのS[1][4]に格納されます.

構文解析が文全体に対応する CKY セル (この例の場合 S[0][7]) まで終わると, そのセル内の全てのエッジについて,fom_root/2によって それらのFOM が 計算されます.fom_root/2では,文の root node の sign が渡されると その sign に対する FOM が返されるようになっています. これら文の root node のエッジが, parse tree の root としての条件を 満たしているかどうかは, root_sign/1 によって最後にチェックされます. 文 "I saw a girl with a telescope." の場合, セル S[0][7] の中の エッジのうち,root_sign/1を満たしかつ最も FOM が高いものは, このような signを持っています. この sign は, ふたつ sign が縮退してひとつになったものです. それぞれ "with a telescope" が動詞句にかかる場合と名詞句にかかる場合に 対応しています. エッジとリンクを相互にたどり FOM の高いほうを選ぶことによって, 最も FOM の高い signを復元することができます.

出力

上記の構文解析によって得られた最も FOM の高い sign をもとにして 出力が行われています. 上の例の場合,"enju/outputdeps.lil" による出力は次のようになります.

ROOT  ROOT  ROOT  ROOT  -1  ROOT  saw       see       VBD  VB   1
saw   see   VBD   VB     1  ARG1  I         i         PRP  PRP  0
saw   see   VBD   VB     1  ARG2  girl      girl      NN   NN   3
a     a     DT    DT     2  ARG1  girl      girl      NN   NN   3
a     a     DT    DT     5  ARG1  telescope telescope NN   NN   6
with  with  IN    IN     4  ARG1  saw       see       VBD  VB   1
with  with  IN    IN     4  ARG2  telescope telescope NN   NN   6


Enju 開発者用マニュアル Enju ホームページ 辻井研究室
MIYAO Yusuke (yusuke@is.s.u-tokyo.ac.jp)