言語処理100本ノック 2015をやってみた(第4章)
スポンサーリンク
でた、形態素解析。こんなのも簡単にできちゃう時代。恐ろしや。
[以下自分用メモ]
Wiki: http://ja.wikipedia.org/wiki/MeCab
公式ページ: http://mecab.googlecode.com/svn/trunk/mecab/doc/index.html
#呼び出し方
MeCab.Tagger('-Ochasen')
MeCab.Tagger('mecabrc')
MeCab.Tagger('-Owakati')
MeCab.Tagger('-Oyomi')
MeCab.Tagger('-Ochasen')
形態素解析エンジンMeCab-pythonを使ってみた. - Subspace at Life
準備
【プログラム】
# coding: utf-8
import sys
import MeCab
m = MeCab.Tagger ()
f = open('neko.txt','r')
data = f.read()
f.close()
f = open('neko.txt.mecab','w')
f.write(m.parse(data))
f.close()【結果】
$ sudo python 3x.py $ head -n 10 neko.txt.mecab 一 名詞,数,*,*,*,*,一,イチ,イチ 記号,空白,*,*,*,*, , , 吾輩 名詞,代名詞,一般,*,*,*,吾輩,ワガハイ,ワガハイ は 助詞,係助詞,*,*,*,*,は,ハ,ワ 猫 名詞,一般,*,*,*,*,猫,ネコ,ネコ で 助動詞,*,*,*,特殊・ダ,連用形,だ,デ,デ ある 助動詞,*,*,*,五段・ラ行アル,基本形,ある,アル,アル 。 記号,句点,*,*,*,*,。,。,。 名前 名詞,一般,*,*,*,*,名前,ナマエ,ナマエ は 助詞,係助詞,*,*,*,*,は,ハ,ワ
以下の順で出力されている
「表層形\t品詞,品詞細分類1,品詞細分類2,品詞細分類3,活用形,活用型,原形,読み,発音」
30. 形態素解析結果の読み込み
表層形(surface),基本形(原型)(base),品詞(pos),品詞細分類1(pos1)として辞書型に入れる。
【実行&結果】
作成した辞書型データを json.dumps(temp1, sort_keys=True, indent=4,ensure_ascii=False)で見るとこんな感じ。
{
"0": {
"base": "一",
"pos": "名詞",
"pos1": "数",
"surface": "一"
},
"1": {
"base": " ",
"pos": "記号",
"pos1": "空白",
"surface": " "
},
"2": {
"base": "吾輩",
"pos": "名詞",
"pos1": "代名詞",
"surface": "吾輩"
},
・
・
・
<省略>
31. 動詞
【実行&結果】
動詞 生れ 動詞 つか 動詞 し 動詞 泣い 動詞 し 動詞 いる 動詞 始め 動詞 見 動詞 聞く 動詞 捕え ・ ・ ・ <省略>
32. 動詞の原形
【実行&結果】
動詞 生れる 動詞 つく 動詞 する 動詞 泣く 動詞 する 動詞 いる 動詞 始める 動詞 見る 動詞 聞く 動詞 捕える ・ ・ ・ <省略>
34. 「AのB」
【実行&結果】
彼 の掌 掌 の上 書生 の顔 はず の顔 顔 の真中 穴 の中 書生 の掌 掌 の裏 何 の事 肝心 の母親 ・ ・ ・ <省略>
35. 名詞の連接
すいません、出題の意味がわからず、パス。
こっから下自信ありません。。。。
36. 単語の出現頻度
【実行&結果】
の 9194 。 7486 て 6873 、 6772 は 6422 に 6268 を 6071 と 5515 が 5339 た 3989 ・ ・ ・ <省略>
37. 頻度上位10語
【実行&結果】

38. ヒストグラム
【実行&結果】

39. Zipfの法則
【実行&結果】

プログラム
# coding: utf-8
import sys
import re
import json
import numpy as np
import matplotlib.pyplot as plt
import matplotlib.font_manager as fm
f = open('neko.txt.mecab','r')
tmp1 = []
temp1 = {}
#30番
for i,line in enumerate(f):
if "EOS" not in line:
# \tか,でスプリット
tmp1 = filter(lambda w: len(w) > 0, re.split(r'\t|,', line))
#0:表層形,1:品詞,2:品詞細分類1,3:品詞細分類2,4:品詞細分類3,5:活用形,6:活用型,7:原形,8:読み,9:発音
temp1[i]={"surface":tmp1[0],"base":tmp1[7],"pos":tmp1[1],"pos1":tmp1[2]}
#print json.dumps(temp1, sort_keys=True, indent=4,ensure_ascii=False)
f.close()
#動詞
def q31(temp1):
for k1,v1 in temp1.iteritems():
if v1["pos"]=="動詞":
print v1["pos"] + " " + v1["surface"]
#重複排除を加えたい
#動詞の原形
def q32(temp1):
for k1,v1 in temp1.iteritems():
if v1["pos"]=="動詞":
print v1["pos"] + " " + v1["base"]
#重複排除を加えたい
#サ変名詞
def q33(temp1):
for k1,v1 in temp1.iteritems():
if v1["pos1"]=="サ変接続":
print v1["pos"] + " " + v1["surface"]
#重複排除を加えたい
#「AのB」
def q34(temp1):
for i in range(0,len(temp1)):
if temp1[i]["pos"]=="名詞":
if (temp1[i+1]["pos"]=="助詞") and (temp1[i+1]["surface"]=="の") and (temp1[i+2]["pos"]=="名詞"):
print temp1[i]["surface"] + " " + temp1[i+1]["surface"] + temp1[i+2]["surface"]
#36. 単語の出現頻度
def q36(temp1):
tmp ={}
for k1,v1 in temp1.iteritems():
if tmp.has_key(v1["surface"]):
tmp.update({ v1["surface"] : int(tmp[v1["surface"]]) + 1 })
else:
tmp[v1["surface"]] = 1
for k, v in sorted(tmp.items(), key=lambda x:x[1],reverse=True):
print k, v
#37. 頻度上位10語
def q37(tmp):
tmp ={}
for k1,v1 in temp1.iteritems():
if tmp.has_key(v1["surface"]):
tmp.update({ v1["surface"] : int(tmp[v1["surface"]]) + 1 })
else:
tmp[v1["surface"]] = 1
i = 0
label_str = []
label_int = []
val = []
for k, v in sorted(tmp.items(), key=lambda x:x[1],reverse=True):
i+=1
label_int.append(i)
label_str.append(k.decode('utf-8'))
val.append(v)
if i == 10:
break
#日本語対応
prop = fm.FontProperties(fname='/home/vagrant/font/ipaexg.ttf')
plt.bar(label_int,val)
plt.xticks(label_int,label_str,fontproperties=prop)
plt.title(u"37. 頻度上位10語",fontproperties=prop)
plt.xlabel(u"単語",fontproperties=prop)
plt.ylabel(u"出現回数",fontproperties=prop)
plt.show()
def q38(tmp):
#単語名をキーとし、値を出現回数とする辞書型データ
tmp ={}
for k1,v1 in temp1.iteritems():
if tmp.has_key(v1["surface"]):
tmp.update({ v1["surface"] : int(tmp[v1["surface"]]) + 1 })
else:
tmp[v1["surface"]] = 1
#出現回数をキーとし、値を単語数とする辞書型データ
tmp1 ={}
for k1,v1 in tmp.iteritems():
if tmp1.has_key(v1):
tmp1.update({ v1 : int(tmp1[v1]) + 1 })
else:
tmp1[v1] = 1
i = 0
label_str = []
label_int = []
val = []
for k, v in sorted(tmp1.items(), key=lambda x:x[1],reverse=True):
i+=1
label_int.append(i)
label_str.append(k)
val.append(v)
if i == 10:
break
#日本語対応
prop = fm.FontProperties(fname='/home/vagrant/font/ipaexg.ttf')
plt.bar(label_int,val)
plt.xticks(label_int,label_str,fontproperties=prop)
plt.title(u"38. ヒストグラム",fontproperties=prop)
plt.xlabel(u"出現頻度",fontproperties=prop)
plt.ylabel(u"出現頻度をとる単語の種類数",fontproperties=prop)
plt.show()
def q39(tmp):
#単語名をキーとし、値を出現回数とする辞書型データ
tmp ={}
for k1,v1 in temp1.iteritems():
if tmp.has_key(v1["surface"]):
tmp.update({ v1["surface"] : int(tmp[v1["surface"]]) + 1 })
else:
tmp[v1["surface"]] = 1
i = 0
label_str = []
label_int = []
val = []
for k, v in sorted(tmp.items(), key=lambda x:x[1],reverse=True):
i+=1
label_int.append(i)
label_str.append(k)
val.append(v)
#日本語対応
prop = fm.FontProperties(fname='/home/vagrant/font/ipaexg.ttf')
plt.xscale("log")
plt.yscale("log")
plt.grid(which="both")
y = np.log(val)
plt.plot(label_int,val)
plt.title(u"39. Zipfの法則",fontproperties=prop)
plt.xlabel(u"単語の出現頻度順位",fontproperties=prop)
plt.ylabel(u"出現頻度",fontproperties=prop)
plt.show()
#問題の関数を呼び出す
q37(temp1)