yasuokaの日記: 単語間・文節間の係り受け解析システムとしてのGiNZA v4.0.0
私(安岡孝一)の昨日の日記に対して、GiNZA v4.0.0にはginza.bunsetu_spansという関数があって、spaCyのSpanとして文節を取り出せる、との情報をいただいた。素晴らしい。GiNZAにdeplacyを併用して、単語間の係り受けと文節間の係り受けを解析してみよう。まずはインストール。
$ pip3 install -U ginza deplacy
次に「国境の長いトンネルを抜けると雪国であった。」という文に対して、単語間の係り受けを可視化してみよう。
$ python3
>>> import spacy
>>> ja=spacy.load("ja_ginza")
>>> doc=ja("国境の長いトンネルを抜けると雪国であった。")
>>> import deplacy
>>> deplacy.render(doc,Japanese=True)
国境 NOUN ═╗<══╗ nmod(体言による連体修飾語)
の ADP <╝ ║ case(格表示)
長い ADJ <══╗ ║ acl(連体修飾節)
トンネル NOUN ═╗═╝═╝<╗ obj(目的語)
を ADP <╝ ║ case(格表示)
抜ける VERB ═══════╝═╗<╗ acl(連体修飾節)
と SCONJ <════════╝ ║ mark(標識)
雪国 NOUN ═╗═╗═╗═════╝═╗ ROOT(親)
で AUX <╝ ║ ║ ║ cop(繫辞)
あっ AUX <══╝ ║ ║ aux(動詞補助成分)
た AUX <════╝ ║ aux(動詞補助成分)
。 PUNCT <════════════╝ punct(句読点)
「長い」⇐acl=「トンネル」については、私個人としてはamodの方がいいのではないか、と思うものの、まあ、そこは立場の違いだろう。続けてginza.bunsetu_spansで、文節の一覧を見てみよう。
>>> import ginza
>>> spans=ginza.bunsetu_spans(doc)
>>> print(spans)
[国境の, 長い, トンネルを, 抜けると, 雪国であった。]
5つの文節から構成されていることがわかる。では、文節間の係り受けを見てみよう。
>>> bdeps=[(ginza.bunsetu_span(t),b) for b in spans for t in b.lefts]
>>> print(bdeps)
[(国境の, トンネルを), (長い, トンネルを), (トンネルを, 抜けると), (抜けると, 雪国であった。)]
b.leftsは、文節bから左向き(文頭方向)に出ている単語係り受けのうち、文節の外に出ていくものの一覧だが、これを逆向きに解釈すれば、文節間の係り受けとして扱える。可視化すると、こんな感じ。
>>> print("\n".join(str(i)+" -> "+str(j) for i,j in bdeps))
国境の -> トンネルを
長い -> トンネルを
トンネルを -> 抜けると
抜けると -> 雪国であった。
日本語における単語間の係り受けと、文節間の係り受けは、微妙な問題を孕んでいるのだが、ぜひ挑戦してみてほしい。
単語間・文節間の係り受け解析システムとしてのGiNZA v4.0.0 More ログイン