自然言語処理100本ノック 第4章 形態素解析(前半)


第4章の前半の問題を解いた記録。
対象とするファイルはwebページにもある通り、neko.txtとする。
> 夏目漱石の小説『吾輩は猫である』の文章（neko.txt）をMeCabを使って形態素解析し，その結果をneko.txt.mecabというファイルに保存せよ．このファイルを用いて，以下の問に対応するプログラムを実装せよ．
なお，問題37, 38, 39はmatplotlibもしくはGnuplotを用いるとよい．

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

```python
# -*- coding: utf-8 -
__author__ = 'todoroki'

def mecab_reader(mecabfile):
    sentences = []
    sentence = []
    for line in mecabfile:
        if line == "EOS\n":
            if len(sentence) > 0:
                sentences.append(sentence)
            sentence = []
        else:
            surface, features = line.split("\t")
            features = features.split(",")
            dic = {
                'surface': surface,
                'base': features[6],
                'pos': features[0],
                'pos1': features[1]
            }
            sentence.append(dic)
    return sentences

if __name__ == '__main__':
    inputfile = 'neko.txt.mecab'
    outputfile = 'neko.mecab_dic.txt'
    f = open(inputfile, 'r')
    g = open(outputfile, 'w')
    sentences = mecab_reader(f)

    for s in sentences:
        # print str(s).decode("string-escape")
        g.write(str(s).decode("string-escape") + "\n")

    f.close()
    g.close()
```
日本語を含む辞書型`s`を単純に`print s`とすると、日本語がそのまま表示できない。
そのため、`str(s).decode("string-escape")`として日本語を表示できるように対応。

## <i class="fa fa-leaf"></i> 31. 動詞
> 動詞の表層形をすべて抽出せよ．

```python
# -*- coding: utf-8 -
__author__ = 'todoroki'

import problem30

def extract_verb(sentences):
    res = []
    for sentence in sentences:
        for morpheme in sentence:
            if morpheme['pos'] == '動詞':
                res.append(morpheme['surface'])
    return res

if __name__ == "__main__":
    inputfile = 'neko.txt.mecab'
    outputfile = 'neko.mecab_verb.txt'
    f = open(inputfile, "r")
    g = open(outputfile, "w")
    sentences = problem30.mecab_reader(f)
    verbs = extract_verb(sentences)
    for verb in verbs:
        # print verb
        g.write(verb + '\n')
    f.close()
    g.close()
```


## <i class="fa fa-leaf"></i> 32. 動詞の原形
> 動詞の原形をすべて抽出せよ．

```python
# -*- coding: utf-8 -
__author__ = 'todoroki'

import problem30

def extract_verb_base(sentences):
    res = []
    for sentence in sentences:
        for morpheme in sentence:
            if morpheme['pos'] == '動詞':
                res.append(morpheme['base'])
    return res

if __name__ == "__main__":
    inputfile = 'neko.txt.mecab'
    outputfile = 'neko.mecab_verb_base.txt'
    f = open(inputfile, "r")
    g = open(outputfile, "w")
    sentences = problem30.mecab_reader(f)
    verb_bases = extract_verb_base(sentences)
    for verb in verb_bases:
        # print verb
        g.write(verb + '\n')
    f.close()
    g.close()
```


## <i class="fa fa-leaf"></i> 33. サ変名詞
> サ変接続の名詞をすべて抽出せよ．

```python
# -*- coding: utf-8 -
__author__ = 'todoroki'

import problem30

def extract_sahen(sentences):
    res = []
    for sentence in sentences:
        for morpheme in sentence:
            if morpheme['pos1'] == 'サ変接続':
                res.append(morpheme['surface'])
    return res

if __name__ == "__main__":
    inputfile = 'neko.txt.mecab'
    outputfile = 'neko.mecab_sahen.txt'
    f = open(inputfile, "r")
    g = open(outputfile, "w")
    sentences = problem30.mecab_reader(f)
    sahens = extract_sahen(sentences)
    for sahen in sahens:
        # print sahen
        g.write(sahen + '\n')
    f.close()
    g.close()
```


## <i class="fa fa-leaf"></i> 34. 「AのB」
> 2つの名詞が「の」で連結されている名詞句を抽出せよ．

```python
# -*- coding: utf-8 -
__author__ = 'todoroki'

import problem30

def extract_AofB(sentences):
    res = []
    for sentence in sentences:
        for k in xrange(len(sentence)-3):
            triple = sentence[k:k+3]
            b1 = triple[0]['pos'] == '名詞'
            b2 = triple[1]['surface'] == 'の'
            b3 = triple[2]['pos'] == '名詞'
            if b1 and b2 and b3:
                res.append(t['surface'] for t in triple)
    return res

if __name__ == "__main__":
    inputfile = 'neko.txt.mecab'
    outputfile = 'neko.mecab_AofB.txt'
    f = open(inputfile, "r")
    g = open(outputfile, "w")
    sentences = problem30.mecab_reader(f)
    res = extract_AofB(sentences)
    for r in res:
        # print "".join(r)
        g.write("".join(r) + '\n')
    f.close()
    g.close()
```


<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/font-awesome/4.4.0/css/font-awesome.min.css">