2018年04月05日

言語処理100本ノックでPython入門 #33 - サ変接続の名詞

  
言語処理100本ノック 2015の問題33に挑戦です。

■ 問題


夏目漱石の小説『吾輩は猫である』の文章(neko.txt)をMeCabを使って形態素解析し,その結果をneko.txt.mecabというファイルに保存せよ.このファイルを用いて,以下の問に対応するプログラムを実装せよ. なお,問題37, 38, 39はmatplotlibもしくはGnuplotを用いるとよい.

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


■ Pythonのコード
import re

def analyze():
    lines = []
    sentence = []
    with open('neko.txt.mecab', 'r', encoding='utf8') as fin:
        for line in fin:
            words = re.split(r'\t|,|\n', line)
            if words[0] == 'EOS':
                if sentence:
                    lines.append(sentence)
                    sentence = []
                continue
            sentence.append({
                "surface": words[0],
                "base": words[7],
                "pos": words[1],
                "pos1": words[2],
            })
    return lines

def extractNouns(lines):
    for sentense in lines:
        seq = filter(lambda w: w['pos'] == '名詞' and w['pos1'] == 'サ変接続', sentense)
        yield from map(lambda w: w['surface'], seq)

def main():
    article = analyze()
    nouns = [surface for surface in extractNouns(article)]
    print(nouns[:50])

if __name__ == '__main__':
    main()


書いたコードについては、前回とほとんど同じなので、特筆すべき点はないです。

ラムダ式が少し複雑になったけど、タプルではなくて文字列を列挙しているので、プログラミングの観点からは、こちらのほうが易しいですね。

論理演算子の論理積が&&じゃなくてandなのがどうも面倒です。いつも&&と書いてエラーになっています。

ところで、このところ新しいし知識を仕入れなくても問題を解くことができるようになってきました。 文法で主要なのはあとはクラスくらいでしょうか? No.33以降の問題文を見てみると、第5章にクラスを実装せよという問題があるので、それまではクラスを使わずに解いていこうと思います。


■ 結果

プログラムでは取り出した先頭50個を表示しています。
なるほど、こういったものが、サ変接続の名詞なのか。
['見当', '記憶', '話', '装飾', '突起', '運転', '記憶', '分別', '決心', '我慢', '餓死', '訪問', '始末', '猶予', '遭遇', '我慢', '記憶', '返報', '勉強', '勉強', '昼寝', '珍重', '昼寝', '経験', '供', '供', '供', '供', '——', '——', '同居', '観察', '断言', '同衾', '供', '迫害', '尊敬', '生活', '剿滅', '議論', '所有', '憤慨', '観念', '御馳走', '掠奪', '代言', '我儘', '我儘', '失敗', '話']