👩💻
言語処理100本ノック 2020 (Rev 2) 第5章: 係り受け解析 40. 係り受け解析結果の読み込み(形態素)
問題
40. 係り受け解析結果の読み込み(形態素)
形態素を表すクラスMorphを実装せよ.このクラスは表層形(surface),基本形(base),品詞(pos),品詞細分類1(pos1)をメンバ変数に持つこととする.さらに,係り受け解析の結果(ai.ja.txt.parsed)を読み込み,各文をMorphオブジェクトのリストとして表現し,冒頭の説明文の形態素列を表示せよ.
solution40.py
class Morph:
def __init__(self, dc):
self.surface = dc['surface']
self.base = dc['base']
self.pos = dc['pos']
self.pos1 = dc['pos1']
def parse_cabocha(block):
res = []
for line in block.split('\n'):
if line == '':
return res
elif line[0] == '*':
continue
(surface, attr) = line.split('\t')
attr = attr.split(',')
lineDict = {
'surface': surface,
'base': attr[6],
'pos': attr[0],
'pos1': attr[1]
}
res.append(Morph(lineDict))
filename = 'chapter05/ai.ja.txt.parsed'
with open(filename, mode='rt', encoding='utf-8') as f:
blocks = f.read().split('EOS\n')
blocks = list(filter(lambda x: x != '', blocks))
blocks = [parse_cabocha(block) for block in blocks]
for m in blocks[1]:
print(vars(m))
output
{'surface': '人工', 'base': '人工', 'pos': '名詞', 'pos1': '一般'}
{'surface': '知能', 'base': '知能', 'pos': '名詞', 'pos1': '一般'}
{'surface': '(', 'base': '(', 'pos': '記号', 'pos1': '括弧開'}
{'surface': 'じん', 'base': 'じん', 'pos': '名詞', 'pos1': '一般'}
{'surface': 'こうち', 'base': 'こうち', 'pos': '名詞', 'pos1': '一般'}
この問題では、CaboCha
を用いて係り受け解析した結果を読み込んでいきます。
まず、Morph
クラスを定義し、こちらは形態素解析の結果を格納するためのクラスです。それには、表層形(surface
)、基本形(base
)、品詞(pos
)、品詞細分類1(pos1
)という4つの変数が定義されています。次に、parse_cabocha
関数を定義します。この関数は、CaboCha
によって出力された結果をパースし、Morph
オブジェクトのリストを返します。最後に、filename
変数には、CaboCha
によって解析されたテキストファイルのパスが代入します。そして、そのファイルを読み込んで、形態素解析の結果を得るために、parse_cabocha
関数を使って、各ブロック(文章の区切り)ごとに形態素解析を実行し、その結果を表示しています。vars()
はPythonの built-in
関数で、それが呼び出されるオブジェクトのインスタンス変数を辞書形式で返します。vars(m)
として呼び出され、それが呼び出されるm
は、Morphクラス
のインスタンスであり、それが持っているインスタンス変数 (surface
, base
, pos
, pos1
)を辞書型で取得し、print
で表示しています。
Discussion