小説「天気の子」の文章をWordCloudで可視化してみた


はじめに

この記事はTokyo City University Advent Calendar 2019 26日目の記事です!

昨日の記事はらぴーと君の聖なる日にWindows98を動かすお話でした。

概要

今回は、「天気の子」の小説版の文章をpythonのwordcloudで可視化してみたので、その簡単なやり方をまとめていきます。
wordcloudというのは、文章の中の出現頻度が高い単語を選び、出現頻度に応じた大きさで図示(可視化)するツールです。
言葉で説明するよりも画像見せれば早いですね。こんな感じです。↓(ちなみにこれは激おこぷんぷん丸のwikiのページらしい)
自分のツイートでこんな感じのことやってる人を見たことあるんじゃないでしょうか。今回はそれを天気の子でやっていきたいと思います。


引用:https://www.pc-koubou.jp/magazine/2646


小説 天気の子(角川文庫)-Amazonより引用

大まかな流れ

  • コーパス(文章データ)をつくる。
  • 必要なライブラリ(Mecab,Neologd)をインストール
  • 形態素解析
  • wordcloudで可視化

コーパス(文章データ)をつくる

まず、元となる小説のテキストのコーパスを作成します。
知人に手伝っていただきました。kindleから一文ずつコピーしてexcelにぶち込みます。

また、こちらのサイトで「こころ」や「人間失格」を始めとする13000以上の近代文学作品のテキストデータを無料でDLできるので、こちらで代用してやってみるといいかなと思います。近代小説でやって見ると味わい深い単語が出てきそうでこれもまた面白そうですね。「天気の子」などの最新小説はさすがにDLできませんので悪しからず。(やりたい人は自作してください)

必要なライブラリ(Mecab,Neologd)をインストール

形態素解析に必要なライブラリをインストールします。
今回は、Mecabを使うことにします。
参考:PythonとMeCabで形態素解析

また、Web上の新語にも対応するため、Neologdという、MeCab用のシステム辞書の辞書も入れておきます。
参考:https://qiita.com/spiderx_jp/items/7f8cbfd762c9abab660b

インストール方法とかは割愛しときます。

形態素解析してみる

まず、

形態素解析ってなんやねん

という人が多いと思うので、説明すると、自然言語処理における一番基礎的な作業で、
文章を単語ごとに区切って、品詞を判別していく、という工程になります。

例えば、

”三月の雨空に、フェリーの出港を知らせる汽笛が長く響く”

という文があったとします。これを単語ごとに区切ると

'三月', 'の', '雨空', 'に', '、', 'フェリー', 'の', '出港', 'を', '知らせる', '汽笛', 'が', '長く', '響く'

というように分けられます。これを、「分かち書き」と言います。
そしてこれらの単語の品詞を特定すると、
三月: 名詞
の: 助詞
雨空: 名詞
に: 助詞
、: 記号
フェリー: 名詞
の: 助詞
出港: 名詞
を: 助詞
知らせる: 動詞
汽笛: 名詞
が: 助詞
長く: 形容詞
響く: 動詞

といった具合に解析できます。ここまでの工程が形態素解析です。
可視化するにあたって、文章中の単語の中で天気の子の特徴が表れるのはやっぱ名詞だと思うんで、形態素解析した単語の中から名詞のみを取り出してみます。
コードはこんな感じ

import numpy as np
import pandas as pd
import MeCab

#MecabにNeologdを適用
tagger = MeCab.Tagger('-Owakati -d /usr/local/lib/mecab/dic/mecab-ipadic-neologd')

tagger.parse('')
def tokenize_ja(text, lower):
    node = tagger.parseToNode(str(text))
    while node:
        if lower and node.feature.split(',')[0] in ["名詞"]:#分かち書きで取得する品詞を指定
            yield node.surface.lower()
        node = node.next
def tokenize(content, token_min_len, token_max_len, lower):
    return [
        str(token) for token in tokenize_ja(content, lower)
        if token_min_len <= len(token) <= token_max_len and not token.startswith('_')
    ]

#学習データの読み込み
path='../data/tenkinoko.csv'
df_tenki=pd.read_csv(path,encoding="SHIFT-JIS")


wakati_tenkinoko_text = []
for i in df_tenki['text']:
    txt = tokenize(i, 1, 10000, True)
    wakati_tenkinoko_text.append(txt)
np.savetxt("../work/tenki_corpus.txt", wakati_tenkinoko_text,fmt='%s', delimiter=',')

df_tenki['wakati_tenkinoko'] = wakati_tenkinoko_text

結果はこんな感じ↓

これで文章の中から名詞のみを取り出すことができました!

wordcludで可視化

形態素解析ができたら、いよいよwordcloudの出番です!
で、「これ」とか「そこ」みたいなwordcloud的にインスタ映えしないというか(言いたいだけ)ちょっとナンセンスなワードが出てくるんで、そいつらはstop_wordsとして取り除いています。
コードはこんな感じ

from wordcloud import WordCloud

tenki_wordlist = df_tenki['wakati_tenkinoko'].values.tolist()
word_cloud_list = []
for i in tenki_wordlist:
    for j in i:
        word_cloud_list.append(j)

result = ','.join(word_cloud_list)

#日本語のフォントパス
fpath = "../data/ipaexg.ttf"

stop_words = ["の","ん","何","さ","!?","の","さん","よう","たち","こと","それ","そう","ちゃん","なに","みたい","まま","くん","もの","!?」","そこ","どこ","ところ","これ","パイ","なん","ここ"]

wordcloud = WordCloud(background_color='white',
    font_path=fpath, width=800, height=600, stopwords=set(stop_words)).generate(result)

#画像を保存
wordcloud.to_file('./wordcloud.png')

実行結果

結果がこちら!ほい!


めちゃめちゃそれっぽくなった!!!!
てかキャラ名の主張がやっぱめっちゃ激しいですね。小説だからそりゃそうか。
その他にも「センパイ」とか「晴れ女」とか「屋上」とか。割と心当たりがあるワードが出てきてますね〜
この画像を見るだけで映画の情景が浮かんでくる気がしなくもなくもなくもないですね。はい。
(なんかよくわかんないけどちょっと感動した)

まとめ

結構いい感じな結果になったのではないでしょうかね。データいじくるの楽しいです。
次はword2vecで解析してみようと思ってます。それでは〜