言語処理100本ノック 2015 第4章 30〜34


言語処理100本ノック 2015」の「第4章: 形態素解析」、30〜34。

30. 形態素解析結果の読み込み

形態素解析結果(neko.txt.mecab)を読み込むプログラムを実装せよ.ただし,各形態素は表層形(surface),基本形(base),品詞(pos),品詞細分類1(pos1)をキーとするマッピング型に格納し,1文を形態素(マッピング型)のリストとして表現せよ.第4章の残りの問題では,ここで作ったプログラムを活用せよ.

「マッピング型」というのがよくわからなかったものの、「をキーとする」という記載から辞書にしておけば良さそうなので、1文を辞書リストにするようにコードを書いてみました。

import argparse


def read_morphemes(lines):
    morphemes = []

    for line in lines:
        if line.rstrip() == 'EOS':
            if len(morphemes) > 0:
                yield morphemes

            morphemes = []
        else:
            t1 = line.split('\t')
            t2 = t1[1].split(',')
            m = {'surface': t1[0], 'base': t2[6], 'pos': t2[0], 'pos1': t2[1]}
            morphemes.append(m)


def main():
    parser = argparse.ArgumentParser()
    parser.add_argument('infile')
    args = parser.parse_args()

    with open(args.infile, mode='r') as f:
        morphemes = read_morphemes(f)

        for morpheme in morphemes:
            print(morpheme)


if __name__ == '__main__':
    main()

31. 動詞

動詞の表層形をすべて抽出せよ.

先程の「read_morphemes」を使用する形で以下のように書いてみました。

import argparse
from itertools import chain


def read_morphemes(lines):
    #ここは前の課題と一緒

def get_words(morphemes):
    words = [m['surface'] for m in chain.from_iterable(morphemes)
             if m['pos'] == '動詞']
    return words


def main():
    parser = argparse.ArgumentParser()
    parser.add_argument('infile')
    args = parser.parse_args()

    with open(args.infile, mode='r') as f:
        morphemes = read_morphemes(f)
        words = get_words(morphemes)

    for word in words:
        print(word)


if __name__ == '__main__':
    main()

ポイントは「chain.from_iterable」使ってC#で言うところのSelectManyみたいなことをやれる、ということでしょうか。

32. 動詞の原形

動詞の原形をすべて抽出せよ.

先の課題のget_wordsを書き換えただけ。

def get_words(morphemes):
    words = [m['base'] for m in chain.from_iterable(morphemes)
             if m['pos'] == '動詞']
    return words

33. サ変名詞

サ変接続の名詞をすべて抽出せよ.

これもget_wordsのみ書き換えで対応。

def get_words(morphemes):
    words = [m['base'] for m in chain.from_iterable(morphemes)
             if m['pos'] == '名詞' and m['pos1'] == 'サ変接続']
    return words

34. 「AのB」

2つの名詞が「の」で連結されている名詞句を抽出せよ.

これも基本的にget_words部分の書き換えですが、言語処理100本ノック 2015 第1章 05〜09で作ったngramを流用してみます。

def ngram(s, n):
    return [s[i:i + n] for i in range(len(s))]


def get_words(morphemes):
    ngrams = (y for y in chain.from_iterable(ngram(x, 3) for x in morphemes)
              if len(y) == 3)
    words = [x[0]['surface'] + x[1]['surface'] + x[2]['surface']
             for x in ngrams
             if x[0]['pos'] == '名詞' and x[1]['surface'] == 'の'
             and x[2]['pos'] == '名詞']
    return words
スポンサーリンク

フォローする

スポンサーリンク