【python】100本ノックにチャレンジ!(030〜034)

#これまでの経緯などについて
[最初の投稿](http://qiita.com/masassy/items/6e25c0adc4ef7c8bf4fc)を参照ください

#[ノック状況](https://qiita.com/masassy/items/6f022af11dfdc16b9cea)
9/24追加

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

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

#準備:neko.txt.mecabの作成
```python:file_analyze_mecab_030.py
from natto import MeCab
import codecs

def file_analyze_mecab(input_filename,output_filename):

    with codecs.open(input_filename,'r','utf-8') as f:
        text = f.read()

    m = MeCab.Tagger("mecabrc")
    wt = m.parse(text)

    with codecs.open(output_filename,'w','utf-8') as wf:
        wf.write(wt)

if __name__=="__main__":
    file_analyze_mecab('neko.txt','neko.txt.mecab')
```
```text:result
一	名詞,数,*,*,*,*,一,イチ,イチ
　	記号,空白,*,*,*,*,　,　,　
吾輩	名詞,代名詞,一般,*,*,*,吾輩,ワガハイ,ワガハイ
は	助詞,係助詞,*,*,*,*,は,ハ,ワ
(長いので略)
```
感想：形態素解析って初めて聞いたので、そこから調査。mecabのパラメータなどは[MeCab: Yet Another Part-of-Speech and Morphological Analyzer](http://taku910.github.io/mecab/)を参考にしました。モジュールなどのネーミングが素敵です。

#030.読み込み
```python:mecab_030.py
#-*-coding:utf-8-*-

import codecs

if __name__ == "__main__":
    with codecs.open("neko.txt.mecab",'r','utf-8') as f:
        data = f.readlines()

    mecab_list=[]
    temp_dict ={}
    for temp_word in data:
        temp_word = temp_word.replace('\t', ',')
        temp_word = temp_word.replace('\n', '')
        if(temp_word.count(',')==9 or temp_word.count(',')==7):
            temp_list = temp_word.split(',')
            temp_dict={'surface':temp_list[0],'base':temp_list[7],'pos':temp_list[1],'pos1':temp_list[2]}
            mecab_list.append(temp_dict)
        else:
            continue
    print(mecab_list)

    with codecs.open('neko.txt.mecab.analyze','w','utf-8') as wf:
        for line in mecab_list:
            wf.write(str(line)+'\n')
```
```text:result
{'surface': '物', 'base': '物', 'pos': '名詞', 'pos1': '一般'}
(長いので略)
```

感想：出力するファイルは見やすいようにリスト型ではなく、ただの文字列に置き換えました。形態素解析の結果の列に含まれる','の数が7だったり9だったりということに気づくまでとてもハマりました。。。

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

```python:vurb_031.py
#-*-coding:utf-8-*-

import codecs
import re
import ast

if __name__ == "__main__":
    with codecs.open("neko.txt.mecab.analyze",'r','utf-8') as f:
        temp_lines = f.readlines()

    pattern = re.compile(r".*動詞.*")
    data = {}
    for temp_line in temp_lines:
        if pattern.match(temp_line):
            data = ast.literal_eval(temp_line)
            print(data['surface'])
        else:
            continue
```
```text:result
で
ある
生れ
た
つか
（長いので略）
```
感想：解析結果のファイルを読み込み、動詞というキーワードを持った列を正規表現で抜き出して、辞書型へ変換後surfaceだけ出力してる。

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

```python:base_vurb_032.py
# -*-coding:utf-8-*-

import codecs
import re
import ast

if __name__ == "__main__":
    with codecs.open("neko.txt.mecab.analyze", 'r', 'utf-8') as f:
        temp_lines = f.readlines()

    pattern = re.compile(r".*動詞.*")
    data = {}
    for temp_line in temp_lines:
        if pattern.match(temp_line):
            data = ast.literal_eval(temp_line)
            print(data['base'])
        else:
            continue
```
```text:result
だ
ある
生れる
た
つく
```
感想：手順は031と同じ。出力をbaseに変えている。

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

```python:sahen_noun_033.py
# -*-coding:utf-8-*-

import codecs
import re
import ast

if __name__ == "__main__":
    with codecs.open("neko.txt.mecab.analyze", 'r', 'utf-8') as f:
        temp_lines = f.readlines()

    pattern = re.compile(r".*サ変接続.*")
    data = {}
    for temp_line in temp_lines:
        if pattern.match(temp_line):
            data = ast.literal_eval(temp_line)
            print(data['surface'])
        else:
            continue
```
```text:result
見当
記憶
話
装飾
突起
(長いので略)
```
感想：手順は032と同じ。抽出する条件をサ変接続へ変えただけ。

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

```python:no_noun_034.py
#-*-coding:utf-8-*-

import codecs
import ast

if __name__ == "__main__":

    with codecs.open('neko.txt.mecab.analyze','r','utf-8') as f:
        temp_lines = f.readlines()

    flag = 0
    temp_list = []
    for temp_line in temp_lines:
        temp_dict = ast.literal_eval(temp_line)
        if (temp_dict['pos'] == '名詞' and flag == 0):
            temp_word = temp_dict['surface']
            flag = 1
            continue

        elif(temp_dict['surface']=='の' and temp_dict['pos']=='助詞' and flag == 1):
            temp_word += temp_dict['surface']
            flag = 2
            continue

        elif(temp_dict['pos']=='名詞' and flag == 2):
            temp_word += temp_dict['surface']
            temp_list.append(temp_word)
            temp_word = ''
            flag = 0
            continue

        else:
            temp_word=''
            flag =0
            continue

    no_noun_list = set(temp_list)


    for temp in no_noun_list:
        print(temp)
```
```text:result
者の子
自分の年
無聊のあまり
左の隅
相手の力量
額の上
方のため
(長いので略)
```
感想：最初にN＝３でposの情報をngram解析して名詞助詞名詞の並びになっているindex番号をリスト化して、その後にマッチするindex番号のsurface情報を抜き出して抜き出した文字列の先頭と語尾に'の'が来ないものを抽出したんですが、お題を正しく見たせていなかった。そして現コードへ修正。お題はちゃんと確認しないとダメですね。反省。