SyntaxNetを使い、英文の各単語にタグ付けを行うところまで完了した。これにより、サンプルの英文に対して、各単語がどのような意味を持つのか(名詞、動詞など)を解析し、表示できるようになった。
つづいて、チュートリアルを読み進んでいき、SyntaxNetを使った構文解析の方法について調査していく。 SyntaxNetの構文解析により、英文を与えると、どのような構文でその英文が成り立っているのかが分かるようになる。
以下はSyntaxNetのチュートリアルの説明図から引用。
SyntaxNetのLocal Pretraining
SyntaxNetがどのようにして構文解析の学習をしているかというと、以下のようなアルゴリズムに基づくらしい。
transition-based dependency parser
というのは僕も全く知らなかったのだが、見た目は非常にシンプルな解析法に思える。
この解析法は、まずは与えられた英語構文をBufferという領域に格納し、Stackという領域に移動しながら構文解析を進めていく。
このBufferとStackの操作は、以下の3つの操作が定義されている。
- SHIFT : Bufferから単語を一つ取り出し、Stackにプッシュする。
- LEFT_ARC : Stackの先頭の2つの単語を取り出し、それぞれを線で結ぶ。このとき、右側の単語から左側の単語に対して線を結ぶ。最後に最初の単語をStackに書き戻す。
- RIGHT_ARC : Stackの先頭の2つの単語を取り出し、それぞれを線で結ぶ。このとき、左側の単語から右側の単語に対して線を結ぶ。最後に2番目の単語をStackに書き戻す。
チュートリアルには以下のGIFが貼られている。ただし高速すぎて何が何だか分からないので、テキストに起こしてみる。
I booked a ticket to Google.
操作 | Stack | Buffer | Semantic |
---|---|---|---|
I booked | a ticket to Google | ||
LEFT_ARC | booked | a ticket to Google | I<--booked |
SHIFT | booked a | ticket to Google | I<--booked |
SHIFT | booked a ticket | to Google | I<--booked |
LEFT_ARC | booked ticket | to Google | I<--booked, a<--ticket |
SHIFT | booked ticket to | I<--booked, a<--ticket | |
SHIFT | booked ticket to Google | I<--booked, a<--ticket | |
RIGHT_ARC | booked ticket to | I<--booked, a<--ticket, to-->Google | |
RIGHT_ARC | booked ticket | I<--booked, a<--ticket, to-->Google, ticket-->to | |
RIGHT_ARC | booked | I<--booked, a<--ticket, to-->Google, ticket-->to, booked-->ticket |
なるほど、確かにこの3つの操作の順番を定義すれば、英文の構文がつかめることになる。
次は、実際にSyntaxNetを使って、構文解析をさせてみよう。