LoginSignup
1
2

More than 3 years have passed since last update.

言語処理100本ノック-57:係り受け解析

Posted at

言語処理100本ノック 2015「第6章: 英語テキストの処理」57本目「係り受け解析」記録です。
「言語処理100本ノック-44:係り受け木の可視化」でやった内容のStanford CoreNLP版ですね。かなりのコードを流用しています。

参考リンク

リンク 備考
057.係り受け解析.ipynb 回答プログラムのGitHubリンク
素人の言語処理100本ノック:57 多くのソース部分のコピペ元
Stanford Core NLP公式 最初に見ておくStanford Core NLPのページ

環境

種類 バージョン 内容
OS Ubuntu18.04.01 LTS 仮想で動かしています
pyenv 1.2.16 複数Python環境を使うことがあるのでpyenv使っています
Python 3.8.1 pyenv上でpython3.8.1を使っています
パッケージはvenvを使って管理しています
Stanford CoreNLP 3.9.2 インストールしたのが1年前で詳しく覚えていないです・・・
1年たってもそれが最新だったのでそのまま使いました
openJDK 1.8.0_242 他目的でインストールしていたJDKをそのまま使いました

上記環境で、以下のPython追加パッケージを使っています。通常のpipでインストールするだけです。

種類 バージョン
pydot 1.4.1

第6章: 英語テキストの処理

学習内容

Stanford Core NLPを用いた英語のテキスト処理を通じて,自然言語処理の様々な基盤技術を概観します.

Stanford Core NLP, ステミング, 品詞タグ付け, 固有表現抽出, 共参照解析, 係り受け解析, 句構造解析, S式

ノック内容

英語のテキスト(nlp.txt)に対して,以下の処理を実行せよ.

57. 係り受け解析

Stanford Core NLPの係り受け解析の結果(collapsed-dependencies)を有向グラフとして可視化せよ.可視化には,係り受け木をDOT言語に変換し,Graphvizを用いるとよい.また,Pythonから有向グラフを直接的に可視化するには,pydotを使うとよい.

課題補足(「係り受け」について)

係り受けはStanford CoreNLP(英語?)では"Dependencies"と呼ばれ、Stanford CoreNLPの仕組みはStanford Dependenciesに載っています。

どうも2種類あるらしく、今回対象とするのはcollapsed-dependenciesの方です。
image.png

やった後に気づきたのですが、有向グラフでエッジ間の関係性(prep_onとか)を追加で書き込めばもっとわかりやすかったです。

回答

回答プログラム 057.係り受け解析.ipynb

import xml.etree.ElementTree as ET

import pydot

for i, sentence in enumerate(ET.parse('./nlp.txt.xml').iterfind('./document/sentences/sentence')):
    edges = []
    for dependency in sentence.iterfind('./dependencies[@type="collapsed-dependencies"]/dep'):

        # 句読点除外
        if dependency.get('type') != 'punct':
            governor = dependency.find('./governor')
            dependent = dependency.find('./dependent')
            edges.append(((governor.get('idx'), governor.text), 
                          (dependent.get('idx'), dependent.text)))
    if len(edges) > 0:
        graph = pydot.graph_from_edges(edges, directed=True)
        graph.write_jpeg('057.graph_{}.jpeg'.format(i))

    if i > 5:
        break

回答解説

XMLファイルのパス

以下のXMLファイルのパスと目的とする係り元、係り先のマッピングです。第5階層のdependenciesタグは属性typecollapsed-dependenciesのものを対象とします。

出力 第1階層 第2階層 第3階層 第4階層 第5階層 第6階層 第7階層
係り元 root document sentences sentence dependencies dep governor
係り先 root document sentences sentence dependencies dep dependent

XMLファイルはGitHubに置いています。

nlp.txt.xml(抜粋)
<root>
  <document>
    <docId>nlp.txt</docId>
    <sentences>
      <sentence id="1">

--中略--

        <dependencies type="collapsed-dependencies">
          <dep type="root">
            <governor idx="0">ROOT</governor>
            <dependent idx="18">field</dependent>
          </dep>
          <dep type="amod">
            <governor idx="3">processing</governor>
            <dependent idx="1">Natural</dependent>
          </dep>
          <dep type="compound">
            <governor idx="3">processing</governor>
            <dependent idx="2">language</dependent>
          </dep>

Pydotを使った有向グラフ表示

以下のコード部分です。やっていることは、「言語処理100本ノック-44:係り受け木の可視化」と同じなので解説しません。ただ、エッジ間の関係性をGraphviznetworkxを使って追加すればよかったと、後悔しています。
記事「networkxでマルチグラフとか、綺麗なグラフを書く【python】」や記事「Python上でGraphvizを使って綺麗なグラフを描く」あたりを参考にすれば書けそう。
そもそもpydotは、2018年12月から更新されていないので今後も続くのか心配です。

for i, sentence in enumerate(ET.parse('./nlp.txt.xml').iterfind('./document/sentences/sentence')):
    edges = []
    for dependency in sentence.iterfind('./dependencies[@type="collapsed-dependencies"]/dep'):

        # 句読点除外
        if dependency.get('type') != 'punct':
            governor = dependency.find('./governor')
            dependent = dependency.find('./dependent')
            edges.append(((governor.get('idx'), governor.text), 
                          (dependent.get('idx'), dependent.text)))
    if len(edges) > 0:
        graph = pydot.graph_from_edges(edges, directed=True)
        graph.write_jpeg('057.graph_{}.jpeg'.format(i))

出力結果(実行結果)

プログラム実行すると以下の結果が出力されます(最初の3文のみ)。

image.png

image.png

image.png

1
2
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
2