アイソモカ

知の遊牧民の開発記録

開発記録 200205 Wed (100本ノック #048, Stanford CoreNLP)

CoreNLP 使うとき、1文しかなくてもごっつ時間かかるねんけど、なんでやろなあ。  

2020/02/06 追記:アノテータオプション付けへんと、機械学習の計算ようさんしはるからや。ルールベースの共参照解析を指定すると、そないに時間かからへんで。

isomocha.hatenablog.com

言語処理100本ノック #048: タプルの抽出

58. タプルの抽出

Stanford Core NLP係り受け解析の結果(collapsed-dependencies)に基づき,「主語 述語 目的語」の組をタブ区切り形式で出力せよ.ただし,主語,述語,目的語の定義は以下を参考にせよ.

  • 述語: nsubj関係とdobj関係の子(dependant)を持つ単語
  • 主語: 述語からnsubj関係にある子(dependent)
  • 目的語: 述語からdobj関係にある子(dependent)

100本ノック #047 と collapsed-dependencies

I have a pen.

という例文について、 Stanford CoreNLP で係り受け解析した結果を前回 #047 で書いたコードで可視化すると、下のようになる。

f:id:piijey:20200204231409p:plain
I have a pen. の係り受け

collapsed-dependencies の該当する部分

          ...
          <dep type="nsubj">
            <governor idx="2">have</governor>
            <dependent idx="1">I</dependent>
          </dep>
          ...
          <dep type="dobj">
            <governor idx="2">have</governor>
            <dependent idx="4">pen</dependent>
          </dep>
          ...

解答

1文について、nsubj 関係と dobj 関係をそれぞれ辞書に格納し、文の最後に辞書同士を照らし合わせて両方を持つ述語を探すという流れ。

# knock_058.py
import xml.etree.ElementTree as ET

coding = False
if coding:
    xmlfile = 'subject_object.txt.xml'
else:
    xmlfile = 'nlp.txt.xml'


def find_svo(sentence):
    vs_dict = {} # key = gvn_idx, value = (s,v)
    vo_dict = {} # key = gvn_idx, value = (v,o)

    for deps in sentence.findall('./dependencies'):
        if deps.get('type') != 'collapsed-dependencies':
            continue
        for dep in deps.findall('./dep'):
            gvn = dep.find('governor')
            dpn = dep.find('dependent')
            if dep.get('type') in ['nsubj']:
                vs_dict[gvn.get('idx')] = (gvn.text, dpn.text)
            elif dep.get('type') in ['dobj']:
                vo_dict[gvn.get('idx')] = (gvn.text, dpn.text)

    for k in vs_dict:
        if k in vo_dict:
            if coding:
                yield [sentence.get('id'), vs_dict[k][1], vs_dict[k][0], vo_dict[k][1]]
            else:
                yield [vs_dict[k][1], vs_dict[k][0], vo_dict[k][1]]


if __name__ == '__main__':
    tree = ET.parse(xmlfile)
    root = tree.getroot()
    for sentence in root.findall('./document/sentences/sentence'):
        for svo in list(find_svo(sentence)):
            print('\t'.join(i for i in svo))

出力

# python knock_058.py >> knock_058.txt の出力
understanding   involve generation
Turing  published   article
experiment  involved    translation
ELIZA   provided    interaction
patient exceeded    base
ELIZA   provide response
which   structured  information
underpinnings   discouraged sort
that    underlies   approach
Some    produced    systems
which   make    decisions
that    contains    errors
implementations involved    coding
algorithms  take    set
Some    produced    systems
which   make    decisions
models  have    advantage
they    express certainty
Systems have    advantages
procedures  make    use
that    make    decisions