#これまでの経緯などについて
最初の投稿を参照ください
#ノック状況
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の作成
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')
一 名詞,数,*,*,*,*,一,イチ,イチ
記号,空白,*,*,*,*, , ,
吾輩 名詞,代名詞,一般,*,*,*,吾輩,ワガハイ,ワガハイ
は 助詞,係助詞,*,*,*,*,は,ハ,ワ
(長いので略)
感想:形態素解析って初めて聞いたので、そこから調査。mecabのパラメータなどはMeCab: Yet Another Part-of-Speech and Morphological Analyzerを参考にしました。モジュールなどのネーミングが素敵です。
#030.読み込み
#-*-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')
{'surface': '物', 'base': '物', 'pos': '名詞', 'pos1': '一般'}
(長いので略)
感想:出力するファイルは見やすいようにリスト型ではなく、ただの文字列に置き換えました。形態素解析の結果の列に含まれる','の数が7だったり9だったりということに気づくまでとてもハマりました。。。
#031. 動詞
動詞の表層形をすべて抽出せよ.
#-*-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
で
ある
生れ
た
つか
(長いので略)
感想:解析結果のファイルを読み込み、動詞というキーワードを持った列を正規表現で抜き出して、辞書型へ変換後surfaceだけ出力してる。
#032. 動詞の原形
動詞の原形をすべて抽出せよ.
# -*-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
だ
ある
生れる
た
つく
感想:手順は031と同じ。出力をbaseに変えている。
#033. サ変名詞
サ変接続の名詞をすべて抽出せよ.
# -*-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
見当
記憶
話
装飾
突起
(長いので略)
感想:手順は032と同じ。抽出する条件をサ変接続へ変えただけ。
#034. 「AのB」
2つの名詞が「の」で連結されている名詞句を抽出せよ.
#-*-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)
者の子
自分の年
無聊のあまり
左の隅
相手の力量
額の上
方のため
(長いので略)
感想:最初にN=3でposの情報をngram解析して名詞助詞名詞の並びになっているindex番号をリスト化して、その後にマッチするindex番号のsurface情報を抜き出して抜き出した文字列の先頭と語尾に'の'が来ないものを抽出したんですが、お題を正しく見たせていなかった。そして現コードへ修正。お題はちゃんと確認しないとダメですね。反省。