「人間失格」をparseする
概念を可視化することは理解の共有と客観視を助ける、という持論を持っている。
ここでいうパースは構文解析を意図して使っており、誰もが一度は読んだことのある(であろう)人間失格は、ビッグデータ的観点からどのような解釈ができ得るのか。という興味を持った。
pythonが趣味なので、青空文庫から人間失格.txt(実際にはningen_shikkaku.txt)をダウンロードし、MeCabとWordCloudを利用して可視化した。
太宰治著/人間失格は「自分」の話?
完全に個人の経験と偏見だが、この本を初めて読んだ時、”これは自分の話かもしれない。とても親近感がある。”と思う中高生は少なくないのではと思う。というのも、作中主人公である私(葉ちゃん)が常に憂いを帯びる青春時代を書いたものであり、その姿が自身と重なるという説が多いようだ(Google検索調べなので適当)。
自分は自分でも
人間失格における頻出単語(助詞、助動詞を除く)
人間失格に出現する単語を前述のwordcloudにて可視化すると、
「自分」という単語が出現頻度が高く、続いて「それ」、「よう」、「もの」・・・とあり「堀木」や「人間」、「道化」、「ヒラメ」という順に並ぶ。確かに作中では自らについて語ることが多く、この図から無理に読み取ろうとすれば、自分は道化を演じる狂人であり、それを馬鹿な振る舞いであると感じていたという文脈は記されていたように思う。
奇しくもこの作品は、「世の思春期における人が自分のことと共感する」作品でもあり、終始「主人公が自分の話」をし続けるという意味で、自分の話であったということだろう(上手いこと言ったつもり)。
同じ言葉を使い続ける人間たち
縦軸:単語の出現頻度
横軸:単語の出現ランキング(x,y軸共に対数)
話は少し変わって、文中に出てくる単語はどのような出現頻度になっているのかを調べた(元々はこれをやりたかった)。品詞に関わらず、対数グラフを書くとまあまあ綺麗な関係性がありそうだ。これを、ジップの法則というらしい。ざっくりいうと、出現頻度(回数)と順位は関係あるよ、という内容だ。
世の中に存在する全ての文章に適用されるということなので、私の日常会話も機会があればパースしたい。と言っても在宅勤務下という非常時のため通常時と異なる単語で構成されていると想定されるが。。。それはそれで差分が取れて面白い。
年齢毎に可視化できると成長やトレンドなどが表出するのだろうか。
補足すると人間失格では、約5万語で構成されており、出現する種類は5500種類の単語で構成されている。1位から10位までの単語は1000回以上出現し(主に「、(句読点)」、「の」、「に」、「て」、「は」などの記号や所謂てにをは)、130位以降は10回以下の出現となる。(因みに面倒だったのでダウンロードしたファイルの中身に記載されているファイル自体の説明文などはそのままにした。)
こうなると、他の作品や別の人の作品にも手を出したくなる。乞うご期待。
こんな感じで書いてみました in Python
まずはモジュールを用意して(sysとosはなくても大丈夫かと)
# import
import MeCab
import sys
import os
import collections
import pandas as pd
import matplotlib.pyplot as plt
from wordcloud import WordCloud
MeCabを試してみる
# test MeCab
text = "恥の多い生涯を送って来ました。"
me = MeCab.Tagger("-Ochasen")
print(me.parse(text))
ここまでが実行できればごちゃごちゃ書いて、
def wordcloud(textdata):
me = MeCab.Tagger('')
parsed = me.parse(textdata)
splitted = ' '.join([x.split('\t')[0] for x in parsed.splitlines()[:-1] \
if x.split('\t')[1].split(",")[0] not in ["助詞","助動詞"]])
fpath="/System/Library/Fonts/Hiragino Sans GB.ttc"
wordc = WordCloud(font_path=fpath,
background_color='white',
width=800, height=600).generate(splitted)
wordc.to_file('ningen_shikkaku_wordcloud.png')
return
def mecab_list(text):
me = MeCab.Tagger("-Ochasen")
me.parse('')
node = me.parseToNode(text)
word_class = []
while node:
word = node.surface
wclass = node.feature.split(',')
if wclass[0] != u'BOS/EOS':
if wclass[6] == None:
word_class.append((word,wclass[0],wclass[1],wclass[2],""))
else:
word_class.append((word,wclass[0],wclass[1],wclass[2],wclass[6]))
node = node.next
return word_class
def word_list(word_class):
list_word = []
for iword in word_class:
list_word.append(iword[0])
return list_word
def count_word(list_word):
print("sample_size = ",len(list_word))
d = collections.Counter(list_word)
df = pd.DataFrame.from_dict(d, orient="index", columns=["num_occur"])
df = df.sort_values("num_occur", ascending=False)
df = df.reset_index()
print(df.columns,df.index)
return df
def plot(df):
fig, ax = plt.subplots()
print(df.head(), df.tail())
plt.plot(df.index,df["num_occur"], color="orange")
plt.ylabel("Number of occurrences")
plt.xlabel("Rank")
ax.set_yscale("log")
ax.set_xscale("log")
plt.grid()
plt.title("The number of occurrences of the word \n and its ranking.")
plt.savefig("Graph_ningensikkaku.png")
return
あとは実行するだけ(******は任意のディレクトリ)。
## main
# read text file
tfile = "/Users/******/Python/ningen_shikkaku.txt"
f = open(tfile,encoding="shift-jis")
textdata = f.read()
f.close()
if __name__ == '__main__':
wordcloud(textdata) #
word_class = mecab_list(textdata) # MeCabでparse
list_word = word_list(word_class) # 単語をリスト化
df = count_word(list_word) # 詳細確認
plot(df) # グラフ描画
アウトプットはワードクラウドと対数グラフ。どちらもpngで出力。
コードはもっと洗練したものを書けるよう精進します。修行中につきあしからず。
参考図書
・人間失格/太宰治
・カルチャロミクス:文化をビッグデータで計測するKindle版
今日の一枚 「尾道の藤棚」
「尾道の藤棚」は、ちょうど昨年の今頃撮影したもの。
この写真を撮った時は、まさかこのような事態になっているとは思いもよらなかった。これからゆく道も、この藤のように鮮やかになりますように。