Edited at

素人の言語処理100本ノック:55

More than 1 year has passed since last update.

言語処理100本ノック 2015の挑戦記録です。環境はUbuntu 16.04 LTS + Python 3.5.2 :: Anaconda 4.1.1 (64-bit)です。過去のノックの一覧はこちらからどうぞ。


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


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



55. 固有表現抽出


入力文中の人名をすべて抜き出せ.



出来上がったコード:


main.py

# coding: utf-8

import os
import subprocess
import xml.etree.ElementTree as ET

fname = 'nlp.txt'
fname_parsed = 'nlp.txt.xml'

def parse_nlp():
'''nlp.txtをStanford Core NLPで解析しxmlファイルへ出力
すでに結果ファイルが存在する場合は実行しない
'''

if not os.path.exists(fname_parsed):

# StanfordCoreNLP実行、標準エラーはparse.outへ出力
subprocess.run(
'java -cp "/usr/local/lib/stanford-corenlp-full-2016-10-31/*"'
' -Xmx2g'
' edu.stanford.nlp.pipeline.StanfordCoreNLP'
' -annotators tokenize,ssplit,pos,lemma,ner,parse,dcoref'
' -file ' + fname + ' 2>parse.out',
shell=True, # shellで実行
check=True # エラーチェックあり
)

# nlp.txtを解析
parse_nlp()

# 解析結果のxmlをパース
root = ET.parse(fname_parsed)

# tokenの抽出
for token in root.iterfind(
'./document/sentences/sentence/tokens/token[NER="PERSON"]'
):
print(token.findtext('word'))



実行結果:


端末:先頭部分

Alan

Turing
Joseph
Weizenbaum
MARGIE
Schank
Wilensky
Meehan
Lehnert
Carbonell
Lehnert
Racter
Jabberwacky
Moore


人名の抽出

Stanford Core NLPには、Stanford Named Entity Recognizer (NER)という固有表現を解析する仕組みがあり、xmlファイルにはその結果が<NER>タグで出力されています。<NER>タグの値は「PERSON」、「ORGANIZATION」、「LOCATION」などになるそうです。

今回は前問のコードをベースに、<NER>タグが「PERSON」の<token>タグだけを抽出するように変更しました。


XPathの利用

XPathは、XML内の任意の部分を指定するための言語です。今回はこれを利用しました。

XPathはかなり複雑な言語らしく、Pythonでも一部しかサポートしていません。ただそのおかげで、サポートされている XPath 構文の解説はシンプルです。これを見れば、Pythonで使えるXPathの構文はだいたい把握できるかと思います。

今回はElement.iterfind()で、XPathを指定しました。指定しているXPathの意味は、「<NER>タグの値がPERSONである/document/sentences/sentence/tokens/tokenタグ」です。

なお、前問<token>タグの抽出は途中の階層を指定していない乱暴なものだったので、今回はきっちり指定してみました。

 

56本目のノックは以上です。誤りなどありましたら、ご指摘いただけますと幸いです。


実行結果には、100本ノックで用いるコーパス・データで配布されているデータの一部が含まれます。この第6章で用いているデータのライセンスはクリエイティブ・コモンズ 表示-継承 3.0 非移植日本語訳)です。