言語処理100本ノック 2020 第5章 前半
第5章 係り受け解析の前半(40-44まで)解説書きます。
MeCabに続き、CaboChaとクラスとお友達になる章。
勉強会の準備などで解けていなかったけれど、やっと再開。
目次
- 40. 係り受け解析結果の読み込み(形態素)
- 41. 係り受け解析結果の読み込み(文節・係り受け)
- 42. 係り元と係り先の文節の表示
- 43. 名詞を含む文節が動詞を含む文節に係るものを抽出
- 44. 係り受け木の可視化
準備
CaboChaのインストール
$ brew install cabocha $ brew install crf++
この章で使うファイル
cabocha -f1 ai.ja.txt > ai.ja.txt.parsed
できたファイルは以下の通り。
オプションがないとtree形式で出てきて加工つらそうだったので、
-f1
でlattice形式にした。
* 0 -1D 1/1 0.000000 人工 名詞,一般,*,*,*,*,人工,ジンコウ,ジンコー 知能 名詞,一般,*,*,*,*,知能,チノウ,チノー EOS EOS * 0 17D 1/1 0.388993 人工 名詞,一般,*,*,*,*,人工,ジンコウ,ジンコー 知能 名詞,一般,*,*,*,*,知能,チノウ,チノー * 1 17D 2/3 0.613549 ( 記号,括弧開,*,*,*,*,(,(,( じん 名詞,一般,*,*,*,*,じん,ジン,ジン こうち 名詞,一般,*,*,*,*,こうち,コウチ,コーチ のう 助詞,終助詞,*,*,*,*,のう,ノウ,ノー 、 記号,読点,*,*,*,*,、,、,、 、 記号,読点,*,*,*,*,、,、,、
参考
40. 係り受け解析結果の読み込み(形態素)
Classあまり書いてこなかったのもあり時間かかってしまった。
ファイルをよく見ると、EOSや空白行、*から始まる行など特殊な場合がある。
そういったパターンは事前に除外する必要がある。
ポイント
- クラスのインスタンス変数について、中身を見る時はvars()を使う
- 普通にprintすると、オブジェクトのアドレスが表示される
解答
# coding:utf-8 class Morph: def __init__(self, mp): self.surface = mp['surface'] self.base = mp['base'] self.pos = mp['pos'] self.pos1 = mp['pos1'] def CabochaParser(): path = 'ai.ja.txt.parsed' cabocha = [] with open(path) as f: for line in f: tmp_line = line.split('EOS\n') tmp_line = list(filter(lambda x: x != '', tmp_line)) # print(tmp_line) for item in tmp_line: # print(item) if item == '' or item[0] == '*': continue (surface, attr) = item.split('\t') attr = attr.split(',') # print(surface, attr) attr_dic = { 'surface': surface, 'base': attr[6], 'pos': attr[0], 'pos1': attr[1] } cabocha.append(Morph(attr_dic)) return cabocha def main(): res = CabochaParser() # Morphクラスのインスタンス変数がほしいので、varsで取り出す for i in res: print(vars(i)) if __name__ == "__main__": main()