"Diary" インターネットさんへの恩返し

いつもソースコードコピペばかりなので,みなさまへ少しばかりの恩返しを

言語処理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. 動詞の原形

【実行&結果】

動詞 生れる
動詞 つく
動詞 する
動詞 泣く
動詞 する
動詞 いる
動詞 始める
動詞 見る
動詞 聞く
動詞 捕える
・
・
・
<省略>

33. サ変名詞

【実行&結果】

名詞 見当
名詞 記憶
名詞 話
名詞 装飾
名詞 突起
名詞 運転
名詞 記憶
名詞 分別
名詞 決心
名詞 我慢
・
・
・
<省略>

34. 「AのB」

【実行&結果】

彼 の掌
掌 の上
書生 の顔
はず の顔
顔 の真中
穴 の中
書生 の掌
掌 の裏
何 の事
肝心 の母親
・
・
・
<省略>

35. 名詞の連接

すいません、出題の意味がわからず、パス。


こっから下自信ありません。。。。

36. 単語の出現頻度

【実行&結果】

の 9194
。 7486
て 6873
、 6772
は 6422
に 6268
を 6071
と 5515
が 5339
た 3989
・
・
・
<省略>

37. 頻度上位10語

【実行&結果】
f:id:azumami:20151001162728p:plain

38. ヒストグラム

【実行&結果】
f:id:azumami:20151001164628p:plain

39. Zipfの法則

【実行&結果】
f:id:azumami:20151001170205p:plain

プログラム

# 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)