言語処理100本ノック 2015の挑戦記録です。環境はUbuntu 16.04 LTS + Python 3.5.2 :: Anaconda 4.1.1 (64-bit)です。過去のノックの一覧はこちらからどうぞ。
第6章: 英語テキストの処理
英語のテキスト(nlp.txt)に対して,以下の処理を実行せよ.
###55. 固有表現抽出
入力文中の人名をすべて抜き出せ.
####出来上がったコード:
# 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 構文]
(http://docs.python.jp/3/library/xml.etree.elementtree.html#supported-xpath-s)の解説はシンプルです。これを見れば、Pythonで使えるXPathの構文はだいたい把握できるかと思います。
今回はElement.iterfind()で、XPathを指定しました。指定しているXPathの意味は、「<NER>
タグの値がPERSON
である/document/sentences/sentence/tokens/token
タグ」です。
なお、前問の<token>
タグの抽出は途中の階層を指定していない乱暴なものだったので、今回はきっちり指定してみました。
56本目のノックは以上です。誤りなどありましたら、ご指摘いただけますと幸いです。
実行結果には、100本ノックで用いるコーパス・データで配布されているデータの一部が含まれます。この第6章で用いているデータのライセンスはクリエイティブ・コモンズ 表示-継承 3.0 非移植(日本語訳)です。